def makeConvergencePlot(DiscFac, CRRA, Rfree, PermShkStd): # Construct finite horizon agent with baseline parameters baseAgent_Fin = IndShockConsumerType(verbose=0, **base_params) baseAgent_Fin.DiscFac = DiscFac baseAgent_Fin.CRRA = CRRA baseAgent_Fin.Rfree = Rfree baseAgent_Fin.PermShkStd = [PermShkStd] baseAgent_Fin.cycles = 100 baseAgent_Fin.updateIncomeProcess() baseAgent_Fin.solve() baseAgent_Fin.unpack('cFunc') # figure limits mMax = 6 # 11 mMin = 0 cMin = 0 cMax = 4 # 7 mPlotMin = 0 mLocCLabels = 5.6 # 9.6 # Defines horizontal limit of figure mPlotTop = 3.5 # 6.5 # Defines maximum m value where functions are plotted mPts = 1000 # Number of points at which functions are evaluated plt.figure(figsize=(12, 8)) plt.ylim([cMin, cMax]) plt.xlim([mMin, mMax]) mBelwLabels = np.linspace(mPlotMin, mLocCLabels - 0.1, mPts) # Range of m below loc of labels m_FullRange = np.linspace(mPlotMin, mPlotTop, mPts) # Full plot range c_Tm0 = m_FullRange # c_Tm0 defines the last period consumption rule (c=m) c_Tm1 = baseAgent_Fin.cFunc[-2]( mBelwLabels ) # c_Tm1 defines the second-to-last period consumption rule c_Tm5 = baseAgent_Fin.cFunc[-6]( mBelwLabels) # c_Tm5 defines the T-5 period consumption rule c_Tm10 = baseAgent_Fin.cFunc[-11]( mBelwLabels) # c_Tm10 defines the T-10 period consumption rule c_Limt = baseAgent_Fin.cFunc[0]( mBelwLabels ) # c_Limt defines limiting infinite-horizon consumption rule plt.plot(mBelwLabels, c_Limt, label="$c(m)$") plt.plot(mBelwLabels, c_Tm1, label="$c_{T-1}(m)$") plt.plot(mBelwLabels, c_Tm5, label="$c_{T-5}(m)$") plt.plot(mBelwLabels, c_Tm10, label="$c_{T-10}(m)$") plt.plot(m_FullRange, c_Tm0, label="$c_{T}(m) = 45$ degree line") plt.legend(fontsize='x-large') plt.tick_params( labelbottom=False, labelleft=False, left="off", right="off", bottom="off", top="off", ) plt.show() return None
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.GICMod: # tattle soln.check_GICMod(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 mBalLvl = Bilt.mBalLvl 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( [mBalLvl, mBalLvl], [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(mBalLvl - 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
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() baseAgent_Inf.solve() baseAgent_Inf.unpack('cFunc') # Retrieve parameters (makes code 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$" mPlotMax = 25 mPlotMin = 0 # 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 makeGICFailExample(DiscFac, PermShkStd, UnempPrb): # Construct the "GIC fails" example. GIC_fails_dictionary = dict(base_params) GIC_fails_dictionary['Rfree'] = 1.04 GIC_fails_dictionary['PermGroFac'] = [1.00] GICFailsExample = IndShockConsumerType( verbose=0, cycles=0, # cycles=0 makes this an infinite horizon consumer **GIC_fails_dictionary) GICFailsExample.DiscFac = DiscFac GICFailsExample.PermShkStd = [PermShkStd] GICFailsExample.UnempPrb = UnempPrb GICFailsExample.updateIncomeProcess() GICFailsExample.checkConditions() # Get calibrated parameters to make code more readable LivPrb = GICFailsExample.LivPrb[0] Rfree = GICFailsExample.Rfree DiscFac = GICFailsExample.DiscFac CRRA = GICFailsExample.CRRA permShkPrbs = GICFailsExample.PermShkDstn[0].pmf permShkVals = GICFailsExample.PermShkDstn[0].X EPermGroFac = GICFailsExample.PermGroFac[0] # np.dot multiplies vectors; probability times value for each outcome is expectation EpermShkInv = np.dot(permShkPrbs, permShkVals**(-1)) # $ \Ex[\permShk^{-1}] $ InvEpermShkInv = (EpermShkInv)**(-1) # $ (\Ex[\permShk^{-1}])^{-1}$ PermGroFac = EPermGroFac * InvEpermShkInv # Uncertainty-adjusted permanent growth factor ERNrmFac = Rfree / PermGroFac # Interest factor normalized by uncertainty-adjusted growth ErNrmRte = ERNrmFac - 1 # Interest rate is interest factor - 1 # "sustainable" C = P + (discounted) interest income # "sustainable" c = 1 + (discounted, normalized) interest income EmDelEq0 = lambda m: 1 + (m - 1) * (ErNrmRte / ERNrmFac ) # "sustainable" c where E[Δ m] = 0 GICFailsExample.solve( ) # Above, we set up the problem but did not solve it GICFailsExample.unpack( 'cFunc' ) # Make the consumption function easily accessible for plotting mPlotMin = 0 mPts = 1000 m = np.linspace(mPlotMin, 5, mPts) c_Limt = GICFailsExample.cFunc[0](m) c_Sstn = EmDelEq0(m) # "sustainable" consumption plt.figure(figsize=(12, 8)) plt.plot(m, c_Limt, label="$c(m_{t})$") plt.plot(m, c_Sstn, label="$\mathsf{E}_{t}[\Delta m_{t+1}] = 0$") plt.xlim(0, 5.5) plt.ylim(0, 1.6) plt.tick_params( labelbottom=False, labelleft=False, left="off", right="off", bottom="off", top="off", ) plt.legend(fontsize='x-large') plt.show() print(f'Current Growth Impatience Factor is {GICFailsExample.GPFInd}') return None
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