def makeTargetMfig(Rfree, DiscFac, CRRA, permShkStd, TranShkStd): inf_hor = IndShockConsumerType(quietly=True, **base_params) inf_hor.Rfree = Rfree inf_hor.DiscFac = DiscFac inf_hor.CRRA = CRRA inf_hor.permShkStd = [permShkStd] inf_hor.TranShkStd = [TranShkStd] inf_hor.update_income_process() mPlotMin = 0 mPlotMax = 250 inf_hor.aXtraMax = mPlotMax inf_hor.solve(quietly=True, messaging_level=logging.CRITICAL) soln = inf_hor.solution[0] Bilt, cFunc = soln.Bilt, soln.cFunc cPlotMin = 0, cFunc(mPlotMax) if Bilt.GICNrm: # tattle soln.check_GICNrm(soln, quietly=False, messaging_level=logging.WARNING) mBelwStE = np.linspace(mPlotMin, mPlotMax, 1000) EPermGroFac = inf_hor.PermGroFac[0] def EmDelEq0(mVec): return (EPermGroFac / Rfree) + (1.0 - EPermGroFac / Rfree) * mVec cBelwStE_Best = cFunc(mBelwStE) # "best" = optimal c cBelwStE_Sstn = EmDelEq0(mBelwStE) # "sustainable" c mNrmStE = Bilt.mNrmStE plt.figure(figsize=(12, 8)) plt.plot(mBelwStE, cBelwStE_Best, label="$c(m_{t})$") plt.plot(mBelwStE, cBelwStE_Sstn, label="$\mathsf{E}_{t}[\Delta m_{t+1}] = 0$") plt.xlim(mPlotMin, mPlotMax) plt.ylim(cPlotMin, cFunc(mPlotMax)) plt.plot( [mNrmStE, mNrmStE], [0, 2.5], color="black", linestyle="--", ) plt.tick_params( # labelbottom=False, # labelleft=False, # left="off", right="off", # bottom="off", top="off", ) plt.text(0, 1.47, r"$c$", fontsize=26) plt.text(3.02, 0, r"$m$", fontsize=26) plt.text(mNrmStE - 0.05, -0.1, "m̌", fontsize=26) plt.legend(fontsize='x-large') plt.show() return None
def makeTargetMfig(Rfree, DiscFac, CRRA, PermShkStd, TranShkStd): baseAgent_Inf = IndShockConsumerType(verbose=0, cycles=0, **base_params) baseAgent_Inf.Rfree = Rfree baseAgent_Inf.DiscFac = DiscFac baseAgent_Inf.CRRA = CRRA baseAgent_Inf.PermShkStd = [PermShkStd] baseAgent_Inf.TranShkStd = [TranShkStd] baseAgent_Inf.updateIncomeProcess() baseAgent_Inf.checkConditions() mPlotMin = 0 mPlotMax = 250 baseAgent_Inf.aXtraMax = mPlotMax baseAgent_Inf.solve() baseAgent_Inf.unpack('cFunc') cPlotMin = 0 cPlotMax = baseAgent_Inf.cFunc[0](mPlotMax) if (baseAgent_Inf.GPFInd >= 1): baseAgent_Inf.checkGICInd(verbose=3) mBelwTrg = np.linspace(mPlotMin, mPlotMax, 1000) EPermGroFac = baseAgent_Inf.PermGroFac[0] EmDelEq0 = lambda m: (EPermGroFac / Rfree) + (1.0 - EPermGroFac / Rfree ) * m cBelwTrg_Best = baseAgent_Inf.cFunc[0](mBelwTrg) # "best" = optimal c cBelwTrg_Sstn = EmDelEq0(mBelwTrg) # "sustainable" c mNrmTrg = baseAgent_Inf.solution[0].mNrmSS plt.figure(figsize=(12, 8)) plt.plot(mBelwTrg, cBelwTrg_Best, label="$c(m_{t})$") plt.plot(mBelwTrg, cBelwTrg_Sstn, label="$\mathsf{E}_{t}[\Delta m_{t+1}] = 0$") plt.xlim(mPlotMin, mPlotMax) plt.ylim(cPlotMin, cPlotMax) plt.plot( [mNrmTrg, mNrmTrg], [0, 2.5], color="black", linestyle="--", ) plt.tick_params( # labelbottom=False, # labelleft=False, # left="off", right="off", # bottom="off", top="off", ) plt.text(0, 1.47, r"$c$", fontsize=26) plt.text(3.02, 0, r"$m$", fontsize=26) plt.text(mNrmTrg - 0.05, -0.1, "m̌", fontsize=26) plt.legend(fontsize='x-large') plt.show() return None
GICNrmFailsButGICRawHolds.solve(quietly=True) # Suppress output # Because we are trying to solve a problem very close to the critical patience # values, we want to do it with extra precision to be sure we've gotten the # answer right. We can retrieve the distance between the last two solutions: distance_original = GICNrmFailsButGICRawHolds.solution[0].distance_last # But high precision would have slowed things down if we used it from the start # Instead, we can take the solution obtained above, and continue it but with # parameters that will yield a more precise answer: # Solve with quadruple the normal range GICNrmFailsButGICRawHolds.aXtraMax = GICNrmFailsButGICRawHolds.aXtraMax * 10 # Solve over four times as many gridpoints GICNrmFailsButGICRawHolds.aXtraCount = GICNrmFailsButGICRawHolds.aXtraCount * 4 GICNrmFailsButGICRawHolds.update_assets_grid() # Solve to a 10 times tighter degree of error tolerance GICNrmFailsButGICRawHolds.tolerance = GICNrmFailsButGICRawHolds.tolerance/10 # When the solver reaches its tolerance threshold, it changes the solver # attribute stge_kind to have 'iter_status' of 'finished' # If we want to continue the solution (having changed something, as above) # To continue the solution from where we left off, we just change the # 'iter_status' to 'iterator' and tell it to ".solve()" again
def makeBoundsFigure(UnempPrb, permShkStd, TranShkStd, DiscFac, CRRA): inf_hor = IndShockConsumerType(quietly=True, messaging_level=logging.CRITICAL, **base_params) inf_hor.UnempPrb = UnempPrb inf_hor.permShkStd = [permShkStd] inf_hor.TranShkStd = [TranShkStd] inf_hor.DiscFac = DiscFac inf_hor.CRRA = CRRA inf_hor.update_income_process() inf_hor.solve(quietly=True, messaging_level=logging.CRITICAL) soln = inf_hor.solution[0] Bilt, Pars = soln.Bilt, soln.Pars cFunc = soln.cFunc mPlotMin, mPlotMax = 0, 25 inf_hor.aXtraMax = mPlotMax # Retrieve parameters (makes code more readable) Rfree, EPermGroFac = Pars.Rfree, Pars.PermGroFac κ_Min = 1.0 - (Rfree**(-1.0)) * (Rfree * DiscFac)**(1.0 / CRRA) h_inf = (1.0 / (1.0 - EPermGroFac / Rfree)) def cFunc_Uncnst(mVec): return (h_inf - 1) * κ_Min + κ_Min * mVec def cFunc_TopBnd(mVec): return (1 - UnempPrb**(1.0 / CRRA) * (Rfree * DiscFac)**(1.0 / CRRA) / Rfree) * mVec def cFunc_BotBnd(mVec): return (1 - (Rfree * DiscFac)**(1.0 / CRRA) / Rfree) * mVec # Plot the consumption function and its bounds cPlotMaxLabel = r"c̅$(m) = (m-1+h)κ̲$" # Use unicode kludge cPlotMinLabel = r"c̲$(m)= (1-\Phi_{R})m = κ̲ m$" # mKnk is point where the two upper bounds meet mKnk = ((h_inf - 1) * κ_Min) / ( (1 - UnempPrb**(1.0 / CRRA) * (Rfree * DiscFac)**(1.0 / CRRA) / Rfree) - κ_Min) mBelwKnkPts, mAbveKnkPts = 50, 100 mBelwKnk = np.linspace(mPlotMin, mKnk, mBelwKnkPts) mAbveKnk = np.linspace(mKnk, mPlotMax, mAbveKnkPts) mFullPts = np.linspace(mPlotMin, mPlotMax, mBelwKnkPts + mAbveKnkPts) plt.figure(figsize=(12, 8)) plt.plot(mFullPts, cFunc(mFullPts), label=r'$c(m)$') plt.plot(mBelwKnk, cFunc_Uncnst(mBelwKnk), label=cPlotMaxLabel, linestyle="--") plt.plot( mAbveKnk, cFunc_Uncnst(mAbveKnk), label= r'Upper Bound $ = $ Min $[\overline{\overline{c}}(m),\overline{c}(m)]$', linewidth=2.5, color='black') plt.plot(mBelwKnk, cFunc_TopBnd(mBelwKnk), linewidth=2.5, color='black') plt.plot(mAbveKnk, cFunc_TopBnd(mAbveKnk), linestyle="--", label=r"$\overline{\overline{c}}(m) = κ̅m = (1 - ℘^{1/ρ}Φᵣ)m$") plt.plot(mBelwKnk, cFunc_BotBnd(mBelwKnk), color='red', linewidth=2.5) plt.plot(mAbveKnk, cFunc_BotBnd(mAbveKnk), color='red', label=cPlotMinLabel, linewidth=2.5) plt.tick_params(labelbottom=False, labelleft=False, left='off', right='off', bottom='off', top='off') plt.xlim(mPlotMin, mPlotMax) plt.ylim(mPlotMin, 1.12 * cFunc_Uncnst(mPlotMax)) plt.text(mPlotMin, 1.12 * cFunc_Uncnst(mPlotMax) + 0.05, "$c$", fontsize=22) plt.text(mPlotMax + 0.1, mPlotMin, "$m$", fontsize=22) plt.legend(fontsize='x-large') plt.show() return None
def makeBoundsFigure(UnempPrb, PermShkStd, TranShkStd, DiscFac, CRRA): baseAgent_Inf = IndShockConsumerType(verbose=0, cycles=0, **base_params) baseAgent_Inf.UnempPrb = UnempPrb baseAgent_Inf.PermShkStd = [PermShkStd] baseAgent_Inf.TranShkStd = [TranShkStd] baseAgent_Inf.DiscFac = DiscFac baseAgent_Inf.CRRA = CRRA baseAgent_Inf.updateIncomeProcess() baseAgent_Inf.checkConditions() mPlotMin = 0 mPlotMax = 2500 baseAgent_Inf.tolerance = 1e-09 baseAgent_Inf.aXtraMax = mPlotMax baseAgent_Inf.solve(verbose=0) baseAgent_Inf.unpack('cFunc') cPlotMin = 0 cPlotMax = 1.2 * baseAgent_Inf.cFunc[0](mPlotMax) # Retrieve parameters (makes code more readable) Rfree = baseAgent_Inf.Rfree CRRA = baseAgent_Inf.CRRA EPermGroFac = baseAgent_Inf.PermGroFac[0] mNrmTrg = baseAgent_Inf.solution[0].mNrmSS UnempPrb = baseAgent_Inf.UnempPrb κ_Min = 1.0 - (Rfree**(-1.0)) * (Rfree * DiscFac)**(1.0 / CRRA) h_inf = (1.0 / (1.0 - EPermGroFac / Rfree)) cFunc_Uncnst = lambda m: (h_inf - 1) * κ_Min + κ_Min * m cFunc_TopBnd = lambda m: (1 - UnempPrb**(1.0 / CRRA) * (Rfree * DiscFac)**(1.0 / CRRA) / Rfree) * m cFunc_BotBnd = lambda m: (1 - (Rfree * DiscFac)**(1.0 / CRRA) / Rfree) * m # Plot the consumption function and its bounds cMaxLabel = r"c̅$(m) = (m-1+h)κ̲$" # Use unicode kludge cMinLabel = r"c̲$(m)= (1-\Phi_{R})m = κ̲ m$" # mKnk is point where the two upper bounds meet mKnk = ((h_inf - 1) * κ_Min) / ( (1 - UnempPrb**(1.0 / CRRA) * (Rfree * DiscFac)**(1.0 / CRRA) / Rfree) - κ_Min) mBelwKnkPts = 300 mAbveKnkPts = 700 mBelwKnk = np.linspace(mPlotMin, mKnk, mBelwKnkPts) mAbveKnk = np.linspace(mKnk, mPlotMax, mAbveKnkPts) mFullPts = np.linspace(mPlotMin, mPlotMax, mBelwKnkPts + mAbveKnkPts) plt.figure(figsize=(12, 8)) plt.plot(mFullPts, baseAgent_Inf.cFunc[0](mFullPts), label=r'$c(m)$') plt.plot(mBelwKnk, cFunc_Uncnst(mBelwKnk), label=cMaxLabel, linestyle="--") plt.plot( mAbveKnk, cFunc_Uncnst(mAbveKnk), label= r'Upper Bound $ = $ Min $[\overline{\overline{c}}(m),\overline{c}(m)]$', linewidth=2.5, color='black') plt.plot(mBelwKnk, cFunc_TopBnd(mBelwKnk), linewidth=2.5, color='black') plt.plot(mAbveKnk, cFunc_TopBnd(mAbveKnk), linestyle="--", label=r"$\overline{\overline{c}}(m) = κ̅m = (1 - ℘^{1/ρ}Φᵣ)m$") plt.plot(mBelwKnk, cFunc_BotBnd(mBelwKnk), color='red', linewidth=2.5) plt.plot(mAbveKnk, cFunc_BotBnd(mAbveKnk), color='red', label=cMinLabel, linewidth=2.5) plt.tick_params(labelbottom=False, labelleft=False, left='off', right='off', bottom='off', top='off') plt.xlim(mPlotMin, mPlotMax) plt.ylim(mPlotMin, 1.12 * cFunc_Uncnst(mPlotMax)) plt.text(mPlotMin, 1.12 * cFunc_Uncnst(mPlotMax) + 0.05, "$c$", fontsize=22) plt.text(mPlotMax + 0.1, mPlotMin, "$m$", fontsize=22) plt.legend(fontsize='x-large') plt.show() return None
def makeGrowthplot(PermGroFac, DiscFac): # cycles=0 tells the solver to find the infinite horizon solution baseAgent_Inf = IndShockConsumerType(verbose=0, cycles=0, **base_params) baseAgent_Inf.PermGroFac = [PermGroFac] baseAgent_Inf.DiscFac = DiscFac baseAgent_Inf.updateIncomeProcess() baseAgent_Inf.checkConditions() mPlotMin = 0 mPlotMax = 3500.5 baseAgent_Inf.mPlotMax = 3500.5 baseAgent_Inf.aXtraMax = mPlotMax baseAgent_Inf.tolerance = 1e-09 baseAgent_Inf.solve() baseAgent_Inf.unpack('cFunc') numPts = 500 if (baseAgent_Inf.GPFInd >= 1): baseAgent_Inf.checkGICInd(verbose=3) elif baseAgent_Inf.solution[0].mNrmSS > mPlotMax: print('Target exists but is outside the plot range.') else: def EcLev_tp1_Over_p_t(a): ''' Taking end-of-period assets a as input, return ratio of expectation of next period's consumption to this period's permanent income Inputs: a: end-of-period assets Returns: EcLev_tp1_Over_p_{t}: next period's expected c level / current p ''' # Extract parameter values to make code more readable permShkVals = baseAgent_Inf.PermShkDstn[0].X tranShkVals = baseAgent_Inf.TranShkDstn[0].X permShkPrbs = baseAgent_Inf.PermShkDstn[0].pmf tranShkPrbs = baseAgent_Inf.TranShkDstn[0].pmf Rfree = baseAgent_Inf.Rfree EPermGroFac = baseAgent_Inf.PermGroFac[0] PermGrowFac_tp1 = EPermGroFac * permShkVals # Nonstochastic growth times idiosyncratic permShk RNrmFac_tp1 = Rfree / PermGrowFac_tp1 # Growth-normalized interest factor # 'bank balances' b = end-of-last-period assets times normalized return factor b_tp1 = RNrmFac_tp1 * a # expand dims of b_tp1 and use broadcasted sum of a column and a row vector # to obtain a matrix of possible market resources next period # because matrix mult is much much faster than looping to calc E m_tp1_GivenTranAndPermShks = np.expand_dims(b_tp1, axis=1) + tranShkVals # List of possible values of $\mathbf{c}_{t+1}$ (Transposed by .T) cRat_tp1_GivenTranAndPermShks = baseAgent_Inf.cFunc[0]( m_tp1_GivenTranAndPermShks).T cLev_tp1_GivenTranAndPermShks = cRat_tp1_GivenTranAndPermShks * PermGrowFac_tp1 # compute expectation over perm shocks by right multiplying with probs EOverPShks_cLev_tp1_GivenTranShkShks = np.dot( cLev_tp1_GivenTranAndPermShks, permShkPrbs) # finish expectation over trans shocks by right multiplying with probs EcLev_tp1_Over_p_t = np.dot(EOverPShks_cLev_tp1_GivenTranShkShks, tranShkPrbs) # return expected consumption return EcLev_tp1_Over_p_t # Calculate the expected consumption growth factor # mBelwTrg defines the plot range on the left of target m value (e.g. m <= target m) mNrmTrg = baseAgent_Inf.solution[0].mNrmSS mPlotMin = 0 mPlotMax = 200 mBelwTrg = np.linspace(mPlotMin, mNrmTrg, numPts) c_For_mBelwTrg = baseAgent_Inf.cFunc[0](mBelwTrg) a_For_mBelwTrg = mBelwTrg - c_For_mBelwTrg EcLev_tp1_Over_p_t_For_mBelwTrg = [ EcLev_tp1_Over_p_t(i) for i in a_For_mBelwTrg ] # mAbveTrg defines the plot range on the right of target m value (e.g. m >= target m) mAbveTrg = np.linspace(mNrmTrg, mPlotMax, numPts) # EcGro_For_mAbveTrg: E [consumption growth factor] when m_{t} is below target m EcGro_For_mBelwTrg = np.array( EcLev_tp1_Over_p_t_For_mBelwTrg) / c_For_mBelwTrg c_For_mAbveTrg = baseAgent_Inf.cFunc[0](mAbveTrg) a_For_mAbveTrg = mAbveTrg - c_For_mAbveTrg EcLev_tp1_Over_p_t_For_mAbveTrg = [ EcLev_tp1_Over_p_t(i) for i in a_For_mAbveTrg ] # EcGro_For_mAbveTrg: E [consumption growth factor] when m_{t} is bigger than target m_{t} EcGro_For_mAbveTrg = np.array( EcLev_tp1_Over_p_t_For_mAbveTrg) / c_For_mAbveTrg Rfree = 1.0 EPermGroFac = 1.0 mNrmTrg = baseAgent_Inf.solution[0].mNrmSS # Calculate Absolute Patience Factor Phi = lower bound of consumption growth factor APF = (Rfree * DiscFac)**(1.0 / CRRA) plt.figure(figsize=(12, 8)) # Plot the Absolute Patience Factor line plt.plot([mPlotMin, mPlotMax], [APF, APF], label="\u03A6 = [(\u03B2 R)^(1/ \u03C1)]/R") # Plot the Permanent Income Growth Factor line plt.plot([mPlotMin, mPlotMax], [EPermGroFac, EPermGroFac], label="\u0393") # Plot the expected consumption growth factor on the left side of target m plt.plot(mBelwTrg, EcGro_For_mBelwTrg, color="black") # Plot the expected consumption growth factor on the right side of target m plt.plot(mAbveTrg, EcGro_For_mAbveTrg, color="black", label="$\mathsf{E}_{t}[c_{t+1}/c_{t}]$") # Plot the target m plt.plot( [mNrmTrg, mNrmTrg], [mPlotMin, mPlotMax], color="black", linestyle="--", label="", ) plt.xlim(1, mPlotMax) plt.ylim(0.94, 1.10) plt.text(2.105, 0.930, "$m_{t}$", fontsize=26, fontweight="bold") plt.text( mNrmTrg - 0.02, 0.930, "m̌", fontsize=26, fontweight="bold", ) plt.tick_params( labelbottom=False, labelleft=False, left="off", right="off", bottom="off", top="off", ) plt.legend(fontsize='x-large') plt.show() return None