def setUp(self): """ Prepare to compare the models by initializing and solving them """ # Set up and solve infinite type import HARK.ConsumptionSaving.ConsumerParameters as Params InfiniteType = IndShockConsumerType(**Params.init_idiosyncratic_shocks) InfiniteType.assignParameters( LivPrb=[1.], DiscFac=0.955, PermGroFac=[1.], PermShkStd=[0.], TempShkStd=[0.], T_total=1, T_retire=0, BoroCnstArt=None, UnempPrb=0., cycles=0) # This is what makes the type infinite horizon InfiniteType.updateIncomeProcess() InfiniteType.solve() InfiniteType.timeFwd() InfiniteType.unpackcFunc() # Make and solve a perfect foresight consumer type with the same parameters PerfectForesightType = deepcopy(InfiniteType) PerfectForesightType.solveOnePeriod = solvePerfForesight PerfectForesightType.solve() PerfectForesightType.unpackcFunc() PerfectForesightType.timeFwd() self.InfiniteType = InfiniteType self.PerfectForesightType = PerfectForesightType
def test_infinite_horizon(self): baseEx_inf = IndShockConsumerType(cycles=0, **self.base_params) baseEx_inf.solve() baseEx_inf.unpackcFunc() m1 = np.linspace(1,baseEx_inf.solution[0].mNrmSS,50) # m1 defines the plot range on the left of target m value (e.g. m <= target m) c_m1 = baseEx_inf.cFunc[0](m1) self.assertAlmostEqual(c_m1[0], 0.8527887545025995) self.assertAlmostEqual(c_m1[-1], 1.0036279936408656) x1 = np.linspace(0,25,1000) cfunc_m = baseEx_inf.cFunc[0](x1) self.assertAlmostEqual(cfunc_m[500], 1.8902146173138235) self.assertAlmostEqual(cfunc_m[700], 2.1591451850267176) m = np.linspace(0.001,8,1000) # Use the HARK method derivative to get the derivative of cFunc, and the values are just the MPC MPC = baseEx_inf.cFunc[0].derivative(m) self.assertAlmostEqual(MPC[500], 0.08415000641504392) self.assertAlmostEqual(MPC[700], 0.07173144137912524)
def setUp(self): """ Prepare to compare the models by initializing and solving them """ # Set up and solve infinite type # Define a test dictionary that should have the same solution in the # perfect foresight and idiosyncratic shocks models. test_dictionary = deepcopy(init_idiosyncratic_shocks) test_dictionary['LivPrb'] = [1.] test_dictionary['DiscFac'] = 0.955 test_dictionary['PermGroFac'] = [1.] test_dictionary['PermShkStd'] = [0.] test_dictionary['TranShkStd'] = [0.] test_dictionary['UnempPrb'] = 0. test_dictionary['T_cycle'] = 1 test_dictionary['T_retire'] = 0 test_dictionary['BoroCnstArt'] = None InfiniteType = IndShockConsumerType(**test_dictionary) InfiniteType.cycles = 0 InfiniteType.updateIncomeProcess() InfiniteType.solve() InfiniteType.unpackcFunc() # Make and solve a perfect foresight consumer type with the same parameters PerfectForesightType = PerfForesightConsumerType(**test_dictionary) PerfectForesightType.cycles = 0 PerfectForesightType.solve() PerfectForesightType.unpackcFunc() self.InfiniteType = InfiniteType self.PerfectForesightType = PerfectForesightType
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.unpackcFunc() # 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): 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() baseAgent_Inf.solve() baseAgent_Inf.unpackcFunc() if (baseAgent_Inf.GIFInd >= 1): baseAgent_Inf.checkGICInd(verbose=3) else: mBelwTrg = np.linspace(0, 4, 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(0, 3) plt.ylim(0, 1.45) 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 test_GICFails(self): GIC_fail_dictionary = dict(self.base_params) GIC_fail_dictionary['Rfree'] = 1.08 GIC_fail_dictionary['PermGroFac'] = [1.00] GICFailExample = IndShockConsumerType( cycles=0, # cycles=0 makes this an infinite horizon consumer **GIC_fail_dictionary) GICFailExample.solve() GICFailExample.unpackcFunc() m = np.linspace(0,5,1000) c_m = GICFailExample.cFunc[0](m) self.assertAlmostEqual(c_m[500], 0.7772637042393458) self.assertAlmostEqual(c_m[700], 0.8392649061916746) self.assertFalse(GICFailExample.GICPF)
def test_baseEx(self): baseEx = IndShockConsumerType(**self.base_params) baseEx.cycles = 100 # Make this type have a finite horizon (Set T = 100) baseEx.solve() baseEx.unpackcFunc() m = np.linspace(0,9.5,1000) c_m = baseEx.cFunc[0](m) c_t1 = baseEx.cFunc[-2](m) c_t5 = baseEx.cFunc[-6](m) c_t10 = baseEx.cFunc[-11](m) self.assertAlmostEqual(c_m[500], 1.4008090582203356) self.assertAlmostEqual(c_t1[500], 2.9227437159255216) self.assertAlmostEqual(c_t5[500], 1.7350607327187664) self.assertAlmostEqual(c_t10[500], 1.4991390649979213) self.assertAlmostEqual(c_t10[600], 1.6101476268581576) self.assertAlmostEqual(c_t10[700], 1.7196531041366991)
# %% LifecycleExample = IndShockConsumerType(**LifecycleDict) LifecycleExample.cycles = 1 # Make this consumer live a sequence of periods -- a lifetime -- exactly once LifecycleExample.solve() print('First element of solution is',LifecycleExample.solution[0]) print('Solution has', len(LifecycleExample.solution),'elements.') # %% [markdown] # This was supposed to be a *ten* period lifecycle model-- why does our consumer type have *eleven* elements in its $\texttt{solution}$? It would be more precise to say that this specification has ten *non-terminal* periods. The solution to the 11th and final period in the model would be the same for every set of parameters: consume $c_t = m_t$, because there is no future. In a lifecycle model, the terminal period is assumed to exist; the $\texttt{LivPrb}$ parameter does not need to end with a $0.0$ in order to guarantee that survivors die. # # We can quickly plot the consumption functions in each period of the model: # %% print('Consumption functions across the lifecycle:') mMin = np.min([LifecycleExample.solution[t].mNrmMin for t in range(LifecycleExample.T_cycle)]) LifecycleExample.unpackcFunc() # This makes all of the cFuncs accessible in the attribute cFunc plotFuncs(LifecycleExample.cFunc,mMin,5) # %% [markdown] # ### "Cyclical" example # # We can also model consumers who face an infinite horizon, but who do *not* face the same problem in every period. Consider someone who works as a ski instructor: they make most of their income for the year in the winter, and make very little money in the other three seasons. # # We can represent this type of individual as a four period, infinite horizon model in which expected "permanent" income growth varies greatly across seasons. # %% {"code_folding": [0]} CyclicalDict = { # Click the arrow to expand this parameter dictionary # Parameters shared with the perfect foresight model "CRRA": 2.0, # Coefficient of relative risk aversion "Rfree": 1.03, # Interest factor on assets "DiscFac": 0.96, # Intertemporal discount factor
'T_age': None, # Age after which simulated agents are automatically killed 'T_cycle': 1 # Number of periods in the cycle for this agent type } # In[ ]: # Create the baseline instance by passing the dictionary to the class. BaselineExample = IndShockConsumerType(**baseline_bufferstock_dictionary) BaselineExample.cycles = 100 # Make this type have an finite horizon (Set T = 100) start_time = clock() BaselineExample.solve() end_time = clock() print('Solving a baseline buffer stock saving model (100 periods) took ' + mystr(end_time - start_time) + ' seconds.') BaselineExample.unpackcFunc() BaselineExample.timeFwd() # In[ ]: # Now we start plotting the different periods' consumption rules. m1 = np.linspace(0, 9.5, 1000) # Set the plot range of m m2 = np.linspace(0, 6.5, 500) c_m = BaselineExample.cFunc[0]( m1 ) # c_m can be used to define the limiting infinite-horizon consumption rule here c_t1 = BaselineExample.cFunc[-2]( m1) # c_t1 defines the second-to-last period consumption rule c_t5 = BaselineExample.cFunc[-6]( m1) # c_t5 defines the T-5 period consumption rule
# ## Convergence of the Consumption Rules # # Under the given parameter values, [the paper's first figure](http://econ.jhu.edu/people/ccarroll/papers/BufferStockTheory/#Convergence-of-the-Consumption-Rules) depicts the successive consumption rules that apply in the last period of life $(c_{T}(m))$, the second-to-last period, and earlier periods $(c_{T-n})$. $c(m)$ is the consumption function to which these converge as # # \[ # c(m) = \lim_{n \uparrow \infty} c_{T-n}(m) # \] # # %% {"hidden": true} # Create a buffer stock consumer instance by passing the dictionary to the class. baseEx = IndShockConsumerType(**base_params) baseEx.cycles = 100 # Make this type have a finite horizon (Set T = 100) baseEx.solve() # Solve the model baseEx.unpackcFunc() # Make the consumption function easily accessible # %% {"hidden": true} # Plot the different periods' consumption rules. m1 = np.linspace(0,9.5,1000) # Set the plot range of m m2 = np.linspace(0,6.5,500) c_m = baseEx.cFunc[0](m1) # c_m can be used to define the limiting infinite-horizon consumption rule here c_t1 = baseEx.cFunc[-2](m1) # c_t1 defines the second-to-last period consumption rule c_t5 = baseEx.cFunc[-6](m1) # c_t5 defines the T-5 period consumption rule c_t10 = baseEx.cFunc[-11](m1) # c_t10 defines the T-10 period consumption rule c_t0 = m2 # c_t0 defines the last period consumption rule plt.figure(figsize = (12,9)) plt.plot(m1,c_m,color="black") plt.plot(m1,c_t1,color="black")
PFexample.track_vars = ["mNrmNow"] PFexample.initializeSim() PFexample.simulate() # %% # Make and solve an example consumer with idiosyncratic income shocks IndShockExample = IndShockConsumerType() IndShockExample.cycles = 0 # Make this type have an infinite horizon # %% start_time = time() IndShockExample.solve() end_time = time() print("Solving a consumer with idiosyncratic shocks took " + mystr(end_time - start_time) + " seconds.") IndShockExample.unpackcFunc() IndShockExample.timeFwd() # %% # Plot the consumption function and MPC for the infinite horizon consumer print("Concave consumption function:") plotFuncs(IndShockExample.cFunc[0], IndShockExample.solution[0].mNrmMin, 5) print("Marginal consumption function:") plotFuncsDer(IndShockExample.cFunc[0], IndShockExample.solution[0].mNrmMin, 5) # %% # Compare the consumption functions for the perfect foresight and idiosyncratic # shock types. Risky income cFunc asymptotically approaches perfect foresight cFunc. print("Consumption functions for perfect foresight vs idiosyncratic shocks:") plotFuncs( [PFexample.cFunc[0], IndShockExample.cFunc[0]],
base_params_dolo['UnempPrb'] = 0 # No point-mass on unemployment state base_params_dolo['TranShkCount'] = 5 # Default number of nodes in dolo base_params_dolo['PermShkCount'] = 5 base_params_dolo['aXtraMax'] = max_m # Use same maximum base_params_dolo['aXtraCount'] = 100 # How dense to make the grid base_params_dolo['DiscFac'] = 0.96 #base_params_dolo['CubicBool'] = False model_HARK = IndShockConsumerType( **base_params_dolo, cycles=0) # cycles=0 indicates infinite horizon # %% # Solve the HARK model model_HARK.updateIncomeProcess() model_HARK.solve() model_HARK.UnempPrb = 0.05 model_HARK.unpackcFunc() # %% # Plot the results: Green is perfect foresight, red is HARK, black is dolo tab = tabulate(model_dolo, dr, 'm') plt.plot(tab['m'], tab['c']) # This is pretty cool syntax m = tab.iloc[:, 2] c_m = model_HARK.cFunc[0](m) # cPF uses the analytical formula for the perfect foresight solution cPF = (np.array(m) - 1 + 1 / (1 - PermGroFac / Rfree)) * ((Rfree - (Rfree * DiscFac)**(1 / CRRA)) / Rfree) plt.plot(tab['m'], c_m, color="red") plt.plot(m, cPF, color="green")
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.unpackcFunc() # 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 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() baseAgent_Inf.solve() baseAgent_Inf.unpackcFunc() if (baseAgent_Inf.GIFInd >= 1): baseAgent_Inf.checkGICInd(verbose=3) elif baseAgent_Inf.solution[0].mNrmSS > 3.5: print('Solution 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 mBelwTrg = np.linspace(1, mNrmTrg, 50) 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, 3.5, 50) # 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([0, 3.5], [APF, APF], label="\u03A6 = [(\u03B2 R)^(1/ \u03C1)]/R") # Plot the Permanent Income Growth Factor line plt.plot([0, 3.5], [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], [0, 3.5], color="black", linestyle="--", label="", ) plt.xlim(1, 3.5) 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
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 print(f'Current Growth Impatience Factor is {GICFailsExample.GIFInd}') GICFailsExample.solve( ) # Above, we set up the problem but did not solve it GICFailsExample.unpackcFunc( ) # 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() return None
# - # ## Counterclockwise Concavification # # + {"code_folding": [0]} # This figure illustrates how both risks and constraints are examples of counterclockwise concavifications. # It plots three lines: the linear consumption function of a perfect foresight consumer, the kinked consumption # function of a consumer who faces a constraint, and the curved consumption function of a consumer that faces risk. # load the three agents: unconstrained perfect foresight, constrained perfect foresight, unconstrained with risk CCC_unconstr = IndShockConsumerType(**init_lifecycle) CCC_unconstr.delFromTimeInv('BoroCnstArt') CCC_unconstr.addToTimeVary('BoroCnstArt') CCC_unconstr.solve() CCC_unconstr.unpackcFunc() CCC_unconstr.timeFwd() CCC_constraint = IndShockConsumerType(**init_lifecycle) CCC_constraint.delFromTimeInv('BoroCnstArt') CCC_constraint.addToTimeVary('BoroCnstArt') CCC_constraint( BoroCnstArt=[None, -1, None, None, None, None, None, None, None, None]) CCC_constraint.solve() CCC_constraint.unpackcFunc() CCC_constraint.timeFwd() CCC_risk = IndShockConsumerType(**init_lifecycle_risk1) CCC_risk.delFromTimeInv('BoroCnstArt') CCC_risk.addToTimeVary('BoroCnstArt') CCC_risk.solve()
# # $$ # c(m) = \lim_{n \uparrow \infty} c_{T-n}(m) \notag # $$ # # %% # Create a buffer stock consumer instance by invoking the IndShockConsumerType class # with the built-in parameter dictionary "base_params" # Construct finite horizon agent with baseline parameters baseAgent_Fin = IndShockConsumerType(**base_params) baseAgent_Fin.cycles = 100 # Set finite horizon (T = 100) baseAgent_Fin.solve() # Solve the model baseAgent_Fin.unpackcFunc() # Make the consumption function easily accessible # %% # Plot the different consumption rules for the different periods mPlotMin = 0 mLocCLabels = 9.6 # Defines horizontal limit of figure mPlotTop = 6.5 # Defines maximum m value where functions are plotted mPts = 1000 # Number of points at which functions are evaluated 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