def _cFuncCubic(aXtraGrid, mNrmMinNow, mNrmNow, cNrmNow, MPCNow, MPCminNow, hNrmNow): mNrmGrid = mNrmMinNow + aXtraGrid mNrmCnst = np.array([mNrmMinNow, mNrmMinNow + 1]) cNrmCnst = np.array([0.0, 1.0]) cFuncNowCnst = linear_interp_fast(mNrmGrid.flatten(), mNrmCnst, cNrmCnst) cFuncNowUnc, MPCNowUnc = cubic_interp_fast( mNrmGrid.flatten(), mNrmNow, cNrmNow, MPCNow, MPCminNow * hNrmNow, MPCminNow ) cNrmNow = np.where(cFuncNowCnst <= cFuncNowUnc, cFuncNowCnst, cFuncNowUnc) return cNrmNow, mNrmGrid
def _find_mNrmStECubic(m, PermGroFac, Rfree, Ex_IncNext, mNrmMin, mNrm, cNrm, MPC, MPCmin, hNrm): # Make a linear function of all combinations of c and m that yield mNext = mNow mZeroChange = (1.0 - PermGroFac / Rfree) * m + (PermGroFac / Rfree) * Ex_IncNext mNrmCnst = np.array([mNrmMin, mNrmMin + 1]) cNrmCnst = np.array([0.0, 1.0]) cFuncNowCnst = linear_interp_fast(np.array([m]), mNrmCnst, cNrmCnst) cFuncNowUnc, MPCNowUnc = cubic_interp_fast(np.array([m]), mNrm, cNrm, MPC, MPCmin * hNrm, MPCmin) cNrmNow = np.where(cFuncNowCnst <= cFuncNowUnc, cFuncNowCnst, cFuncNowUnc) # Find the steady state level of market resources res = cNrmNow[0] - mZeroChange # A zero of this is SS market resources return res
def _add_vFuncNumba( mNrmNext, mNrmGridNext, vNvrsNext, vNvrsPNext, MPCminNvrsNext, hNrmNext, CRRA, PermShkVals_temp, PermGroFac, DiscFacEff, ShkPrbs_temp, EndOfPrdvP, aNrmNow, BoroCnstNat, mNrmGrid, cFuncNow, mNrmMinNow, MPCmaxEff, MPCminNow, ): """ Construct the end-of-period value function for this period, storing it as an attribute of self for use by other methods. """ # vFunc always cubic vNvrsFuncNow, _ = cubic_interp_fast( mNrmNext.flatten(), mNrmGridNext, vNvrsNext, vNvrsPNext, MPCminNvrsNext * hNrmNext, MPCminNvrsNext, ) vFuncNext = utility(vNvrsFuncNow, CRRA).reshape(mNrmNext.shape) VLvlNext = ( PermShkVals_temp ** (1.0 - CRRA) * PermGroFac ** (1.0 - CRRA) ) * vFuncNext EndOfPrdv = DiscFacEff * np.sum(VLvlNext * ShkPrbs_temp, axis=0) # value transformed through inverse utility EndOfPrdvNvrs = utility_inv(EndOfPrdv, CRRA) EndOfPrdvNvrsP = EndOfPrdvP * utility_invP(EndOfPrdv, CRRA) EndOfPrdvNvrs = _np_insert(EndOfPrdvNvrs, 0, 0.0) # This is a very good approximation, vNvrsPP = 0 at the asset minimum EndOfPrdvNvrsP = _np_insert(EndOfPrdvNvrsP, 0, EndOfPrdvNvrsP[0]) aNrm_temp = _np_insert(aNrmNow, 0, BoroCnstNat) """ Creates the value function for this period, defined over market resources m. self must have the attribute EndOfPrdvFunc in order to execute. """ # Compute expected value and marginal value on a grid of market resources aNrmNow = mNrmGrid - cFuncNow EndOfPrdvNvrsFunc, _ = cubic_interp_fast( aNrmNow, aNrm_temp, EndOfPrdvNvrs, EndOfPrdvNvrsP ) EndOfPrdvFunc = utility(EndOfPrdvNvrsFunc, CRRA) vNrmNow = utility(cFuncNow, CRRA) + EndOfPrdvFunc vPnow = utilityP(cFuncNow, CRRA) # Construct the beginning-of-period value function vNvrs = utility_inv(vNrmNow, CRRA) # value transformed through inverse utility vNvrsP = vPnow * utility_invP(vNrmNow, CRRA) mNrmGrid = _np_insert(mNrmGrid, 0, mNrmMinNow) vNvrs = _np_insert(vNvrs, 0, 0.0) vNvrsP = _np_insert(vNvrsP, 0, MPCmaxEff ** (-CRRA / (1.0 - CRRA))) MPCminNvrs = MPCminNow ** (-CRRA / (1.0 - CRRA)) return ( mNrmGrid, vNvrs, vNvrsP, MPCminNvrs, )
def _solveConsIndShockCubicNumba( mNrmMinNext, mNrmNext, mNrmUnc, cNrmUnc, MPCNext, cFuncInterceptNext, cFuncSlopeNext, CRRA, DiscFacEff, Rfree, PermGroFac, PermShkVals_temp, ShkPrbs_temp, aNrmNow, BoroCnstNat, MPCmaxNow, ): mNrmCnst = np.array([mNrmMinNext, mNrmMinNext + 1]) cNrmCnst = np.array([0.0, 1.0]) cFuncNextCnst, MPCNextCnst = linear_interp_deriv_fast( mNrmNext.flatten(), mNrmCnst, cNrmCnst ) cFuncNextUnc, MPCNextUnc = cubic_interp_fast( mNrmNext.flatten(), mNrmUnc, cNrmUnc, MPCNext, cFuncInterceptNext, cFuncSlopeNext, ) cFuncNext = np.where(cFuncNextCnst <= cFuncNextUnc, cFuncNextCnst, cFuncNextUnc) vPfuncNext = utilityP(cFuncNext, CRRA).reshape(mNrmNext.shape) EndOfPrdvP = ( DiscFacEff * Rfree * PermGroFac ** (-CRRA) * np.sum(PermShkVals_temp ** (-CRRA) * vPfuncNext * ShkPrbs_temp, axis=0) ) # Finds interpolation points (c,m) for the consumption function. cNrmNow = EndOfPrdvP ** (-1.0 / CRRA) mNrmNow = cNrmNow + aNrmNow # Limiting consumption is zero as m approaches mNrmMin cNrm = _np_insert(cNrmNow, 0, 0.0, axis=-1) mNrm = _np_insert(mNrmNow, 0, BoroCnstNat, axis=-1) """ Makes a cubic spline interpolation of the unconstrained consumption function for this period. """ MPCinterpNext = np.where(cFuncNextCnst <= cFuncNextUnc, MPCNextCnst, MPCNextUnc) vPPfuncNext = (MPCinterpNext * utilityPP(cFuncNext, CRRA)).reshape(mNrmNext.shape) EndOfPrdvPP = ( DiscFacEff * Rfree * Rfree * PermGroFac ** (-CRRA - 1.0) * np.sum(PermShkVals_temp ** (-CRRA - 1.0) * vPPfuncNext * ShkPrbs_temp, axis=0) ) dcda = EndOfPrdvPP / utilityPP(cNrm[1:], CRRA) MPC = dcda / (dcda + 1.0) MPC = _np_insert(MPC, 0, MPCmaxNow) return cNrm, mNrm, MPC, EndOfPrdvP