Coverage for HARK/ConsumptionSaving/ConsGenIncProcessModel.py: 89%
312 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-02 05:14 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-02 05:14 +0000
1"""
2Classes to solve consumption-saving models with idiosyncratic shocks to income
3in which shocks are not necessarily fully transitory or fully permanent. Extends
4ConsIndShockModel by explicitly tracking persistent income as a state variable,
5and allows (log) persistent income to follow an AR1 process rather than random walk.
6"""
8import numpy as np
10from HARK import AgentType, NullFunc
11from HARK.Calibration.Income.IncomeProcesses import (
12 construct_lognormal_income_process_unemployment,
13 get_PermShkDstn_from_IncShkDstn,
14 get_TranShkDstn_from_IncShkDstn,
15 pLvlFuncAR1,
16 make_trivial_pLvlNextFunc,
17 make_explicit_perminc_pLvlNextFunc,
18 make_AR1_style_pLvlNextFunc,
19 make_pLvlGrid_by_simulation,
20 make_basic_pLvlPctiles,
21)
22from HARK.ConsumptionSaving.ConsIndShockModel import (
23 ConsumerSolution,
24 IndShockConsumerType,
25 make_lognormal_kNrm_init_dstn,
26 make_lognormal_pLvl_init_dstn,
27)
28from HARK.distributions import expected
29from HARK.interpolation import (
30 BilinearInterp,
31 ConstantFunction,
32 CubicInterp,
33 IdentityFunction,
34 LinearInterp,
35 LinearInterpOnInterp1D,
36 LowerEnvelope2D,
37 MargMargValueFuncCRRA,
38 MargValueFuncCRRA,
39 UpperEnvelope,
40 ValueFuncCRRA,
41 VariableLowerBoundFunc2D,
42)
43from HARK.rewards import (
44 CRRAutility,
45 CRRAutility_inv,
46 CRRAutility_invP,
47 CRRAutilityP,
48 CRRAutilityP_inv,
49 CRRAutilityP_invP,
50 CRRAutilityPP,
51 UtilityFuncCRRA,
52)
53from HARK.utilities import make_assets_grid
55__all__ = [
56 "pLvlFuncAR1",
57 "GenIncProcessConsumerType",
58 "IndShockExplicitPermIncConsumerType",
59 "PersistentShockConsumerType",
60 "init_explicit_perm_inc",
61 "init_persistent_shocks",
62]
64utility = CRRAutility
65utilityP = CRRAutilityP
66utilityPP = CRRAutilityPP
67utilityP_inv = CRRAutilityP_inv
68utility_invP = CRRAutility_invP
69utility_inv = CRRAutility_inv
70utilityP_invP = CRRAutilityP_invP
73###############################################################################
76def make_2D_CRRA_solution_terminal(CRRA):
77 """
78 Construct the terminal period solution for a consumption-saving model with CRRA
79 utility and two state variables: levels of market resources and permanent income.
81 Parameters
82 ----------
83 CRRA : float
84 Coefficient of relative risk aversion. This is the only relevant parameter.
86 Returns
87 -------
88 solution_terminal : ConsumerSolution
89 Terminal period solution for someone with the given CRRA.
90 """
91 cFunc_terminal = IdentityFunction(i_dim=0, n_dims=2)
92 vFunc_terminal = ValueFuncCRRA(cFunc_terminal, CRRA)
93 vPfunc_terminal = MargValueFuncCRRA(cFunc_terminal, CRRA)
94 vPPfunc_terminal = MargMargValueFuncCRRA(cFunc_terminal, CRRA)
95 solution_terminal = ConsumerSolution(
96 cFunc=cFunc_terminal,
97 vFunc=vFunc_terminal,
98 vPfunc=vPfunc_terminal,
99 vPPfunc=vPPfunc_terminal,
100 mNrmMin=ConstantFunction(0.0),
101 hNrm=ConstantFunction(0.0),
102 MPCmin=1.0,
103 MPCmax=1.0,
104 )
105 solution_terminal.hLvl = solution_terminal.hNrm
106 solution_terminal.mLvlMin = solution_terminal.mNrmMin
107 return solution_terminal
110def solve_one_period_ConsGenIncProcess(
111 solution_next,
112 IncShkDstn,
113 LivPrb,
114 DiscFac,
115 CRRA,
116 Rfree,
117 pLvlNextFunc,
118 BoroCnstArt,
119 aXtraGrid,
120 pLvlGrid,
121 vFuncBool,
122 CubicBool,
123):
124 """
125 Solves one one period problem of a consumer who experiences persistent and
126 transitory shocks to his income. Unlike in ConsIndShock, consumers do not
127 necessarily have the same predicted level of p next period as this period
128 (after controlling for growth). Instead, they have a function that translates
129 current persistent income into expected next period persistent income (subject
130 to shocks).
132 Parameters
133 ----------
134 solution_next : ConsumerSolution
135 The solution to next period's one period problem.
136 IncShkDstn : distribution.Distribution
137 A discrete
138 approximation to the income process between the period being solved
139 and the one immediately following (in solution_next). Order: event
140 probabilities, persistent shocks, transitory shocks.
141 LivPrb : float
142 Survival probability; likelihood of being alive at the beginning of
143 the succeeding period.
144 DiscFac : float
145 Intertemporal discount factor for future utility.
146 CRRA : float
147 Coefficient of relative risk aversion.
148 Rfree : float
149 Risk free interest factor on end-of-period assets.
150 pLvlNextFunc : float
151 Expected persistent income next period as a function of current pLvl.
152 BoroCnstArt: float or None
153 Borrowing constraint for the minimum allowable assets to end the
154 period with.
155 aXtraGrid: np.array
156 Array of "extra" end-of-period (normalized) asset values-- assets
157 above the absolute minimum acceptable level.
158 pLvlGrid: np.array
159 Array of persistent income levels at which to solve the problem.
160 vFuncBool: boolean
161 An indicator for whether the value function should be computed and
162 included in the reported solution.
163 CubicBool: boolean
164 An indicator for whether the solver should use cubic or linear interpolation.
166 Returns
167 -------
168 solution_now : ConsumerSolution
169 Solution to this period's consumption-saving problem.
170 """
171 # Define the utility function for this period
172 uFunc = UtilityFuncCRRA(CRRA)
173 DiscFacEff = DiscFac * LivPrb # "effective" discount factor
175 # Unpack next period's income shock distribution
176 ShkPrbsNext = IncShkDstn.pmv
177 PermShkValsNext = IncShkDstn.atoms[0]
178 TranShkValsNext = IncShkDstn.atoms[1]
179 PermShkMinNext = np.min(PermShkValsNext)
180 TranShkMinNext = np.min(TranShkValsNext)
182 # Calculate the probability that we get the worst possible income draw
183 IncNext = PermShkValsNext * TranShkValsNext
184 WorstIncNext = PermShkMinNext * TranShkMinNext
185 WorstIncPrb = np.sum(ShkPrbsNext[IncNext == WorstIncNext])
186 # WorstIncPrb is the "Weierstrass p" concept: the odds we get the WORST thing
188 # Unpack next period's (marginal) value function
189 vFuncNext = solution_next.vFunc # This is None when vFuncBool is False
190 vPfuncNext = solution_next.vPfunc
191 vPPfuncNext = solution_next.vPPfunc # This is None when CubicBool is False
193 # Update the bounding MPCs and PDV of human wealth:
194 PatFac = ((Rfree * DiscFacEff) ** (1.0 / CRRA)) / Rfree
195 try:
196 MPCminNow = 1.0 / (1.0 + PatFac / solution_next.MPCmin)
197 except:
198 MPCminNow = 0.0
199 mLvlMinNext = solution_next.mLvlMin
201 # TODO: Deal with this unused code for the upper bound of MPC (should be a function now)
202 # Ex_IncNext = np.dot(ShkPrbsNext, TranShkValsNext * PermShkValsNext)
203 # hNrmNow = 0.0
204 # temp_fac = (WorstIncPrb ** (1.0 / CRRA)) * PatFac
205 # MPCmaxNow = 1.0 / (1.0 + temp_fac / solution_next.MPCmax)
207 # Define some functions for calculating future expectations
208 def calc_pLvl_next(S, p):
209 return pLvlNextFunc(p) * S["PermShk"]
211 def calc_mLvl_next(S, a, p_next):
212 return Rfree * a + p_next * S["TranShk"]
214 def calc_hLvl(S, p):
215 pLvl_next = calc_pLvl_next(S, p)
216 hLvl = S["TranShk"] * pLvl_next + solution_next.hLvl(pLvl_next)
217 return hLvl
219 def calc_v_next(S, a, p):
220 pLvl_next = calc_pLvl_next(S, p)
221 mLvl_next = calc_mLvl_next(S, a, pLvl_next)
222 v_next = vFuncNext(mLvl_next, pLvl_next)
223 return v_next
225 def calc_vP_next(S, a, p):
226 pLvl_next = calc_pLvl_next(S, p)
227 mLvl_next = calc_mLvl_next(S, a, pLvl_next)
228 vP_next = vPfuncNext(mLvl_next, pLvl_next)
229 return vP_next
231 def calc_vPP_next(S, a, p):
232 pLvl_next = calc_pLvl_next(S, p)
233 mLvl_next = calc_mLvl_next(S, a, pLvl_next)
234 vPP_next = vPPfuncNext(mLvl_next, pLvl_next)
235 return vPP_next
237 # Construct human wealth level as a function of productivity pLvl
238 hLvlGrid = 1.0 / Rfree * expected(calc_hLvl, IncShkDstn, args=(pLvlGrid))
239 hLvlNow = LinearInterp(np.insert(pLvlGrid, 0, 0.0), np.insert(hLvlGrid, 0, 0.0))
241 # Make temporary grids of income shocks and next period income values
242 ShkCount = TranShkValsNext.size
243 pLvlCount = pLvlGrid.size
244 PermShkVals_temp = np.tile(
245 np.reshape(PermShkValsNext, (1, ShkCount)), (pLvlCount, 1)
246 )
247 TranShkVals_temp = np.tile(
248 np.reshape(TranShkValsNext, (1, ShkCount)), (pLvlCount, 1)
249 )
250 pLvlNext_temp = (
251 np.tile(
252 np.reshape(pLvlNextFunc(pLvlGrid), (pLvlCount, 1)),
253 (1, ShkCount),
254 )
255 * PermShkVals_temp
256 )
258 # Find the natural borrowing constraint for each persistent income level
259 aLvlMin_candidates = (
260 mLvlMinNext(pLvlNext_temp) - TranShkVals_temp * pLvlNext_temp
261 ) / Rfree
262 aLvlMinNow = np.max(aLvlMin_candidates, axis=1)
263 BoroCnstNat = LinearInterp(
264 np.insert(pLvlGrid, 0, 0.0), np.insert(aLvlMinNow, 0, 0.0)
265 )
267 # Define the minimum allowable mLvl by pLvl as the greater of the natural and artificial borrowing constraints
268 if BoroCnstArt is not None:
269 BoroCnstArt = LinearInterp(np.array([0.0, 1.0]), np.array([0.0, BoroCnstArt]))
270 mLvlMinNow = UpperEnvelope(BoroCnstArt, BoroCnstNat)
271 else:
272 mLvlMinNow = BoroCnstNat
274 # Define the constrained consumption function as "consume all" shifted by mLvlMin
275 cFuncNowCnstBase = BilinearInterp(
276 np.array([[0.0, 0.0], [1.0, 1.0]]),
277 np.array([0.0, 1.0]),
278 np.array([0.0, 1.0]),
279 )
280 cFuncNowCnst = VariableLowerBoundFunc2D(cFuncNowCnstBase, mLvlMinNow)
282 # Define grids of pLvl and aLvl on which to compute future expectations
283 pLvlCount = pLvlGrid.size
284 aNrmCount = aXtraGrid.size
285 pLvlNow = np.tile(pLvlGrid, (aNrmCount, 1)).transpose()
286 aLvlNow = np.tile(aXtraGrid, (pLvlCount, 1)) * pLvlNow + BoroCnstNat(pLvlNow)
287 # shape = (pLvlCount,aNrmCount)
288 if pLvlGrid[0] == 0.0: # aLvl turns out badly if pLvl is 0 at bottom
289 aLvlNow[0, :] = aXtraGrid
291 # Calculate end-of-period marginal value of assets
292 EndOfPrd_vP = (
293 DiscFacEff * Rfree * expected(calc_vP_next, IncShkDstn, args=(aLvlNow, pLvlNow))
294 )
296 # If the value function has been requested, construct the end-of-period vFunc
297 if vFuncBool:
298 # Compute expected value from end-of-period states
299 EndOfPrd_v = expected(calc_v_next, IncShkDstn, args=(aLvlNow, pLvlNow))
300 EndOfPrd_v *= DiscFacEff
302 # Transformed value through inverse utility function to "decurve" it
303 EndOfPrd_vNvrs = uFunc.inv(EndOfPrd_v)
304 EndOfPrd_vNvrsP = EndOfPrd_vP * uFunc.derinv(EndOfPrd_v, order=(0, 1))
306 # Add points at mLvl=zero
307 EndOfPrd_vNvrs = np.concatenate(
308 (np.zeros((pLvlCount, 1)), EndOfPrd_vNvrs), axis=1
309 )
310 EndOfPrd_vNvrsP = np.concatenate(
311 (
312 np.reshape(EndOfPrd_vNvrsP[:, 0], (pLvlCount, 1)),
313 EndOfPrd_vNvrsP,
314 ),
315 axis=1,
316 )
317 # This is a very good approximation, vNvrsPP = 0 at the asset minimum
319 # Make a temporary aLvl grid for interpolating the end-of-period value function
320 aLvl_temp = np.concatenate(
321 (
322 np.reshape(BoroCnstNat(pLvlGrid), (pLvlGrid.size, 1)),
323 aLvlNow,
324 ),
325 axis=1,
326 )
328 # Make an end-of-period value function for each persistent income level in the grid
329 EndOfPrd_vNvrsFunc_list = []
330 for p in range(pLvlCount):
331 EndOfPrd_vNvrsFunc_list.append(
332 CubicInterp(
333 aLvl_temp[p, :] - BoroCnstNat(pLvlGrid[p]),
334 EndOfPrd_vNvrs[p, :],
335 EndOfPrd_vNvrsP[p, :],
336 )
337 )
338 EndOfPrd_vNvrsFuncBase = LinearInterpOnInterp1D(
339 EndOfPrd_vNvrsFunc_list, pLvlGrid
340 )
342 # Re-adjust the combined end-of-period value function to account for the
343 # natural borrowing constraint shifter and "re-curve" it
344 EndOfPrd_vNvrsFunc = VariableLowerBoundFunc2D(
345 EndOfPrd_vNvrsFuncBase, BoroCnstNat
346 )
347 EndOfPrd_vFunc = ValueFuncCRRA(EndOfPrd_vNvrsFunc, CRRA)
349 # Solve the first order condition to get optimal consumption, then find the
350 # endogenous gridpoints
351 cLvlNow = uFunc.derinv(EndOfPrd_vP, order=(1, 0))
352 mLvlNow = cLvlNow + aLvlNow
354 # Limiting consumption is zero as m approaches mNrmMin
355 c_for_interpolation = np.concatenate((np.zeros((pLvlCount, 1)), cLvlNow), axis=-1)
356 m_for_interpolation = np.concatenate(
357 (
358 BoroCnstNat(np.reshape(pLvlGrid, (pLvlCount, 1))),
359 mLvlNow,
360 ),
361 axis=-1,
362 )
364 # Limiting consumption is MPCmin*mLvl as p approaches 0
365 m_temp = np.reshape(m_for_interpolation[0, :], (1, m_for_interpolation.shape[1]))
366 m_for_interpolation = np.concatenate((m_temp, m_for_interpolation), axis=0)
367 c_for_interpolation = np.concatenate(
368 (MPCminNow * m_temp, c_for_interpolation), axis=0
369 )
371 # Make an array of corresponding pLvl values, adding an additional column for
372 # the mLvl points at the lower boundary *and* an extra row for pLvl=0.
373 p_for_interpolation = np.concatenate(
374 (np.reshape(pLvlGrid, (pLvlCount, 1)), pLvlNow), axis=-1
375 )
376 p_for_interpolation = np.concatenate(
377 (np.zeros((1, m_for_interpolation.shape[1])), p_for_interpolation)
378 )
380 # Build the set of cFuncs by pLvl, gathered in a list
381 cFunc_by_pLvl_list = [] # list of consumption functions for each pLvl
382 if CubicBool:
383 # Calculate end-of-period marginal marginal value of assets
384 vPP_fac = DiscFacEff * Rfree * Rfree
385 EndOfPrd_vPP = expected(calc_vPP_next, IncShkDstn, args=(aLvlNow, pLvlNow))
386 EndOfPrd_vPP *= vPP_fac
388 # Calculate the MPC at each gridpoint
389 dcda = EndOfPrd_vPP / uFunc.der(np.array(c_for_interpolation[1:, 1:]), order=2)
390 MPC = dcda / (dcda + 1.0)
391 MPC = np.concatenate((np.reshape(MPC[:, 0], (MPC.shape[0], 1)), MPC), axis=1)
393 # Stick an extra row of MPC values at pLvl=zero
394 MPC = np.concatenate((MPCminNow * np.ones((1, aNrmCount + 1)), MPC), axis=0)
396 # Make cubic consumption function with respect to mLvl for each persistent income level
397 for j in range(p_for_interpolation.shape[0]):
398 pLvl_j = p_for_interpolation[j, 0]
399 m_temp = m_for_interpolation[j, :] - BoroCnstNat(pLvl_j)
401 # Make a cubic consumption function for this pLvl
402 c_temp = c_for_interpolation[j, :]
403 MPC_temp = MPC[j, :]
404 if pLvl_j > 0:
405 cFunc_by_pLvl_list.append(
406 CubicInterp(
407 m_temp,
408 c_temp,
409 MPC_temp,
410 lower_extrap=True,
411 slope_limit=MPCminNow,
412 intercept_limit=MPCminNow * hLvlNow(pLvl_j),
413 )
414 )
415 else: # When pLvl=0, cFunc is linear
416 cFunc_by_pLvl_list.append(
417 LinearInterp(m_temp, c_temp, lower_extrap=True)
418 )
420 # Basic version: use linear interpolation within a pLvl
421 else:
422 # Loop over pLvl values and make an mLvl for each one
423 for j in range(p_for_interpolation.shape[0]):
424 pLvl_j = p_for_interpolation[j, 0]
425 m_temp = m_for_interpolation[j, :] - BoroCnstNat(pLvl_j)
427 # Make a linear consumption function for this pLvl
428 c_temp = c_for_interpolation[j, :]
429 if pLvl_j > 0:
430 cFunc_by_pLvl_list.append(
431 LinearInterp(
432 m_temp,
433 c_temp,
434 lower_extrap=True,
435 slope_limit=MPCminNow,
436 intercept_limit=MPCminNow * hLvlNow(pLvl_j),
437 )
438 )
439 else:
440 cFunc_by_pLvl_list.append(
441 LinearInterp(m_temp, c_temp, lower_extrap=True)
442 )
444 # Combine all linear cFuncs into one function
445 pLvl_list = p_for_interpolation[:, 0]
446 cFuncUncBase = LinearInterpOnInterp1D(cFunc_by_pLvl_list, pLvl_list)
447 cFuncNowUnc = VariableLowerBoundFunc2D(cFuncUncBase, BoroCnstNat)
448 # Re-adjust for lower bound of natural borrowing constraint
450 # Combine the constrained and unconstrained functions into the true consumption function
451 cFuncNow = LowerEnvelope2D(cFuncNowUnc, cFuncNowCnst)
453 # Make the marginal value function
454 vPfuncNow = MargValueFuncCRRA(cFuncNow, CRRA)
456 # If using cubic spline interpolation, construct the marginal marginal value function
457 if CubicBool:
458 vPPfuncNow = MargMargValueFuncCRRA(cFuncNow, CRRA)
459 else:
460 vPPfuncNow = NullFunc()
462 # If the value function has been requested, construct it now
463 if vFuncBool:
464 # Compute expected value and marginal value on a grid of market resources
465 # Tile pLvl across m values
466 pLvl_temp = np.tile(pLvlGrid, (aNrmCount, 1))
467 mLvl_temp = (
468 np.tile(mLvlMinNow(pLvlGrid), (aNrmCount, 1))
469 + np.tile(np.reshape(aXtraGrid, (aNrmCount, 1)), (1, pLvlCount)) * pLvl_temp
470 )
471 cLvl_temp = cFuncNow(mLvl_temp, pLvl_temp)
472 aLvl_temp = mLvl_temp - cLvl_temp
473 v_temp = uFunc(cLvl_temp) + EndOfPrd_vFunc(aLvl_temp, pLvl_temp)
474 vP_temp = uFunc.der(cLvl_temp)
476 # Calculate pseudo-inverse value and its first derivative (wrt mLvl)
477 vNvrs_temp = uFunc.inv(v_temp) # value transformed through inverse utility
478 vNvrsP_temp = vP_temp * uFunc.derinv(v_temp, order=(0, 1))
480 # Add data at the lower bound of m
481 mLvl_temp = np.concatenate(
482 (np.reshape(mLvlMinNow(pLvlGrid), (1, pLvlCount)), mLvl_temp), axis=0
483 )
484 vNvrs_temp = np.concatenate((np.zeros((1, pLvlCount)), vNvrs_temp), axis=0)
485 vNvrsP_temp = np.concatenate(
486 (np.reshape(vNvrsP_temp[0, :], (1, vNvrsP_temp.shape[1])), vNvrsP_temp),
487 axis=0,
488 )
490 # Add data at the lower bound of p
491 MPCminNvrs = MPCminNow ** (-CRRA / (1.0 - CRRA))
492 m_temp = np.reshape(mLvl_temp[:, 0], (aNrmCount + 1, 1))
493 mLvl_temp = np.concatenate((m_temp, mLvl_temp), axis=1)
494 vNvrs_temp = np.concatenate((MPCminNvrs * m_temp, vNvrs_temp), axis=1)
495 vNvrsP_temp = np.concatenate(
496 (MPCminNvrs * np.ones((aNrmCount + 1, 1)), vNvrsP_temp), axis=1
497 )
499 # Construct the pseudo-inverse value function
500 vNvrsFunc_list = []
501 for j in range(pLvlCount + 1):
502 pLvl = np.insert(pLvlGrid, 0, 0.0)[j]
503 vNvrsFunc_list.append(
504 CubicInterp(
505 mLvl_temp[:, j] - mLvlMinNow(pLvl),
506 vNvrs_temp[:, j],
507 vNvrsP_temp[:, j],
508 MPCminNvrs * hLvlNow(pLvl),
509 MPCminNvrs,
510 )
511 )
512 vNvrsFuncBase = LinearInterpOnInterp1D(
513 vNvrsFunc_list, np.insert(pLvlGrid, 0, 0.0)
514 ) # Value function "shifted"
515 vNvrsFuncNow = VariableLowerBoundFunc2D(vNvrsFuncBase, mLvlMinNow)
517 # "Re-curve" the pseudo-inverse value function into the value function
518 vFuncNow = ValueFuncCRRA(vNvrsFuncNow, CRRA)
520 else:
521 vFuncNow = NullFunc()
523 # Package and return the solution object
524 solution_now = ConsumerSolution(
525 cFunc=cFuncNow,
526 vFunc=vFuncNow,
527 vPfunc=vPfuncNow,
528 vPPfunc=vPPfuncNow,
529 mNrmMin=0.0, # Not a normalized model, mLvlMin will be added below
530 hNrm=0.0, # Not a normalized model, hLvl will be added below
531 MPCmin=MPCminNow,
532 MPCmax=0.0, # This should be a function, need to make it
533 )
534 solution_now.hLvl = hLvlNow
535 solution_now.mLvlMin = mLvlMinNow
536 return solution_now
539###############################################################################
541# Make a constructor dictionary for the general income process consumer type
542GenIncProcessConsumerType_constructors_default = {
543 "IncShkDstn": construct_lognormal_income_process_unemployment,
544 "PermShkDstn": get_PermShkDstn_from_IncShkDstn,
545 "TranShkDstn": get_TranShkDstn_from_IncShkDstn,
546 "aXtraGrid": make_assets_grid,
547 "pLvlPctiles": make_basic_pLvlPctiles,
548 "pLvlGrid": make_pLvlGrid_by_simulation,
549 "pLvlNextFunc": make_trivial_pLvlNextFunc,
550 "solution_terminal": make_2D_CRRA_solution_terminal,
551 "kNrmInitDstn": make_lognormal_kNrm_init_dstn,
552 "pLvlInitDstn": make_lognormal_pLvl_init_dstn,
553}
555# Make a dictionary with parameters for the default constructor for kNrmInitDstn
556GenIncProcessConsumerType_kNrmInitDstn_default = {
557 "kLogInitMean": -12.0, # Mean of log initial capital
558 "kLogInitStd": 0.0, # Stdev of log initial capital
559 "kNrmInitCount": 15, # Number of points in initial capital discretization
560}
562# Make a dictionary with parameters for the default constructor for pLvlInitDstn
563GenIncProcessConsumerType_pLvlInitDstn_default = {
564 "pLogInitMean": 0.0, # Mean of log permanent income
565 "pLogInitStd": 0.4, # Stdev of log permanent income
566 "pLvlInitCount": 15, # Number of points in initial capital discretization
567}
569# Default parameters to make IncShkDstn using construct_lognormal_income_process_unemployment
570GenIncProcessConsumerType_IncShkDstn_default = {
571 "PermShkStd": [0.1], # Standard deviation of log permanent income shocks
572 "PermShkCount": 7, # Number of points in discrete approximation to permanent income shocks
573 "TranShkStd": [0.1], # Standard deviation of log transitory income shocks
574 "TranShkCount": 7, # Number of points in discrete approximation to transitory income shocks
575 "UnempPrb": 0.05, # Probability of unemployment while working
576 "IncUnemp": 0.3, # Unemployment benefits replacement rate while working
577 "T_retire": 0, # Period of retirement (0 --> no retirement)
578 "UnempPrbRet": 0.005, # Probability of "unemployment" while retired
579 "IncUnempRet": 0.0, # "Unemployment" benefits when retired
580}
582# Default parameters to make aXtraGrid using make_assets_grid
583GenIncProcessConsumerType_aXtraGrid_default = {
584 "aXtraMin": 0.001, # Minimum end-of-period "assets above minimum" value
585 "aXtraMax": 30, # Maximum end-of-period "assets above minimum" value
586 "aXtraNestFac": 3, # Exponential nesting factor for aXtraGrid
587 "aXtraCount": 48, # Number of points in the grid of "assets above minimum"
588 "aXtraExtra": [0.005, 0.01], # Additional other values to add in grid (optional)
589}
590GenIncProcessConsumerType_pLvlNextFunc_default = {} # Trivial function has no parameters
592# Default parameters to make pLvlGrid using make_basic_pLvlPctiles
593GenIncProcessConsumerType_pLvlPctiles_default = {
594 "pLvlPctiles_count": 19, # Number of points in the "body" of the grid
595 "pLvlPctiles_bound": [0.05, 0.95], # Percentile bounds of the "body"
596 "pLvlPctiles_tail_count": 4, # Number of points in each tail of the grid
597 "pLvlPctiles_tail_order": np.e, # Scaling factor for points in each tail
598}
600# Default parameters to make pLvlGrid using make_pLvlGrid_by_simulation
601GenIncProcessConsumerType_pLvlGrid_default = {
602 "pLvlExtra": None, # Additional permanent income points to automatically add to the grid, optional
603}
605# Make a dictionary to specify a general income process consumer type
606GenIncProcessConsumerType_solving_default = {
607 # BASIC HARK PARAMETERS REQUIRED TO SOLVE THE MODEL
608 "cycles": 1, # Finite, non-cyclic model
609 "T_cycle": 1, # Number of periods in the cycle for this agent type
610 "pseudo_terminal": False, # Terminal period really does exist
611 "constructors": GenIncProcessConsumerType_constructors_default, # See dictionary above
612 # PRIMITIVE RAW PARAMETERS REQUIRED TO SOLVE THE MODEL
613 "CRRA": 2.0, # Coefficient of relative risk aversion
614 "Rfree": [1.03], # Interest factor on retained assets
615 "DiscFac": 0.96, # Intertemporal discount factor
616 "LivPrb": [0.98], # Survival probability after each period
617 "BoroCnstArt": 0.0, # Artificial borrowing constraint
618 "vFuncBool": False, # Whether to calculate the value function during solution
619 "CubicBool": False, # Whether to use cubic spline interpolation when True
620 # (Uses linear spline interpolation for cFunc when False)
621}
622GenIncProcessConsumerType_simulation_default = {
623 # PARAMETERS REQUIRED TO SIMULATE THE MODEL
624 "AgentCount": 10000, # Number of agents of this type
625 "T_age": None, # Age after which simulated agents are automatically killed
626 "PermGroFacAgg": 1.0, # Aggregate permanent income growth factor
627 # (The portion of PermGroFac attributable to aggregate productivity growth)
628 "NewbornTransShk": False, # Whether Newborns have transitory shock
629 # ADDITIONAL OPTIONAL PARAMETERS
630 "PerfMITShk": False, # Do Perfect Foresight MIT Shock
631 # (Forces Newborns to follow solution path of the agent they replaced if True)
632 "neutral_measure": False, # Whether to use permanent income neutral measure (see Harmenberg 2021)
633}
634GenIncProcessConsumerType_default = {}
635GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_kNrmInitDstn_default)
636GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_pLvlInitDstn_default)
637GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_IncShkDstn_default)
638GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_aXtraGrid_default)
639GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_pLvlNextFunc_default)
640GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_pLvlGrid_default)
641GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_pLvlPctiles_default)
642GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_solving_default)
643GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_simulation_default)
644init_general_inc = GenIncProcessConsumerType_default
647class GenIncProcessConsumerType(IndShockConsumerType):
648 r"""
649 A consumer type with idiosyncratic shocks to persistent and transitory income.
650 Their problem is defined by a sequence of income distributions, survival prob-
651 abilities, and persistent income growth functions, as well as time invariant
652 values for risk aversion, discount factor, the interest rate, the grid of
653 end-of-period assets, and an artificial borrowing constraint.
655 .. math::
656 \begin{eqnarray*}
657 V_t(M_t,P_t) &=& \max_{C_t} U(C_t) + \beta (1-\mathsf{D}_{t+1}) \mathbb{E} [V_{t+1}(M_{t+1}, P_{t+1}) ], \\
658 A_t &=& M_t - C_t, \\
659 A_t/P_t &\geq& \underline{a}, \\
660 M_{t+1} &=& R A_t + \theta_{t+1}, \\
661 P_{t+1} &=& G_{t+1}(P_t)\psi_{t+1}, \\
662 (\psi_{t+1},\theta_{t+1}) &\sim& F_{t+1}, \\
663 \mathbb{E} [F_{t+1}] &=& 1, \\
664 U(C) &=& \frac{C^{1-\rho}}{1-\rho}. \\
665 \end{eqnarray*}
668 Constructors
669 ------------
670 IncShkDstn: Constructor, :math:`\psi`, :math:`\theta`
671 The agent's income shock distributions.
673 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.construct_lognormal_income_process_unemployment`
674 aXtraGrid: Constructor
675 The agent's asset grid.
677 Its default constructor is :func:`HARK.utilities.make_assets_grid`
678 pLvlNextFunc: Constructor
679 An arbitrary function used to evolve the GenIncShockConsumerType's permanent income
681 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_trivial_pLvlNextFunc`
682 pLvlGrid: Constructor
683 The agent's pLvl grid
685 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_pLvlGrid_by_simulation`
686 pLvlPctiles: Constructor
687 The agents income level percentile grid
689 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_basic_pLvlPctiles`
691 Solving Parameters
692 ------------------
693 cycles: int
694 0 specifies an infinite horizon model, 1 specifies a finite model.
695 T_cycle: int
696 Number of periods in the cycle for this agent type.
697 CRRA: float, :math:`\rho`
698 Coefficient of Relative Risk Aversion.
699 Rfree: float or list[float], time varying, :math:`\mathsf{R}`
700 Risk Free interest rate. Pass a list of floats to make Rfree time varying.
701 DiscFac: float, :math:`\beta`
702 Intertemporal discount factor.
703 LivPrb: list[float], time varying, :math:`1-\mathsf{D}`
704 Survival probability after each period.
705 BoroCnstArt: float, :math:`\underline{a}`
706 The minimum Asset/Perminant Income ratio, None to ignore.
707 vFuncBool: bool
708 Whether to calculate the value function during solution.
709 CubicBool: bool
710 Whether to use cubic spline interpoliation.
712 Simulation Parameters
713 ---------------------
714 AgentCount: int
715 Number of agents of this kind that are created during simulations.
716 T_age: int
717 Age after which to automatically kill agents, None to ignore.
718 T_sim: int, required for simulation
719 Number of periods to simulate.
720 track_vars: list[strings]
721 List of variables that should be tracked when running the simulation.
722 For this agent, the options are 'PermShk', 'TranShk', 'aLvl', 'cLvl', 'mLvl', 'pLvl', and 'who_dies'.
724 PermShk is the agent's permanent income shock
726 TranShk is the agent's transitory income shock
728 aLvl is the nominal asset level
730 cLvl is the nominal consumption level
732 mLvl is the nominal market resources
734 pLvl is the permanent income level
736 who_dies is the array of which agents died
737 aNrmInitMean: float
738 Mean of Log initial Normalized Assets.
739 aNrmInitStd: float
740 Std of Log initial Normalized Assets.
741 pLvlInitMean: float
742 Mean of Log initial permanent income.
743 pLvlInitStd: float
744 Std of Log initial permanent income.
745 PermGroFacAgg: float
746 Aggregate permanent income growth factor (The portion of PermGroFac attributable to aggregate productivity growth).
747 PerfMITShk: boolean
748 Do Perfect Foresight MIT Shock (Forces Newborns to follow solution path of the agent they replaced if True).
749 NewbornTransShk: boolean
750 Whether Newborns have transitory shock.
752 Attributes
753 ----------
754 solution: list[Consumer solution object]
755 Created by the :func:`.solve` method. Finite horizon models create a list with T_cycle+1 elements, for each period in the solution.
756 Infinite horizon solutions return a list with T_cycle elements for each period in the cycle.
758 Unlike other models with this solution type, this model's variables are NOT normalized.
759 The solution functions also depend on the permanent income level. For example, :math:`C=\text{cFunc}(M,P)`.
760 hNrm has been replaced by hLvl which is a function of permanent income.
761 MPC max has not yet been implemented for this class. It will be a function of permanent income.
763 Visit :class:`HARK.ConsumptionSaving.ConsIndShockModel.ConsumerSolution` for more information about the solution.
765 history: Dict[Array]
766 Created by running the :func:`.simulate()` method.
767 Contains the variables in track_vars. Each item in the dictionary is an array with the shape (T_sim,AgentCount).
768 Visit :class:`HARK.core.AgentType.simulate` for more information.
769 """
771 IncShkDstn_default = GenIncProcessConsumerType_IncShkDstn_default
772 aXtraGrid_default = GenIncProcessConsumerType_aXtraGrid_default
773 pLvlNextFunc_default = GenIncProcessConsumerType_pLvlNextFunc_default
774 pLvlGrid_default = GenIncProcessConsumerType_pLvlGrid_default
775 pLvlPctiles_default = GenIncProcessConsumerType_pLvlPctiles_default
776 solving_default = GenIncProcessConsumerType_solving_default
777 simulation_default = GenIncProcessConsumerType_simulation_default
779 state_vars = ["kLvl", "pLvl", "mLvl", "aLvl", "aNrm"]
780 time_vary_ = IndShockConsumerType.time_vary_ + ["pLvlNextFunc", "pLvlGrid"]
781 default_ = {
782 "params": GenIncProcessConsumerType_default,
783 "solver": solve_one_period_ConsGenIncProcess,
784 "model": "ConsGenIncProcess.yaml",
785 }
787 def pre_solve(self):
788 self.construct("solution_terminal")
790 def update_income_process(self):
791 self.update(
792 "IncShkDstn",
793 "PermShkDstn",
794 "TranShkDstn",
795 "pLvlPctiles",
796 "pLvlNextFunc",
797 "pLvlGrid",
798 )
800 def update_pLvlNextFunc(self):
801 """
802 Update the function that maps this period's permanent income level to next
803 period's expected permanent income level.
805 Parameters
806 ----------
807 None
809 Returns
810 -------
811 None
812 """
813 self.construct("pLvlNextFunc")
815 def install_retirement_func(self):
816 """
817 Installs a special pLvlNextFunc representing retirement in the correct
818 element of self.pLvlNextFunc. Draws on the attributes T_retire and
819 pLvlNextFuncRet. If T_retire is zero or pLvlNextFuncRet does not
820 exist, this method does nothing. Should only be called from within the
821 method update_pLvlNextFunc, which ensures that time is flowing forward.
823 Parameters
824 ----------
825 None
827 Returns
828 -------
829 None
830 """
831 if (not hasattr(self, "pLvlNextFuncRet")) or self.T_retire == 0:
832 return
833 t = self.T_retire
834 self.pLvlNextFunc[t] = self.pLvlNextFuncRet
836 def update_pLvlGrid(self):
837 """
838 Update the grid of persistent income levels.
840 Parameters
841 ----------
842 None
844 Returns
845 -------
846 None
847 """
848 self.construct("pLvlPctiles", "pLvlGrid")
849 self.add_to_time_vary("pLvlGrid")
851 def sim_birth(self, which_agents):
852 """
853 Makes new consumers for the given indices. Initialized variables include aNrm and pLvl, as
854 well as time variables t_age and t_cycle. Normalized assets and persistent income levels
855 are drawn from lognormal distributions given by aNrmInitMean and aNrmInitStd (etc).
857 Parameters
858 ----------
859 which_agents : np.array(Bool)
860 Boolean array of size self.AgentCount indicating which agents should be "born".
862 Returns
863 -------
864 None
865 """
866 super().sim_birth(which_agents)
867 self.state_now["aLvl"][which_agents] = (
868 self.state_now["aNrm"][which_agents] * self.state_now["pLvl"][which_agents]
869 )
871 def transition(self):
872 """
873 Calculates updated values of normalized market resources
874 and persistent income level for each
875 agent. Uses pLvlNow, aLvlNow, PermShkNow, TranShkNow.
877 Parameters
878 ----------
879 None
881 Returns
882 -------
883 kLvlNow
884 pLvlNow
885 mLvlNow
886 """
887 kLvlNow = self.state_prev["aLvl"]
888 pLvlNow = np.zeros_like(kLvlNow)
889 RfreeNow = self.get_Rfree()
891 # Calculate new states: normalized market resources and persistent income level
892 for t in range(self.T_cycle):
893 these = t == self.t_cycle
894 pLvlNow[these] = (
895 self.pLvlNextFunc[t - 1](self.state_prev["pLvl"][these])
896 * self.shocks["PermShk"][these]
897 )
899 # state value
900 bLvlNow = RfreeNow * kLvlNow # Bank balances before labor income
902 # Market resources after income - state value
903 mLvlNow = bLvlNow + self.shocks["TranShk"] * pLvlNow
905 return (kLvlNow, pLvlNow, mLvlNow)
907 def get_controls(self):
908 """
909 Calculates consumption for each consumer of this type using the consumption functions.
911 Parameters
912 ----------
913 None
915 Returns
916 -------
917 None
918 """
919 cLvlNow = np.zeros(self.AgentCount) + np.nan
920 MPCnow = np.zeros(self.AgentCount) + np.nan
922 for t in range(self.T_cycle):
923 these = t == self.t_cycle
924 cLvlNow[these] = self.solution[t].cFunc(
925 self.state_now["mLvl"][these], self.state_now["pLvl"][these]
926 )
927 MPCnow[these] = self.solution[t].cFunc.derivativeX(
928 self.state_now["mLvl"][these], self.state_now["pLvl"][these]
929 )
930 self.controls["cLvl"] = cLvlNow
931 self.MPCnow = MPCnow
933 def get_poststates(self):
934 """
935 Calculates end-of-period assets for each consumer of this type.
936 Identical to version in IndShockConsumerType but uses Lvl rather than Nrm variables.
938 Parameters
939 ----------
940 None
942 Returns
943 -------
944 None
945 """
946 self.state_now["aLvl"] = self.state_now["mLvl"] - self.controls["cLvl"]
947 # moves now to prev
948 AgentType.get_poststates(self)
951###############################################################################
953# Make a dictionary for the "explicit permanent income" consumer type; see parent dictionary above.
954IndShockExplicitPermIncConsumerType_constructors_default = (
955 GenIncProcessConsumerType_constructors_default.copy()
956)
957IndShockExplicitPermIncConsumerType_constructors_default["pLvlNextFunc"] = (
958 make_explicit_perminc_pLvlNextFunc
959)
960IndShockExplicitPermIncConsumerType_IncShkDstn_default = (
961 GenIncProcessConsumerType_IncShkDstn_default.copy()
962)
963IndShockExplicitPermIncConsumerType_kNrmInitDstn_default = (
964 GenIncProcessConsumerType_kNrmInitDstn_default.copy()
965)
966IndShockExplicitPermIncConsumerType_pLvlInitDstn_default = (
967 GenIncProcessConsumerType_pLvlInitDstn_default.copy()
968)
969IndShockExplicitPermIncConsumerType_aXtraGrid_default = (
970 GenIncProcessConsumerType_aXtraGrid_default.copy()
971)
972IndShockExplicitPermIncConsumerType_pLvlNextFunc_default = (
973 GenIncProcessConsumerType_pLvlNextFunc_default.copy()
974)
975IndShockExplicitPermIncConsumerType_pLvlGrid_default = (
976 GenIncProcessConsumerType_pLvlGrid_default.copy()
977)
978IndShockExplicitPermIncConsumerType_pLvlPctiles_default = (
979 GenIncProcessConsumerType_pLvlPctiles_default.copy()
980)
981IndShockExplicitPermIncConsumerType_solving_default = (
982 GenIncProcessConsumerType_solving_default.copy()
983)
984IndShockExplicitPermIncConsumerType_solving_default["constructors"] = (
985 IndShockExplicitPermIncConsumerType_constructors_default
986)
987IndShockExplicitPermIncConsumerType_pLvlNextFunc_default["PermGroFac"] = [1.0]
988IndShockExplicitPermIncConsumerType_simulation_default = (
989 GenIncProcessConsumerType_simulation_default.copy()
990)
992IndShockExplicitPermIncConsumerType_default = {}
993IndShockExplicitPermIncConsumerType_default.update(
994 IndShockExplicitPermIncConsumerType_IncShkDstn_default
995)
996IndShockExplicitPermIncConsumerType_default.update(
997 IndShockExplicitPermIncConsumerType_kNrmInitDstn_default
998)
999IndShockExplicitPermIncConsumerType_default.update(
1000 IndShockExplicitPermIncConsumerType_pLvlInitDstn_default
1001)
1002IndShockExplicitPermIncConsumerType_default.update(
1003 IndShockExplicitPermIncConsumerType_aXtraGrid_default
1004)
1005IndShockExplicitPermIncConsumerType_default.update(
1006 IndShockExplicitPermIncConsumerType_pLvlNextFunc_default
1007)
1008IndShockExplicitPermIncConsumerType_default.update(
1009 IndShockExplicitPermIncConsumerType_pLvlGrid_default
1010)
1011IndShockExplicitPermIncConsumerType_default.update(
1012 IndShockExplicitPermIncConsumerType_pLvlPctiles_default
1013)
1014IndShockExplicitPermIncConsumerType_default.update(
1015 IndShockExplicitPermIncConsumerType_solving_default
1016)
1017IndShockExplicitPermIncConsumerType_default.update(
1018 IndShockExplicitPermIncConsumerType_simulation_default
1019)
1020init_explicit_perm_inc = IndShockExplicitPermIncConsumerType_default
1022# NB: Permanent income growth was not in the default dictionary for GenIncProcessConsumerType
1023# because its pLvlNextFunc constructor was *trivial*: no permanent income dynamics at all!
1024# For the "explicit permanent income" model, this parameter is added back into the dictionary.
1025# However, note that if this model is used in an *infinite horizon* setting, it will work
1026# best if the product of PermGroFac (across all periods) is 1. If it is far from 1, then the
1027# pLvlGrid that is constructed by the default method might not be appropriate.
1030class IndShockExplicitPermIncConsumerType(GenIncProcessConsumerType):
1031 r"""
1032 A consumer type based on GenIncProcessModel, where the general function
1033 describing the path of permanent income multiplies the current permanent
1034 income by the PermGroFac (:math:`\Gamma`). It's behavior is the same as
1035 :class:`HARK.ConsumptionSaving.ConsIndShockModel.IndShockConsumerType`, except
1036 that the variables aren't normalized. This makes the result less
1037 accurate. This Model uses a lognormal random walk income process.
1038 If you would like to use a different income process, use
1039 :class:`HARK.ConsumptionSaving.ConsGenIncProcessModel.GenIncProcessConsumerType`
1041 .. math::
1042 \begin{eqnarray*}
1043 V_t(M_t,P_t) &=& \max_{C_t} U(C_t) + \beta (1-\mathsf{D}_{t+1}) \mathbb{E} [V_{t+1}(M_{t+1}, P_{t+1}) ], \\
1044 A_t &=& M_t - C_t, \\
1045 A_t/P_t &\geq& \underline{a}, \\
1046 M_{t+1} &=& R A_t + \theta_{t+1}, \\
1047 P_{t+1} &=& G_{t+1}(P_t)\psi_{t+1}, \\
1048 (\psi_{t+1},\theta_{t+1}) &\sim& F_{t+1}, \\
1049 \mathbb{E} [F_{t+1}] &=& 1, \\
1050 U(C) &=& \frac{C^{1-\rho}}{1-\rho}. \\
1051 G_{t+1} (x) &=&\Gamma_{t+1} x
1052 \end{eqnarray*}
1055 Constructors
1056 ------------
1057 IncShkDstn: Constructor, :math:`\psi`, :math:`\theta`
1058 The agent's income shock distributions.
1060 It's default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.construct_lognormal_income_process_unemployment`
1061 aXtraGrid: Constructor
1062 The agent's asset grid.
1064 It's default constructor is :func:`HARK.utilities.make_assets_grid`
1065 pLvlNextFunc: Constructor, (:math:`\Gamma`)
1066 An arbitrary function used to evolve the GenIncShockConsumerType's permanent income
1068 It's default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_explicit_perminc_pLvlNextFunc`
1069 pLvlGrid: Constructor
1070 The agent's pLvl grid
1072 It's default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_pLvlGrid_by_simulation`
1073 pLvlPctiles: Constructor
1074 The agents income level percentile grid
1076 It's default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_basic_pLvlPctiles`
1078 Solving Parameters
1079 ------------------
1080 cycles: int
1081 0 specifies an infinite horizon model, 1 specifies a finite model.
1082 T_cycle: int
1083 Number of periods in the cycle for this agent type.
1084 CRRA: float, :math:`\rho`
1085 Coefficient of Relative Risk Aversion.
1086 Rfree: float or list[float], time varying, :math:`\mathsf{R}`
1087 Risk Free interest rate. Pass a list of floats to make Rfree time varying.
1088 DiscFac: float, :math:`\beta`
1089 Intertemporal discount factor.
1090 LivPrb: list[float], time varying, :math:`1-\mathsf{D}`
1091 Survival probability after each period.
1092 PermGroFac: list[float], time varying, :math:`\Gamma`
1093 Permanent income growth factor.
1094 BoroCnstArt: float, :math:`\underline{a}`
1095 The minimum Asset/Perminant Income ratio, None to ignore.
1096 vFuncBool: bool
1097 Whether to calculate the value function during solution.
1098 CubicBool: bool
1099 Whether to use cubic spline interpoliation.
1101 Simulation Parameters
1102 ---------------------
1103 AgentCount: int
1104 Number of agents of this kind that are created during simulations.
1105 T_age: int
1106 Age after which to automatically kill agents, None to ignore.
1107 T_sim: int, required for simulation
1108 Number of periods to simulate.
1109 track_vars: list[strings]
1110 List of variables that should be tracked when running the simulation.
1111 For this agent, the options are 'PermShk', 'TranShk', 'aLvl', 'cLvl', 'mLvl', 'pLvl', and 'who_dies'.
1113 PermShk is the agent's permanent income shock
1115 TranShk is the agent's transitory income shock
1117 aLvl is the nominal asset level
1119 cLvl is the nominal consumption level
1121 mLvl is the nominal market resources
1123 pLvl is the permanent income level
1125 who_dies is the array of which agents died
1126 aNrmInitMean: float
1127 Mean of Log initial Normalized Assets.
1128 aNrmInitStd: float
1129 Std of Log initial Normalized Assets.
1130 pLvlInitMean: float
1131 Mean of Log initial permanent income.
1132 pLvlInitStd: float
1133 Std of Log initial permanent income.
1134 PermGroFacAgg: float
1135 Aggregate permanent income growth factor (The portion of PermGroFac attributable to aggregate productivity growth).
1136 PerfMITShk: boolean
1137 Do Perfect Foresight MIT Shock (Forces Newborns to follow solution path of the agent they replaced if True).
1138 NewbornTransShk: boolean
1139 Whether Newborns have transitory shock.
1141 Attributes
1142 ----------
1143 solution: list[Consumer solution object]
1144 Created by the :func:`.solve` method. Finite horizon models create a list with T_cycle+1 elements, for each period in the solution.
1145 Infinite horizon solutions return a list with T_cycle elements for each period in the cycle.
1147 Unlike other models with this solution type, this model's variables are NOT normalized.
1148 The solution functions also depend on the permanent income level. For example, :math:`C=\text{cFunc}(M,P)`.
1149 hNrm has been replaced by hLvl which is a function of permanent income.
1150 MPC max has not yet been implemented for this class. It will be a function of permanent income.
1152 Visit :class:`HARK.ConsumptionSaving.ConsIndShockModel.ConsumerSolution` for more information about the solution.
1154 history: Dict[Array]
1155 Created by running the :func:`.simulate()` method.
1156 Contains the variables in track_vars. Each item in the dictionary is an array with the shape (T_sim,AgentCount).
1157 Visit :class:`HARK.core.AgentType.simulate` for more information.
1158 """
1160 IncShkDstn_default = GenIncProcessConsumerType_IncShkDstn_default
1161 aXtraGrid_default = GenIncProcessConsumerType_aXtraGrid_default
1162 pLvlNextFunc_default = GenIncProcessConsumerType_pLvlNextFunc_default
1163 pLvlGrid_default = GenIncProcessConsumerType_pLvlGrid_default
1164 pLvlPctiles_default = GenIncProcessConsumerType_pLvlPctiles_default
1165 solving_default = GenIncProcessConsumerType_solving_default
1166 simulation_default = GenIncProcessConsumerType_simulation_default
1168 default_ = {
1169 "params": init_explicit_perm_inc,
1170 "solver": solve_one_period_ConsGenIncProcess,
1171 }
1174###############################################################################
1176# Make a dictionary for the "persistent idiosyncratic shocks" consumer type; see parent dictionary above.
1178PersistentShockConsumerType_constructors_default = (
1179 GenIncProcessConsumerType_constructors_default.copy()
1180)
1181PersistentShockConsumerType_constructors_default["pLvlNextFunc"] = (
1182 make_AR1_style_pLvlNextFunc
1183)
1184PersistentShockConsumerType_kNrmInitDstn_default = (
1185 IndShockExplicitPermIncConsumerType_kNrmInitDstn_default.copy()
1186)
1187PersistentShockConsumerType_pLvlInitDstn_default = (
1188 IndShockExplicitPermIncConsumerType_pLvlInitDstn_default.copy()
1189)
1190PersistentShockConsumerType_IncShkDstn_default = (
1191 IndShockExplicitPermIncConsumerType_IncShkDstn_default.copy()
1192)
1193PersistentShockConsumerType_aXtraGrid_default = (
1194 IndShockExplicitPermIncConsumerType_aXtraGrid_default.copy()
1195)
1196PersistentShockConsumerType_pLvlNextFunc_default = (
1197 IndShockExplicitPermIncConsumerType_pLvlNextFunc_default.copy()
1198)
1199PersistentShockConsumerType_pLvlGrid_default = (
1200 IndShockExplicitPermIncConsumerType_pLvlGrid_default.copy()
1201)
1202PersistentShockConsumerType_pLvlPctiles_default = (
1203 IndShockExplicitPermIncConsumerType_pLvlPctiles_default.copy()
1204)
1205PersistentShockConsumerType_solving_default = (
1206 IndShockExplicitPermIncConsumerType_solving_default.copy()
1207)
1208PersistentShockConsumerType_solving_default["constructors"] = (
1209 PersistentShockConsumerType_constructors_default
1210)
1211PersistentShockConsumerType_pLvlNextFunc_default["PrstIncCorr"] = 0.98
1212PersistentShockConsumerType_simulation_default = (
1213 IndShockExplicitPermIncConsumerType_simulation_default.copy()
1214)
1216PersistentShockConsumerType_default = {}
1217PersistentShockConsumerType_default.update(
1218 PersistentShockConsumerType_IncShkDstn_default
1219)
1220PersistentShockConsumerType_default.update(
1221 PersistentShockConsumerType_kNrmInitDstn_default
1222)
1223PersistentShockConsumerType_default.update(
1224 PersistentShockConsumerType_pLvlInitDstn_default
1225)
1226PersistentShockConsumerType_default.update(
1227 PersistentShockConsumerType_aXtraGrid_default
1228)
1229PersistentShockConsumerType_default.update(
1230 PersistentShockConsumerType_pLvlNextFunc_default
1231)
1232PersistentShockConsumerType_default.update(PersistentShockConsumerType_pLvlGrid_default)
1233PersistentShockConsumerType_default.update(
1234 PersistentShockConsumerType_pLvlPctiles_default
1235)
1236PersistentShockConsumerType_default.update(PersistentShockConsumerType_solving_default)
1237PersistentShockConsumerType_default.update(
1238 PersistentShockConsumerType_simulation_default
1239)
1240init_persistent_shocks = PersistentShockConsumerType_default
1243class PersistentShockConsumerType(GenIncProcessConsumerType):
1244 r"""
1245 A consumer type based on GenIncProcessModel, where the log permanent income follows an AR1 process.
1246 If you would like to use a different income process, use
1247 :class:`HARK.ConsumptionSaving.ConsGenIncProcessModel.GenIncProcessConsumerType`
1249 .. math::
1250 \begin{eqnarray*}
1251 V_t(M_t,P_t) &=& \max_{C_t} U(C_t) + \beta (1-\mathsf{D}_{t+1}) \mathbb{E} [V_{t+1}(M_{t+1}, P_{t+1}) ], \\
1252 A_t &=& M_t - C_t, \\
1253 A_t/P_t &\geq& \underline{a}, \\
1254 M_{t+1} &=& R A_t + \theta_{t+1}, \\
1255 p_{t+1} &=& G_{t+1}(P_t)\psi_{t+1}, \\
1256 (\psi_{t+1},\theta_{t+1}) &\sim& F_{t+1}, \\
1257 \mathbb{E} [F_{t+1}] &=& 1, \\
1258 U(C) &=& \frac{C^{1-\rho}}{1-\rho}, \\
1259 log(G_{t+1} (x)) &=&\varphi log(x) + (1-\varphi) log(\overline{P}_{t})+log(\Gamma_{t+1}) + log(\psi_{t+1}), \\
1260 \overline{P}_{t+1} &=& \overline{P}_{t} \Gamma_{t+1} \\
1261 \end{eqnarray*}
1264 Constructors
1265 ------------
1266 IncShkDstn: Constructor, :math:`\psi`, :math:`\theta`
1267 The agent's income shock distributions.
1269 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.construct_lognormal_income_process_unemployment`
1270 aXtraGrid: Constructor
1271 The agent's asset grid.
1273 Its default constructor is :func:`HARK.utilities.make_assets_grid`
1274 pLvlNextFunc: Constructor, (:math:`\Gamma`, :math:`\varphi`)
1275 An arbitrary function used to evolve the GenIncShockConsumerType's permanent income
1277 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_AR1_style_pLvlNextFunc`
1278 pLvlGrid: Constructor
1279 The agent's pLvl grid
1281 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_pLvlGrid_by_simulation`
1282 pLvlPctiles: Constructor
1283 The agents income level percentile grid
1285 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_basic_pLvlPctiles`
1287 Solving Parameters
1288 ------------------
1289 cycles: int
1290 0 specifies an infinite horizon model, 1 specifies a finite model.
1291 T_cycle: int
1292 Number of periods in the cycle for this agent type.
1293 CRRA: float, :math:`\rho`
1294 Coefficient of Relative Risk Aversion.
1295 Rfree: float or list[float], time varying, :math:`\mathsf{R}`
1296 Risk Free interest rate. Pass a list of floats to make Rfree time varying.
1297 DiscFac: float, :math:`\beta`
1298 Intertemporal discount factor.
1299 LivPrb: list[float], time varying, :math:`1-\mathsf{D}`
1300 Survival probability after each period.
1301 PermGroFac: list[float], time varying, :math:`\Gamma`
1302 Permanent income growth factor.
1303 BoroCnstArt: float, :math:`\underline{a}`
1304 The minimum Asset/Perminant Income ratio, None to ignore.
1305 vFuncBool: bool
1306 Whether to calculate the value function during solution.
1307 CubicBool: bool
1308 Whether to use cubic spline interpoliation.
1310 Simulation Parameters
1311 ---------------------
1312 AgentCount: int
1313 Number of agents of this kind that are created during simulations.
1314 T_age: int
1315 Age after which to automatically kill agents, None to ignore.
1316 T_sim: int, required for simulation
1317 Number of periods to simulate.
1318 track_vars: list[strings]
1319 List of variables that should be tracked when running the simulation.
1320 For this agent, the options are 'PermShk', 'TranShk', 'aLvl', 'cLvl', 'mLvl', 'pLvl', and 'who_dies'.
1322 PermShk is the agent's permanent income shock
1324 TranShk is the agent's transitory income shock
1326 aLvl is the nominal asset level
1328 cLvl is the nominal consumption level
1330 mLvl is the nominal market resources
1332 pLvl is the permanent income level
1334 who_dies is the array of which agents died
1335 aNrmInitMean: float
1336 Mean of Log initial Normalized Assets.
1337 aNrmInitStd: float
1338 Std of Log initial Normalized Assets.
1339 pLvlInitMean: float
1340 Mean of Log initial permanent income.
1341 pLvlInitStd: float
1342 Std of Log initial permanent income.
1343 PermGroFacAgg: float
1344 Aggregate permanent income growth factor (The portion of PermGroFac attributable to aggregate productivity growth).
1345 PerfMITShk: boolean
1346 Do Perfect Foresight MIT Shock (Forces Newborns to follow solution path of the agent they replaced if True).
1347 NewbornTransShk: boolean
1348 Whether Newborns have transitory shock.
1350 Attributes
1351 ----------
1352 solution: list[Consumer solution object]
1353 Created by the :func:`.solve` method. Finite horizon models create a list with T_cycle+1 elements, for each period in the solution.
1354 Infinite horizon solutions return a list with T_cycle elements for each period in the cycle.
1356 Unlike other models with this solution type, this model's variables are NOT normalized.
1357 The solution functions also depend on the permanent income level. For example, :math:`C=\text{cFunc}(M,P)`.
1358 hNrm has been replaced by hLvl which is a function of permanent income.
1359 MPC max has not yet been implemented for this class. It will be a function of permanent income.
1361 Visit :class:`HARK.ConsumptionSaving.ConsIndShockModel.ConsumerSolution` for more information about the solution.
1363 history: Dict[Array]
1364 Created by running the :func:`.simulate()` method.
1365 Contains the variables in track_vars. Each item in the dictionary is an array with the shape (T_sim,AgentCount).
1366 Visit :class:`HARK.core.AgentType.simulate` for more information.
1367 """
1369 IncShkDstn_default = PersistentShockConsumerType_IncShkDstn_default
1370 aXtraGrid_default = PersistentShockConsumerType_aXtraGrid_default
1371 pLvlNextFunc_default = PersistentShockConsumerType_pLvlNextFunc_default
1372 pLvlGrid_default = PersistentShockConsumerType_pLvlGrid_default
1373 pLvlPctiles_default = PersistentShockConsumerType_pLvlPctiles_default
1374 solving_default = PersistentShockConsumerType_solving_default
1375 simulation_default = PersistentShockConsumerType_simulation_default
1377 default_ = {
1378 "params": init_persistent_shocks,
1379 "solver": solve_one_period_ConsGenIncProcess,
1380 }