def post_solve(self): self.solution_fast = deepcopy(self.solution) if self.cycles == 0: terminal = 1 else: terminal = self.cycles self.solution[terminal] = self.solution_terminal_cs for i in range(terminal): solution = self.solution[i] # Construct the consumption function as a linear interpolation. cFunc = LinearInterp(solution.mNrm, solution.cNrm) """ Defines the value and marginal value functions for this period. Uses the fact that for a perfect foresight CRRA utility problem, if the MPC in period t is :math:`\kappa_{t}`, and relative risk aversion :math:`\rho`, then the inverse value vFuncNvrs has a constant slope of :math:`\kappa_{t}^{-\rho/(1-\rho)}` and vFuncNvrs has value of zero at the lower bound of market resources mNrmMin. See PerfForesightConsumerType.ipynb documentation notebook for a brief explanation and the links below for a fuller treatment. https://www.econ2.jhu.edu/people/ccarroll/public/lecturenotes/consumption/PerfForesightCRRA/#vFuncAnalytical https://www.econ2.jhu.edu/people/ccarroll/SolvingMicroDSOPs/#vFuncPF """ vFuncNvrs = LinearInterp( np.array([solution.mNrmMin, solution.mNrmMin + 1.0]), np.array([0.0, solution.vFuncNvrsSlope]), ) vFunc = ValueFuncCRRA(vFuncNvrs, self.CRRA) vPfunc = MargValueFuncCRRA(cFunc, self.CRRA) consumer_solution = ConsumerSolution( cFunc=cFunc, vFunc=vFunc, vPfunc=vPfunc, mNrmMin=solution.mNrmMin, hNrm=solution.hNrm, MPCmin=solution.MPCmin, MPCmax=solution.MPCmax, ) Ex_IncNext = 1.0 # Perfect foresight income of 1 # Add mNrmStE to the solution and return it consumer_solution.mNrmStE = _add_mNrmStENumba( self.Rfree, self.PermGroFac[i], solution.mNrm, solution.cNrm, solution.mNrmMin, Ex_IncNext, _find_mNrmStE, ) self.solution[i] = consumer_solution
def post_solve(self): self.solution_fast = deepcopy(self.solution) if self.cycles == 0: cycles = 1 else: cycles = self.cycles self.solution[-1] = self.solution_terminal_cs for i in range(cycles): for j in range(self.T_cycle): solution = self.solution[i * self.T_cycle + j] # Define the borrowing constraint (limiting consumption function) cFuncNowCnst = LinearInterp( np.array([solution.mNrmMin, solution.mNrmMin + 1]), np.array([0.0, 1.0]), ) """ Constructs a basic solution for this period, including the consumption function and marginal value function. """ if self.CubicBool: # Makes a cubic spline interpolation of the unconstrained consumption # function for this period. cFuncNowUnc = CubicInterp( solution.mNrm, solution.cNrm, solution.MPC, solution.cFuncLimitIntercept, solution.cFuncLimitSlope, ) else: # Makes a linear interpolation to represent the (unconstrained) consumption function. # Construct the unconstrained consumption function cFuncNowUnc = LinearInterp( solution.mNrm, solution.cNrm, solution.cFuncLimitIntercept, solution.cFuncLimitSlope, ) # Combine the constrained and unconstrained functions into the true consumption function cFuncNow = LowerEnvelope(cFuncNowUnc, cFuncNowCnst) # Make the marginal value function and the marginal marginal value function vPfuncNow = MargValueFuncCRRA(cFuncNow, self.CRRA) # Pack up the solution and return it consumer_solution = ConsumerSolution( cFunc=cFuncNow, vPfunc=vPfuncNow, mNrmMin=solution.mNrmMin, hNrm=solution.hNrm, MPCmin=solution.MPCmin, MPCmax=solution.MPCmax, ) if self.vFuncBool: vNvrsFuncNow = CubicInterp( solution.mNrmGrid, solution.vNvrs, solution.vNvrsP, solution.MPCminNvrs * solution.hNrm, solution.MPCminNvrs, ) vFuncNow = ValueFuncCRRA(vNvrsFuncNow, self.CRRA) consumer_solution.vFunc = vFuncNow if self.CubicBool or self.vFuncBool: _searchFunc = ( _find_mNrmStECubic if self.CubicBool else _find_mNrmStELinear ) # Add mNrmStE to the solution and return it consumer_solution.mNrmStE = _add_mNrmStEIndNumba( self.PermGroFac[j], self.Rfree, solution.Ex_IncNext, solution.mNrmMin, solution.mNrm, solution.cNrm, solution.MPC, solution.MPCmin, solution.hNrm, _searchFunc, ) self.solution[i * self.T_cycle + j] = consumer_solution