# Because we are trying to solve a problem very close to the critical patience values # be sure to do it with extra precision # Solve with twice the normal number of gridpoints GICNrmFailsButGICRawHoldsDict['aXtraMax'] = base_params['aXtraCount'] * 2 # Solve over a four times larger range GICNrmFailsButGICRawHoldsDict['aXtraCount'] = base_params['aXtraCount'] * 4 GICNrmFailsButGICRawHolds = IndShockConsumerType( cycles=0, # cycles=0 makes this an infinite horizon consumer verbose=3, # by default, check conditions won't print out any information **GICNrmFailsButGICRawHoldsDict) # Solve to a tighter than usual degree of error tolerance GICNrmFailsButGICRawHolds.tolerance = GICNrmFailsButGICRawHolds.tolerance/100 # The check_conditions method does what it sounds like it would # verbose=0: Print nothing; # verbose=3: Print all available info GICNrmFailsButGICRawHolds.solve(verbose=2) # %% {"jupyter": {"source_hidden": true}, "tags": []} # Plot GICNrmFailsButGICRawHolds #fig = plt.figure(figsize = (12,8)) # ax = fig.add_subplot(111) fig, ax = plt.subplots(figsize=(12, 8)) [xMin, xMax] = [0.0, 8.0]
def cGroTargetFig_make(PermGroFac, DiscFac): gro_params = deepcopy(base_params) gro_params['PermGroFac'] = [PermGroFac] gro_params['DiscFac'] = DiscFac gro_params['aXtraGrid'] = 40 gro_params['aXtraMax'] = 100 baseAgent_Inf = IndShockConsumerType( **gro_params, quietly=True, messaging_level=logging.WARNING) # construct it silently baseAgent_Inf.tolerance = baseAgent_Inf.tolerance / 10 baseAgent_Inf.solve(quietly=True, messaging_level=logging.WARNING) soln = baseAgent_Inf.solution[0] # shorthand Bilt, Pars, E_Next_, cFunc = soln.Bilt, soln.Pars, soln.E_Next_, soln.cFunc Rfree, DiscFac, CRRA, G = Pars.Rfree, Pars.DiscFac, Pars.CRRA, Pars.PermGroFac color_cons, color_mrktLev, color_mrktRat, color_perm = "blue", "red", "green", "orange" mPlotMin, mCalcMax, mPlotMax = 0.3, 50, 8 # Get StE and target values mNrmStE, mNrmTrg = Bilt.mNrmStE, Bilt.mNrmTrg pts_num = 200 # Plot this many points m_pts = np.linspace(1, mPlotMax, pts_num) # values of m for plot c_pts = soln.cFunc(m_pts) # values of c for plot a_pts = m_pts - c_pts # values of a Ex_cLev_tp1_Over_pLev_t = [ E_Next_.cLev_tp1_Over_pLev_t_from_a_t(a) for a in a_pts ] Ex_mLev_tp1_Over_pLev_t = [ E_Next_.mLev_tp1_Over_pLev_t_from_a_t(a) for a in a_pts ] Ex_m_tp1_from_a_t = [E_Next_.m_tp1_from_a_t(a) for a in a_pts] Ex_cLevGro = np.array(Ex_cLev_tp1_Over_pLev_t) / c_pts Ex_mLevGro = np.array(Ex_mLev_tp1_Over_pLev_t) / m_pts Ex_mRatGro = np.array(Ex_m_tp1_from_a_t) / m_pts # Absolute Patience Factor = lower bound of consumption growth factor APF = (Rfree * DiscFac)**(1.0 / CRRA) fig, ax = plt.subplots(figsize=(12, 4)) # Plot the Absolute Patience Factor line ax.plot([0, mPlotMax], [APF, APF], color=color_cons, linestyle='dashed') # Plot the Permanent Income Growth Factor line ax.plot([0, mPlotMax], [G, G], color=color_perm) # Plot the expected consumption growth factor ax.plot( m_pts, Ex_cLevGro, color=color_cons, label= r'$\mathbf{c}$-Level-Growth: $\mathbb{E}_{t}[{\mathbf{c}}_{t+1}/{\mathbf{c}}_{t}]$' ) # Plot the expect growth for the level of market resources mLevGro_lbl, = ax.plot( m_pts, Ex_mLevGro, color=color_mrktLev, label= r'$\mathbf{m}$-Level-Growth: $\mathbb{E}_{t}[{\mathbf{m}}_{t+1}/{\mathbf{m}}_{t}]$' ) # Plot the expect growth for the market resources ratio mRatGro_lbl, = ax.plot( m_pts, Ex_mRatGro, color=color_mrktRat, label=r'$m$-ratio Growth: $\mathbb{E}_{t}[m_{t+1}/m_{t}]$') # Axes limits GroFacMin, GroFacMax, xMin = 0.96, 1.08, 1.1 if mNrmStE and mNrmStE < mPlotMax: ax.plot(mNrmStE, PermGroFac, marker=".", markersize=15, color="black") # mLevGro, = ax.plot([mNrmStE, mNrmStE], [0, GroFacMax], color=color_mrktLev, # label=r'$\mathbf{m}$-Level-Growth: $\mathbb{E}_{t}[{\mathbf{m}}_{t+1}/{\mathbf{m}}_{t}]$') # ax.legend(handles=[mLevGro]) ax.set_xlim(xMin, mPlotMax * 1.2) ax.set_ylim(GroFacMin, GroFacMax) # mRatGro, = ax.plot([mNrmTrg, mNrmTrg], [0, GroFacMax], color=color_mrktRat, ax.legend(handles=[mLevGro_lbl, mRatGro_lbl]) ax.legend(prop=dict(size=fssml)) ax.text(mPlotMax + 0.01, PermGroFac, r"$\Gamma$", fontsize=fssml, fontweight='bold') # ax.text(mPlotMax+0.01, Ex_cLevGro[-1], # r"$\mathsf{E}_{t}[\mathbf{c}_{t+1}/\mathbf{c}_{t}]$", fontsize=fssml, fontweight='bold') ax.text(mPlotMax + 0.01, APF - 0.003, r'$\Phi = (R\beta)^{1/\rho}$', fontsize=fssml, fontweight='bold') # Ticks # ax.tick_params(labelbottom=False, labelleft=True, left='off', ax.tick_params(labelbottom=True, labelleft=True, left='off', right='on', bottom='on', top='off') plt.setp(ax.get_yticklabels(), fontsize=fssml) _log.critical(f'mNrmTrg: {mNrmTrg:.3f}') _log.critical(f'mNrmStE: {mNrmStE:.3f}') plt.legend(fontsize='medium') ax.set_ylabel('Growth Factors', fontsize=fsmid) 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
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
"aNrmInitStd": .5, # Standard deviation of log initial assets "pLvlInitMean": 0, # Mean of log initial permanent income "pLvlInitStd": 0, # Standard deviation of log initial permanent income "PermGroFacAgg": 1.0, # Aggregate permanent income growth factor "T_age": None, # Age after which simulated agents are automatically killed } # %% [markdown] # # Solve # %% collapsed=true jupyter={"outputs_hidden": true, "source_hidden": true} fast = IndShockConsumerType(**Harmenberg_Dict, verbose=1) fast.cycles = 0 fast.Rfree = 1.2**.25 fast.PermGroFac = [1.02] fast.tolerance = fast.tolerance / 100 fast.track_vars = ['cNrm', 'pLvl'] fast.solve(verbose=False) # %% [markdown] # # Calculate Patience Conditions # %% collapsed=true jupyter={"outputs_hidden": true} fast.check_conditions(verbose=True) # %% jupyter={"source_hidden": true} # Simulate a population fast.initialize_sim() fast.simulate() print('done')