Coverage for HARK / ConsumptionSaving / ConsGenIncProcessModel.py: 97%
293 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-25 05:22 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-25 05:22 +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 approximation to the income shocks between the period being
138 solved and the one immediately following (in solution_next).
139 LivPrb : float
140 Survival probability; likelihood of being alive at the beginning of
141 the succeeding period.
142 DiscFac : float
143 Intertemporal discount factor for future utility.
144 CRRA : float
145 Coefficient of relative risk aversion.
146 Rfree : float
147 Risk free interest factor on end-of-period assets.
148 pLvlNextFunc : float
149 Expected persistent income next period as a function of current pLvl.
150 BoroCnstArt: float or None
151 Borrowing constraint for the minimum allowable assets to end the
152 period with.
153 aXtraGrid: np.array
154 Array of "extra" end-of-period (normalized) asset values-- assets
155 above the absolute minimum acceptable level.
156 pLvlGrid: np.array
157 Array of persistent income levels at which to solve the problem.
158 vFuncBool: boolean
159 An indicator for whether the value function should be computed and
160 included in the reported solution.
161 CubicBool: boolean
162 An indicator for whether the solver should use cubic or linear interpolation.
164 Returns
165 -------
166 solution_now : ConsumerSolution
167 Solution to this period's consumption-saving problem.
168 """
169 # Define the utility function for this period
170 uFunc = UtilityFuncCRRA(CRRA)
171 DiscFacEff = DiscFac * LivPrb # "effective" discount factor
173 # Unpack next period's income shock distribution
174 ShkPrbsNext = IncShkDstn.pmv
175 PermShkValsNext = IncShkDstn.atoms[0]
176 TranShkValsNext = IncShkDstn.atoms[1]
177 PermShkMinNext = np.min(PermShkValsNext)
178 TranShkMinNext = np.min(TranShkValsNext)
180 # Calculate the probability that we get the worst possible income draw
181 IncNext = PermShkValsNext * TranShkValsNext
182 WorstIncNext = PermShkMinNext * TranShkMinNext
183 WorstIncPrb = np.sum(ShkPrbsNext[IncNext == WorstIncNext])
184 # WorstIncPrb is the "Weierstrass p" concept: the odds we get the WORST thing
186 # Unpack next period's (marginal) value function
187 vFuncNext = solution_next.vFunc # This is None when vFuncBool is False
188 vPfuncNext = solution_next.vPfunc
189 vPPfuncNext = solution_next.vPPfunc # This is None when CubicBool is False
191 # Update the bounding MPCs and PDV of human wealth:
192 PatFac = ((Rfree * DiscFacEff) ** (1.0 / CRRA)) / Rfree
193 try:
194 MPCminNow = 1.0 / (1.0 + PatFac / solution_next.MPCmin)
195 except:
196 MPCminNow = 0.0
197 mLvlMinNext = solution_next.mLvlMin
199 # TODO: Deal with this unused code for the upper bound of MPC (should be a function now)
200 # Ex_IncNext = np.dot(ShkPrbsNext, TranShkValsNext * PermShkValsNext)
201 # hNrmNow = 0.0
202 # temp_fac = (WorstIncPrb ** (1.0 / CRRA)) * PatFac
203 # MPCmaxNow = 1.0 / (1.0 + temp_fac / solution_next.MPCmax)
205 # Define some functions for calculating future expectations
206 def calc_pLvl_next(S, p):
207 return pLvlNextFunc(p) * S["PermShk"]
209 def calc_mLvl_next(S, a, p_next):
210 return Rfree * a + p_next * S["TranShk"]
212 def calc_hLvl(S, p):
213 pLvl_next = calc_pLvl_next(S, p)
214 hLvl = S["TranShk"] * pLvl_next + solution_next.hLvl(pLvl_next)
215 return hLvl
217 def calc_v_next(S, a, p):
218 pLvl_next = calc_pLvl_next(S, p)
219 mLvl_next = calc_mLvl_next(S, a, pLvl_next)
220 v_next = vFuncNext(mLvl_next, pLvl_next)
221 return v_next
223 def calc_vP_next(S, a, p):
224 pLvl_next = calc_pLvl_next(S, p)
225 mLvl_next = calc_mLvl_next(S, a, pLvl_next)
226 vP_next = vPfuncNext(mLvl_next, pLvl_next)
227 return vP_next
229 def calc_vPP_next(S, a, p):
230 pLvl_next = calc_pLvl_next(S, p)
231 mLvl_next = calc_mLvl_next(S, a, pLvl_next)
232 vPP_next = vPPfuncNext(mLvl_next, pLvl_next)
233 return vPP_next
235 # Construct human wealth level as a function of productivity pLvl
236 hLvlGrid = 1.0 / Rfree * expected(calc_hLvl, IncShkDstn, args=(pLvlGrid))
237 hLvlNow = LinearInterp(np.insert(pLvlGrid, 0, 0.0), np.insert(hLvlGrid, 0, 0.0))
239 # Make temporary grids of income shocks and next period income values
240 ShkCount = TranShkValsNext.size
241 pLvlCount = pLvlGrid.size
242 PermShkVals_temp = np.tile(
243 np.reshape(PermShkValsNext, (1, ShkCount)), (pLvlCount, 1)
244 )
245 TranShkVals_temp = np.tile(
246 np.reshape(TranShkValsNext, (1, ShkCount)), (pLvlCount, 1)
247 )
248 pLvlNext_temp = (
249 np.tile(
250 np.reshape(pLvlNextFunc(pLvlGrid), (pLvlCount, 1)),
251 (1, ShkCount),
252 )
253 * PermShkVals_temp
254 )
256 # Find the natural borrowing constraint for each persistent income level
257 aLvlMin_candidates = (
258 mLvlMinNext(pLvlNext_temp) - TranShkVals_temp * pLvlNext_temp
259 ) / Rfree
260 aLvlMinNow = np.max(aLvlMin_candidates, axis=1)
261 BoroCnstNat = LinearInterp(
262 np.insert(pLvlGrid, 0, 0.0), np.insert(aLvlMinNow, 0, 0.0)
263 )
265 # Define the minimum allowable mLvl by pLvl as the greater of the natural and artificial borrowing constraints
266 if BoroCnstArt is not None:
267 BoroCnstArt = LinearInterp(np.array([0.0, 1.0]), np.array([0.0, BoroCnstArt]))
268 mLvlMinNow = UpperEnvelope(BoroCnstArt, BoroCnstNat)
269 else:
270 mLvlMinNow = BoroCnstNat
272 # Define the constrained consumption function as "consume all" shifted by mLvlMin
273 cFuncNowCnstBase = BilinearInterp(
274 np.array([[0.0, 0.0], [1.0, 1.0]]),
275 np.array([0.0, 1.0]),
276 np.array([0.0, 1.0]),
277 )
278 cFuncNowCnst = VariableLowerBoundFunc2D(cFuncNowCnstBase, mLvlMinNow)
280 # Define grids of pLvl and aLvl on which to compute future expectations
281 pLvlCount = pLvlGrid.size
282 aNrmCount = aXtraGrid.size
283 pLvlNow = np.tile(pLvlGrid, (aNrmCount, 1)).transpose()
284 aLvlNow = np.tile(aXtraGrid, (pLvlCount, 1)) * pLvlNow + BoroCnstNat(pLvlNow)
285 # shape = (pLvlCount,aNrmCount)
286 if pLvlGrid[0] == 0.0: # aLvl turns out badly if pLvl is 0 at bottom
287 aLvlNow[0, :] = aXtraGrid
289 # Calculate end-of-period marginal value of assets
290 EndOfPrd_vP = (
291 DiscFacEff * Rfree * expected(calc_vP_next, IncShkDstn, args=(aLvlNow, pLvlNow))
292 )
294 # If the value function has been requested, construct the end-of-period vFunc
295 if vFuncBool:
296 # Compute expected value from end-of-period states
297 EndOfPrd_v = expected(calc_v_next, IncShkDstn, args=(aLvlNow, pLvlNow))
298 EndOfPrd_v *= DiscFacEff
300 # Transformed value through inverse utility function to "decurve" it
301 EndOfPrd_vNvrs = uFunc.inv(EndOfPrd_v)
302 EndOfPrd_vNvrsP = EndOfPrd_vP * uFunc.derinv(EndOfPrd_v, order=(0, 1))
304 # Add points at mLvl=zero
305 EndOfPrd_vNvrs = np.concatenate(
306 (np.zeros((pLvlCount, 1)), EndOfPrd_vNvrs), axis=1
307 )
308 EndOfPrd_vNvrsP = np.concatenate(
309 (
310 np.reshape(EndOfPrd_vNvrsP[:, 0], (pLvlCount, 1)),
311 EndOfPrd_vNvrsP,
312 ),
313 axis=1,
314 )
315 # This is a very good approximation, vNvrsPP = 0 at the asset minimum
317 # Make a temporary aLvl grid for interpolating the end-of-period value function
318 aLvl_temp = np.concatenate(
319 (
320 np.reshape(BoroCnstNat(pLvlGrid), (pLvlGrid.size, 1)),
321 aLvlNow,
322 ),
323 axis=1,
324 )
326 # Make an end-of-period value function for each persistent income level in the grid
327 EndOfPrd_vNvrsFunc_list = []
328 for p in range(pLvlCount):
329 EndOfPrd_vNvrsFunc_list.append(
330 CubicInterp(
331 aLvl_temp[p, :] - BoroCnstNat(pLvlGrid[p]),
332 EndOfPrd_vNvrs[p, :],
333 EndOfPrd_vNvrsP[p, :],
334 )
335 )
336 EndOfPrd_vNvrsFuncBase = LinearInterpOnInterp1D(
337 EndOfPrd_vNvrsFunc_list, pLvlGrid
338 )
340 # Re-adjust the combined end-of-period value function to account for the
341 # natural borrowing constraint shifter and "re-curve" it
342 EndOfPrd_vNvrsFunc = VariableLowerBoundFunc2D(
343 EndOfPrd_vNvrsFuncBase, BoroCnstNat
344 )
345 EndOfPrd_vFunc = ValueFuncCRRA(EndOfPrd_vNvrsFunc, CRRA)
347 # Solve the first order condition to get optimal consumption, then find the
348 # endogenous gridpoints
349 cLvlNow = uFunc.derinv(EndOfPrd_vP, order=(1, 0))
350 mLvlNow = cLvlNow + aLvlNow
352 # Limiting consumption is zero as m approaches mNrmMin
353 c_for_interpolation = np.concatenate((np.zeros((pLvlCount, 1)), cLvlNow), axis=-1)
354 m_for_interpolation = np.concatenate(
355 (
356 BoroCnstNat(np.reshape(pLvlGrid, (pLvlCount, 1))),
357 mLvlNow,
358 ),
359 axis=-1,
360 )
362 # Limiting consumption is MPCmin*mLvl as p approaches 0
363 m_temp = np.reshape(m_for_interpolation[0, :], (1, m_for_interpolation.shape[1]))
364 m_for_interpolation = np.concatenate((m_temp, m_for_interpolation), axis=0)
365 c_for_interpolation = np.concatenate(
366 (MPCminNow * m_temp, c_for_interpolation), axis=0
367 )
369 # Make an array of corresponding pLvl values, adding an additional column for
370 # the mLvl points at the lower boundary *and* an extra row for pLvl=0.
371 p_for_interpolation = np.concatenate(
372 (np.reshape(pLvlGrid, (pLvlCount, 1)), pLvlNow), axis=-1
373 )
374 p_for_interpolation = np.concatenate(
375 (np.zeros((1, m_for_interpolation.shape[1])), p_for_interpolation)
376 )
378 # Build the set of cFuncs by pLvl, gathered in a list
379 cFunc_by_pLvl_list = [] # list of consumption functions for each pLvl
380 if CubicBool:
381 # Calculate end-of-period marginal marginal value of assets
382 vPP_fac = DiscFacEff * Rfree * Rfree
383 EndOfPrd_vPP = expected(calc_vPP_next, IncShkDstn, args=(aLvlNow, pLvlNow))
384 EndOfPrd_vPP *= vPP_fac
386 # Calculate the MPC at each gridpoint
387 dcda = EndOfPrd_vPP / uFunc.der(np.array(c_for_interpolation[1:, 1:]), order=2)
388 MPC = dcda / (dcda + 1.0)
389 MPC = np.concatenate((np.reshape(MPC[:, 0], (MPC.shape[0], 1)), MPC), axis=1)
391 # Stick an extra row of MPC values at pLvl=zero
392 MPC = np.concatenate((MPCminNow * np.ones((1, aNrmCount + 1)), MPC), axis=0)
394 # Make cubic consumption function with respect to mLvl for each persistent income level
395 for j in range(p_for_interpolation.shape[0]):
396 pLvl_j = p_for_interpolation[j, 0]
397 m_temp = m_for_interpolation[j, :] - BoroCnstNat(pLvl_j)
399 # Make a cubic consumption function for this pLvl
400 c_temp = c_for_interpolation[j, :]
401 MPC_temp = MPC[j, :]
402 if pLvl_j > 0:
403 cFunc_by_pLvl_list.append(
404 CubicInterp(
405 m_temp,
406 c_temp,
407 MPC_temp,
408 lower_extrap=True,
409 slope_limit=MPCminNow,
410 intercept_limit=MPCminNow * hLvlNow(pLvl_j),
411 )
412 )
413 else: # When pLvl=0, cFunc is linear
414 cFunc_by_pLvl_list.append(
415 LinearInterp(m_temp, c_temp, lower_extrap=True)
416 )
418 # Basic version: use linear interpolation within a pLvl
419 else:
420 # Loop over pLvl values and make an mLvl for each one
421 for j in range(p_for_interpolation.shape[0]):
422 pLvl_j = p_for_interpolation[j, 0]
423 m_temp = m_for_interpolation[j, :] - BoroCnstNat(pLvl_j)
425 # Make a linear consumption function for this pLvl
426 c_temp = c_for_interpolation[j, :]
427 if pLvl_j > 0:
428 cFunc_by_pLvl_list.append(
429 LinearInterp(
430 m_temp,
431 c_temp,
432 lower_extrap=True,
433 slope_limit=MPCminNow,
434 intercept_limit=MPCminNow * hLvlNow(pLvl_j),
435 )
436 )
437 else:
438 cFunc_by_pLvl_list.append(
439 LinearInterp(m_temp, c_temp, lower_extrap=True)
440 )
442 # Combine all linear cFuncs into one function
443 pLvl_list = p_for_interpolation[:, 0]
444 cFuncUncBase = LinearInterpOnInterp1D(cFunc_by_pLvl_list, pLvl_list)
445 cFuncNowUnc = VariableLowerBoundFunc2D(cFuncUncBase, BoroCnstNat)
446 # Re-adjust for lower bound of natural borrowing constraint
448 # Combine the constrained and unconstrained functions into the true consumption function
449 cFuncNow = LowerEnvelope2D(cFuncNowUnc, cFuncNowCnst)
451 # Make the marginal value function
452 vPfuncNow = MargValueFuncCRRA(cFuncNow, CRRA)
454 # If using cubic spline interpolation, construct the marginal marginal value function
455 if CubicBool:
456 vPPfuncNow = MargMargValueFuncCRRA(cFuncNow, CRRA)
457 else:
458 vPPfuncNow = NullFunc()
460 # If the value function has been requested, construct it now
461 if vFuncBool:
462 # Compute expected value and marginal value on a grid of market resources
463 # Tile pLvl across m values
464 pLvl_temp = np.tile(pLvlGrid, (aNrmCount, 1))
465 mLvl_temp = (
466 np.tile(mLvlMinNow(pLvlGrid), (aNrmCount, 1))
467 + np.tile(np.reshape(aXtraGrid, (aNrmCount, 1)), (1, pLvlCount)) * pLvl_temp
468 )
469 cLvl_temp = cFuncNow(mLvl_temp, pLvl_temp)
470 aLvl_temp = mLvl_temp - cLvl_temp
471 v_temp = uFunc(cLvl_temp) + EndOfPrd_vFunc(aLvl_temp, pLvl_temp)
472 vP_temp = uFunc.der(cLvl_temp)
474 # Calculate pseudo-inverse value and its first derivative (wrt mLvl)
475 vNvrs_temp = uFunc.inv(v_temp) # value transformed through inverse utility
476 vNvrsP_temp = vP_temp * uFunc.derinv(v_temp, order=(0, 1))
478 # Add data at the lower bound of m
479 mLvl_temp = np.concatenate(
480 (np.reshape(mLvlMinNow(pLvlGrid), (1, pLvlCount)), mLvl_temp), axis=0
481 )
482 vNvrs_temp = np.concatenate((np.zeros((1, pLvlCount)), vNvrs_temp), axis=0)
483 vNvrsP_temp = np.concatenate(
484 (np.reshape(vNvrsP_temp[0, :], (1, vNvrsP_temp.shape[1])), vNvrsP_temp),
485 axis=0,
486 )
488 # Add data at the lower bound of p
489 MPCminNvrs = MPCminNow ** (-CRRA / (1.0 - CRRA))
490 m_temp = np.reshape(mLvl_temp[:, 0], (aNrmCount + 1, 1))
491 mLvl_temp = np.concatenate((m_temp, mLvl_temp), axis=1)
492 vNvrs_temp = np.concatenate((MPCminNvrs * m_temp, vNvrs_temp), axis=1)
493 vNvrsP_temp = np.concatenate(
494 (MPCminNvrs * np.ones((aNrmCount + 1, 1)), vNvrsP_temp), axis=1
495 )
497 # Construct the pseudo-inverse value function
498 vNvrsFunc_list = []
499 for j in range(pLvlCount + 1):
500 pLvl = np.insert(pLvlGrid, 0, 0.0)[j]
501 vNvrsFunc_list.append(
502 CubicInterp(
503 mLvl_temp[:, j] - mLvlMinNow(pLvl),
504 vNvrs_temp[:, j],
505 vNvrsP_temp[:, j],
506 MPCminNvrs * hLvlNow(pLvl),
507 MPCminNvrs,
508 )
509 )
510 # Value function "shifted"
511 vNvrsFuncBase = LinearInterpOnInterp1D(
512 vNvrsFunc_list, np.insert(pLvlGrid, 0, 0.0)
513 )
514 vNvrsFuncNow = VariableLowerBoundFunc2D(vNvrsFuncBase, mLvlMinNow)
516 # "Re-curve" the pseudo-inverse value function into the value function
517 vFuncNow = ValueFuncCRRA(vNvrsFuncNow, CRRA)
519 else:
520 vFuncNow = NullFunc()
522 # Package and return the solution object
523 solution_now = ConsumerSolution(
524 cFunc=cFuncNow,
525 vFunc=vFuncNow,
526 vPfunc=vPfuncNow,
527 vPPfunc=vPPfuncNow,
528 mNrmMin=0.0, # Not a normalized model, mLvlMin will be added below
529 hNrm=0.0, # Not a normalized model, hLvl will be added below
530 MPCmin=MPCminNow,
531 MPCmax=0.0, # This should be a function, need to make it
532 )
533 solution_now.hLvl = hLvlNow
534 solution_now.mLvlMin = mLvlMinNow
535 return solution_now
538###############################################################################
540# Make a constructor dictionary for the general income process consumer type
541GenIncProcessConsumerType_constructors_default = {
542 "IncShkDstn": construct_lognormal_income_process_unemployment,
543 "PermShkDstn": get_PermShkDstn_from_IncShkDstn,
544 "TranShkDstn": get_TranShkDstn_from_IncShkDstn,
545 "aXtraGrid": make_assets_grid,
546 "pLvlPctiles": make_basic_pLvlPctiles,
547 "pLvlGrid": make_pLvlGrid_by_simulation,
548 "pLvlNextFunc": make_trivial_pLvlNextFunc,
549 "solution_terminal": make_2D_CRRA_solution_terminal,
550 "kNrmInitDstn": make_lognormal_kNrm_init_dstn,
551 "pLvlInitDstn": make_lognormal_pLvl_init_dstn,
552}
554# Make a dictionary with parameters for the default constructor for kNrmInitDstn
555GenIncProcessConsumerType_kNrmInitDstn_default = {
556 "kLogInitMean": -12.0, # Mean of log initial capital
557 "kLogInitStd": 0.0, # Stdev of log initial capital
558 "kNrmInitCount": 15, # Number of points in initial capital discretization
559}
561# Make a dictionary with parameters for the default constructor for pLvlInitDstn
562GenIncProcessConsumerType_pLvlInitDstn_default = {
563 "pLogInitMean": 0.0, # Mean of log permanent income
564 "pLogInitStd": 0.4, # Stdev of log permanent income
565 "pLvlInitCount": 15, # Number of points in initial capital discretization
566}
568# Default parameters to make IncShkDstn using construct_lognormal_income_process_unemployment
569GenIncProcessConsumerType_IncShkDstn_default = {
570 "PermShkStd": [0.1], # Standard deviation of log permanent income shocks
571 "PermShkCount": 7, # Number of points in discrete approximation to permanent income shocks
572 "TranShkStd": [0.1], # Standard deviation of log transitory income shocks
573 "TranShkCount": 7, # Number of points in discrete approximation to transitory income shocks
574 "UnempPrb": 0.05, # Probability of unemployment while working
575 "IncUnemp": 0.3, # Unemployment benefits replacement rate while working
576 "T_retire": 0, # Period of retirement (0 --> no retirement)
577 "UnempPrbRet": 0.005, # Probability of "unemployment" while retired
578 "IncUnempRet": 0.0, # "Unemployment" benefits when retired
579}
581# Default parameters to make aXtraGrid using make_assets_grid
582GenIncProcessConsumerType_aXtraGrid_default = {
583 "aXtraMin": 0.001, # Minimum end-of-period "assets above minimum" value
584 "aXtraMax": 30, # Maximum end-of-period "assets above minimum" value
585 "aXtraNestFac": 3, # Exponential nesting factor for aXtraGrid
586 "aXtraCount": 48, # Number of points in the grid of "assets above minimum"
587 "aXtraExtra": [0.005, 0.01], # Additional other values to add in grid (optional)
588}
589GenIncProcessConsumerType_pLvlNextFunc_default = {} # Trivial function has no parameters
591# Default parameters to make pLvlGrid using make_basic_pLvlPctiles
592GenIncProcessConsumerType_pLvlPctiles_default = {
593 "pLvlPctiles_count": 19, # Number of points in the "body" of the grid
594 "pLvlPctiles_bound": [0.05, 0.95], # Percentile bounds of the "body"
595 "pLvlPctiles_tail_count": 4, # Number of points in each tail of the grid
596 "pLvlPctiles_tail_order": np.e, # Scaling factor for points in each tail
597}
599# Default parameters to make pLvlGrid using make_pLvlGrid_by_simulation
600GenIncProcessConsumerType_pLvlGrid_default = {
601 "pLvlExtra": None, # Additional permanent income points to automatically add to the grid, optional
602}
604# Make a dictionary to specify a general income process consumer type
605GenIncProcessConsumerType_solving_default = {
606 # BASIC HARK PARAMETERS REQUIRED TO SOLVE THE MODEL
607 "cycles": 1, # Finite, non-cyclic model
608 "T_cycle": 1, # Number of periods in the cycle for this agent type
609 "pseudo_terminal": False, # Terminal period really does exist
610 "constructors": GenIncProcessConsumerType_constructors_default, # See dictionary above
611 # PRIMITIVE RAW PARAMETERS REQUIRED TO SOLVE THE MODEL
612 "CRRA": 2.0, # Coefficient of relative risk aversion
613 "Rfree": [1.03], # Interest factor on retained assets
614 "DiscFac": 0.96, # Intertemporal discount factor
615 "LivPrb": [0.98], # Survival probability after each period
616 "BoroCnstArt": 0.0, # Artificial borrowing constraint
617 "vFuncBool": False, # Whether to calculate the value function during solution
618 "CubicBool": False, # Whether to use cubic spline interpolation when True
619 # (Uses linear spline interpolation for cFunc when False)
620}
621GenIncProcessConsumerType_simulation_default = {
622 # PARAMETERS REQUIRED TO SIMULATE THE MODEL
623 "AgentCount": 10000, # Number of agents of this type
624 "T_age": None, # Age after which simulated agents are automatically killed
625 "PermGroFacAgg": 1.0, # Aggregate permanent income growth factor
626 # (The portion of PermGroFac attributable to aggregate productivity growth)
627 "NewbornTransShk": False, # Whether Newborns have transitory shock
628 # ADDITIONAL OPTIONAL PARAMETERS
629 "PerfMITShk": False, # Do Perfect Foresight MIT Shock
630 # (Forces Newborns to follow solution path of the agent they replaced if True)
631 "neutral_measure": False, # Whether to use permanent income neutral measure (see Harmenberg 2021)
632}
633GenIncProcessConsumerType_default = {}
634GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_kNrmInitDstn_default)
635GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_pLvlInitDstn_default)
636GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_IncShkDstn_default)
637GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_aXtraGrid_default)
638GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_pLvlNextFunc_default)
639GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_pLvlGrid_default)
640GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_pLvlPctiles_default)
641GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_solving_default)
642GenIncProcessConsumerType_default.update(GenIncProcessConsumerType_simulation_default)
643init_general_inc = GenIncProcessConsumerType_default
646class GenIncProcessConsumerType(IndShockConsumerType):
647 r"""
648 A consumer type with idiosyncratic shocks to persistent and transitory income.
649 Their problem is defined by a sequence of income distributions, survival prob-
650 abilities, and persistent income growth functions, as well as time invariant
651 values for risk aversion, discount factor, the interest rate, the grid of
652 end-of-period assets, and an artificial borrowing constraint.
654 .. math::
655 \begin{eqnarray*}
656 V_t(M_t,P_t) &=& \max_{C_t} U(C_t) + \beta \mathsf{S}_{t} \mathbb{E} [V_{t+1}(M_{t+1}, P_{t+1}) ], \\
657 A_t &=& M_t - C_t, \\
658 A_t/P_t &\geq& \underline{a}, \\
659 M_{t+1} &=& R_{t+1} A_t + \theta_{t+1}, \\
660 P_{t+1} &=& G_{t+1}(P_t)\psi_{t+1}, \\
661 (\psi_{t+1},\theta_{t+1}) &\sim& F_{t+1}, \\
662 \mathbb{E} [\psi_{t+1}] &=& 1, \\
663 U(C) &=& \frac{C^{1-\rho}}{1-\rho}. \\
664 \end{eqnarray*}
667 Constructors
668 ------------
669 IncShkDstn: Constructor, :math:`\psi`, :math:`\theta`
670 The agent's income shock distributions.
672 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.construct_lognormal_income_process_unemployment`
673 aXtraGrid: Constructor
674 The agent's asset grid.
676 Its default constructor is :func:`HARK.utilities.make_assets_grid`
677 pLvlNextFunc: Constructor
678 An arbitrary function used to evolve the GenIncShockConsumerType's permanent income
680 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_trivial_pLvlNextFunc`
681 pLvlGrid: Constructor
682 The agent's pLvl grid
684 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_pLvlGrid_by_simulation`
685 pLvlPctiles: Constructor
686 The agents income level percentile grid
688 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_basic_pLvlPctiles`
690 Solving Parameters
691 ------------------
692 cycles: int
693 0 specifies an infinite horizon model, 1 specifies a finite model.
694 T_cycle: int
695 Number of periods in the cycle for this agent type.
696 CRRA: float, :math:`\rho`
697 Coefficient of Relative Risk Aversion.
698 Rfree: float or list[float], time varying, :math:`\mathsf{R}_t`
699 Risk Free interest rate. Pass a list of floats to make Rfree time varying.
700 DiscFac: float, :math:`\beta`
701 Intertemporal discount factor.
702 LivPrb: list[float], time varying, :math:`\mathsf{S}_t`
703 Survival probability after each period.
704 BoroCnstArt: float, :math:`\underline{a}`
705 The minimum Asset/Perminant Income ratio, None to ignore.
706 vFuncBool: bool
707 Whether to calculate the value function during solution.
708 CubicBool: bool
709 Whether to use cubic spline interpoliation.
711 Simulation Parameters
712 ---------------------
713 AgentCount: int
714 Number of agents of this kind that are created during simulations.
715 T_age: int
716 Age after which to automatically kill agents, None to ignore.
717 T_sim: int, required for simulation
718 Number of periods to simulate.
719 track_vars: list[strings]
720 List of variables that should be tracked when running the simulation.
721 For this agent, the options are 'PermShk', 'TranShk', 'aLvl', 'cLvl', 'mLvl', 'pLvl', and 'who_dies'.
723 PermShk is the agent's permanent income shock
725 TranShk is the agent's transitory income shock
727 aLvl is the nominal asset level
729 cLvl is the nominal consumption level
731 mLvl is the nominal market resources
733 pLvl is the permanent income level
735 who_dies is the array of which agents died
736 aNrmInitMean: float
737 Mean of Log initial Normalized Assets.
738 aNrmInitStd: float
739 Std of Log initial Normalized Assets.
740 pLvlInitMean: float
741 Mean of Log initial permanent income.
742 pLvlInitStd: float
743 Std of Log initial permanent income.
744 PermGroFacAgg: float
745 Aggregate permanent income growth factor (The portion of PermGroFac attributable to aggregate productivity growth).
746 PerfMITShk: boolean
747 Do Perfect Foresight MIT Shock (Forces Newborns to follow solution path of the agent they replaced if True).
748 NewbornTransShk: boolean
749 Whether Newborns have transitory shock.
751 Attributes
752 ----------
753 solution: list[Consumer solution object]
754 Created by the :func:`.solve` method. Finite horizon models create a list with T_cycle+1 elements, for each period in the solution.
755 Infinite horizon solutions return a list with T_cycle elements for each period in the cycle.
757 Unlike other models with this solution type, this model's variables are NOT normalized.
758 The solution functions also depend on the permanent income level. For example, :math:`C=\text{cFunc}(M,P)`.
759 hNrm has been replaced by hLvl which is a function of permanent income.
760 MPC max has not yet been implemented for this class. It will be a function of permanent income.
762 Visit :class:`HARK.ConsumptionSaving.ConsIndShockModel.ConsumerSolution` for more information about the solution.
764 history: Dict[Array]
765 Created by running the :func:`.simulate()` method.
766 Contains the variables in track_vars. Each item in the dictionary is an array with the shape (T_sim,AgentCount).
767 Visit :class:`HARK.core.AgentType.simulate` for more information.
768 """
770 IncShkDstn_default = GenIncProcessConsumerType_IncShkDstn_default
771 aXtraGrid_default = GenIncProcessConsumerType_aXtraGrid_default
772 pLvlNextFunc_default = GenIncProcessConsumerType_pLvlNextFunc_default
773 pLvlGrid_default = GenIncProcessConsumerType_pLvlGrid_default
774 pLvlPctiles_default = GenIncProcessConsumerType_pLvlPctiles_default
775 solving_default = GenIncProcessConsumerType_solving_default
776 simulation_default = GenIncProcessConsumerType_simulation_default
778 state_vars = ["kLvl", "pLvl", "mLvl", "aLvl", "aNrm"]
779 time_vary_ = IndShockConsumerType.time_vary_ + ["pLvlNextFunc", "pLvlGrid"]
780 default_ = {
781 "params": GenIncProcessConsumerType_default,
782 "solver": solve_one_period_ConsGenIncProcess,
783 "model": "ConsGenIncProcess.yaml",
784 "track_vars": ["aLvl", "cLvl", "mLvl", "pLvl"],
785 }
787 def pre_solve(self):
788 self.construct("solution_terminal")
790 def install_retirement_func(self):
791 """
792 Installs a special pLvlNextFunc representing retirement in the correct
793 element of self.pLvlNextFunc. Draws on the attributes T_retire and
794 pLvlNextFuncRet. If T_retire is zero or pLvlNextFuncRet does not
795 exist, this method does nothing.
797 Parameters
798 ----------
799 None
801 Returns
802 -------
803 None
804 """
805 if (not hasattr(self, "pLvlNextFuncRet")) or self.T_retire == 0:
806 return
807 t = self.T_retire
808 self.pLvlNextFunc[t] = self.pLvlNextFuncRet
810 def sim_birth(self, which_agents):
811 """
812 Makes new consumers for the given indices. Initialized variables include aNrm and pLvl, as
813 well as time variables t_age and t_cycle. Normalized assets and persistent income levels
814 are drawn from lognormal distributions given by aNrmInitMean and aNrmInitStd (etc).
816 Parameters
817 ----------
818 which_agents : np.array(Bool)
819 Boolean array of size self.AgentCount indicating which agents should be "born".
821 Returns
822 -------
823 None
824 """
825 super().sim_birth(which_agents)
826 self.state_now["aLvl"][which_agents] = (
827 self.state_now["aNrm"][which_agents] * self.state_now["pLvl"][which_agents]
828 )
830 def transition(self):
831 """
832 Calculates updated values of normalized market resources
833 and persistent income level for each
834 agent. Uses pLvlNow, aLvlNow, PermShkNow, TranShkNow.
836 Parameters
837 ----------
838 None
840 Returns
841 -------
842 kLvlNow
843 pLvlNow
844 mLvlNow
845 """
846 kLvlNow = self.state_prev["aLvl"]
847 pLvlNow = np.zeros_like(kLvlNow)
848 RportNow = self.get_Rport()
850 # Calculate new states: normalized market resources and persistent income level
851 for t in range(self.T_cycle):
852 these = t == self.t_cycle
853 pLvlNow[these] = (
854 self.pLvlNextFunc[t - 1](self.state_prev["pLvl"][these])
855 * self.shocks["PermShk"][these]
856 )
858 # state value
859 bLvlNow = RportNow * kLvlNow # Bank balances before labor income
861 # Market resources after income - state value
862 mLvlNow = bLvlNow + self.shocks["TranShk"] * pLvlNow
864 return (kLvlNow, pLvlNow, mLvlNow)
866 def get_controls(self):
867 """
868 Calculates consumption for each consumer of this type using the consumption functions.
870 Parameters
871 ----------
872 None
874 Returns
875 -------
876 None
877 """
878 cLvlNow = np.zeros(self.AgentCount) + np.nan
879 MPCnow = np.zeros(self.AgentCount) + np.nan
881 for t in range(self.T_cycle):
882 these = t == self.t_cycle
883 cLvlNow[these] = self.solution[t].cFunc(
884 self.state_now["mLvl"][these], self.state_now["pLvl"][these]
885 )
886 MPCnow[these] = self.solution[t].cFunc.derivativeX(
887 self.state_now["mLvl"][these], self.state_now["pLvl"][these]
888 )
889 self.controls["cLvl"] = cLvlNow
890 self.MPCnow = MPCnow
892 def get_poststates(self):
893 """
894 Calculates end-of-period assets for each consumer of this type.
895 Identical to version in IndShockConsumerType but uses Lvl rather than Nrm variables.
897 Parameters
898 ----------
899 None
901 Returns
902 -------
903 None
904 """
905 self.state_now["aLvl"] = self.state_now["mLvl"] - self.controls["cLvl"]
906 # moves now to prev
907 AgentType.get_poststates(self)
909 def check_conditions(self, verbose=None):
910 raise NotImplementedError() # pragma: nocover
912 def calc_limiting_values(self):
913 raise NotImplementedError() # pragma: nocover
916###############################################################################
918# Make a dictionary for the "explicit permanent income" consumer type; see parent dictionary above.
919IndShockExplicitPermIncConsumerType_constructors_default = (
920 GenIncProcessConsumerType_constructors_default.copy()
921)
922IndShockExplicitPermIncConsumerType_constructors_default["pLvlNextFunc"] = (
923 make_explicit_perminc_pLvlNextFunc
924)
925IndShockExplicitPermIncConsumerType_IncShkDstn_default = (
926 GenIncProcessConsumerType_IncShkDstn_default.copy()
927)
928IndShockExplicitPermIncConsumerType_kNrmInitDstn_default = (
929 GenIncProcessConsumerType_kNrmInitDstn_default.copy()
930)
931IndShockExplicitPermIncConsumerType_pLvlInitDstn_default = (
932 GenIncProcessConsumerType_pLvlInitDstn_default.copy()
933)
934IndShockExplicitPermIncConsumerType_aXtraGrid_default = (
935 GenIncProcessConsumerType_aXtraGrid_default.copy()
936)
937IndShockExplicitPermIncConsumerType_pLvlNextFunc_default = (
938 GenIncProcessConsumerType_pLvlNextFunc_default.copy()
939)
940IndShockExplicitPermIncConsumerType_pLvlGrid_default = (
941 GenIncProcessConsumerType_pLvlGrid_default.copy()
942)
943IndShockExplicitPermIncConsumerType_pLvlPctiles_default = (
944 GenIncProcessConsumerType_pLvlPctiles_default.copy()
945)
946IndShockExplicitPermIncConsumerType_solving_default = (
947 GenIncProcessConsumerType_solving_default.copy()
948)
949IndShockExplicitPermIncConsumerType_solving_default["constructors"] = (
950 IndShockExplicitPermIncConsumerType_constructors_default
951)
952IndShockExplicitPermIncConsumerType_pLvlNextFunc_default["PermGroFac"] = [1.0]
953IndShockExplicitPermIncConsumerType_simulation_default = (
954 GenIncProcessConsumerType_simulation_default.copy()
955)
957IndShockExplicitPermIncConsumerType_default = {}
958IndShockExplicitPermIncConsumerType_default.update(
959 IndShockExplicitPermIncConsumerType_IncShkDstn_default
960)
961IndShockExplicitPermIncConsumerType_default.update(
962 IndShockExplicitPermIncConsumerType_kNrmInitDstn_default
963)
964IndShockExplicitPermIncConsumerType_default.update(
965 IndShockExplicitPermIncConsumerType_pLvlInitDstn_default
966)
967IndShockExplicitPermIncConsumerType_default.update(
968 IndShockExplicitPermIncConsumerType_aXtraGrid_default
969)
970IndShockExplicitPermIncConsumerType_default.update(
971 IndShockExplicitPermIncConsumerType_pLvlNextFunc_default
972)
973IndShockExplicitPermIncConsumerType_default.update(
974 IndShockExplicitPermIncConsumerType_pLvlGrid_default
975)
976IndShockExplicitPermIncConsumerType_default.update(
977 IndShockExplicitPermIncConsumerType_pLvlPctiles_default
978)
979IndShockExplicitPermIncConsumerType_default.update(
980 IndShockExplicitPermIncConsumerType_solving_default
981)
982IndShockExplicitPermIncConsumerType_default.update(
983 IndShockExplicitPermIncConsumerType_simulation_default
984)
985init_explicit_perm_inc = IndShockExplicitPermIncConsumerType_default
987# NB: Permanent income growth was not in the default dictionary for GenIncProcessConsumerType
988# because its pLvlNextFunc constructor was *trivial*: no permanent income dynamics at all!
989# For the "explicit permanent income" model, this parameter is added back into the dictionary.
990# However, note that if this model is used in an *infinite horizon* setting, it will work
991# best if the product of PermGroFac (across all periods) is 1. If it is far from 1, then the
992# pLvlGrid that is constructed by the default method might not be appropriate.
995class IndShockExplicitPermIncConsumerType(GenIncProcessConsumerType):
996 r"""
997 A consumer type based on GenIncProcessModel, where the general function
998 describing the path of permanent income multiplies the current permanent
999 income by the PermGroFac (:math:`\Gamma`). It's behavior is the same as
1000 :class:`HARK.ConsumptionSaving.ConsIndShockModel.IndShockConsumerType`, except
1001 that the variables aren't normalized. This makes the result less
1002 accurate. This Model uses a lognormal random walk income process.
1003 If you would like to use a different income process, use
1004 :class:`HARK.ConsumptionSaving.ConsGenIncProcessModel.GenIncProcessConsumerType`
1006 .. math::
1007 \begin{eqnarray*}
1008 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}) ], \\
1009 A_t &=& M_t - C_t, \\
1010 A_t/P_t &\geq& \underline{a}, \\
1011 M_{t+1} &=& R A_t + \theta_{t+1}, \\
1012 P_{t+1} &=& G_{t+1}(P_t)\psi_{t+1}, \\
1013 (\psi_{t+1},\theta_{t+1}) &\sim& F_{t+1}, \\
1014 \mathbb{E} [F_{t+1}] &=& 1, \\
1015 U(C) &=& \frac{C^{1-\rho}}{1-\rho}. \\
1016 G_{t+1} (x) &=&\Gamma_{t+1} x
1017 \end{eqnarray*}
1020 Constructors
1021 ------------
1022 IncShkDstn: Constructor, :math:`\psi`, :math:`\theta`
1023 The agent's income shock distributions.
1025 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.construct_lognormal_income_process_unemployment`
1026 aXtraGrid: Constructor
1027 The agent's asset grid.
1029 Its default constructor is :func:`HARK.utilities.make_assets_grid`
1030 pLvlNextFunc: Constructor, (:math:`\Gamma`)
1031 An arbitrary function used to evolve the GenIncShockConsumerType's permanent income
1033 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_explicit_perminc_pLvlNextFunc`
1034 pLvlGrid: Constructor
1035 The agent's pLvl grid
1037 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_pLvlGrid_by_simulation`
1038 pLvlPctiles: Constructor
1039 The agents income level percentile grid
1041 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_basic_pLvlPctiles`
1043 Solving Parameters
1044 ------------------
1045 cycles: int
1046 0 specifies an infinite horizon model, 1 specifies a finite model.
1047 T_cycle: int
1048 Number of periods in the cycle for this agent type.
1049 CRRA: float, :math:`\rho`
1050 Coefficient of Relative Risk Aversion.
1051 Rfree: float or list[float], time varying, :math:`\mathsf{R}`
1052 Risk Free interest rate. Pass a list of floats to make Rfree time varying.
1053 DiscFac: float, :math:`\beta`
1054 Intertemporal discount factor.
1055 LivPrb: list[float], time varying, :math:`1-\mathsf{D}`
1056 Survival probability after each period.
1057 PermGroFac: list[float], time varying, :math:`\Gamma`
1058 Permanent income growth factor.
1059 BoroCnstArt: float, :math:`\underline{a}`
1060 The minimum Asset/Perminant Income ratio, None to ignore.
1061 vFuncBool: bool
1062 Whether to calculate the value function during solution.
1063 CubicBool: bool
1064 Whether to use cubic spline interpoliation.
1066 Simulation Parameters
1067 ---------------------
1068 AgentCount: int
1069 Number of agents of this kind that are created during simulations.
1070 T_age: int
1071 Age after which to automatically kill agents, None to ignore.
1072 T_sim: int, required for simulation
1073 Number of periods to simulate.
1074 track_vars: list[strings]
1075 List of variables that should be tracked when running the simulation.
1076 For this agent, the options are 'PermShk', 'TranShk', 'aLvl', 'cLvl', 'mLvl', 'pLvl', and 'who_dies'.
1078 PermShk is the agent's permanent income shock
1080 TranShk is the agent's transitory income shock
1082 aLvl is the nominal asset level
1084 cLvl is the nominal consumption level
1086 mLvl is the nominal market resources
1088 pLvl is the permanent income level
1090 who_dies is the array of which agents died
1091 aNrmInitMean: float
1092 Mean of Log initial Normalized Assets.
1093 aNrmInitStd: float
1094 Std of Log initial Normalized Assets.
1095 pLvlInitMean: float
1096 Mean of Log initial permanent income.
1097 pLvlInitStd: float
1098 Std of Log initial permanent income.
1099 PermGroFacAgg: float
1100 Aggregate permanent income growth factor (The portion of PermGroFac attributable to aggregate productivity growth).
1101 PerfMITShk: boolean
1102 Do Perfect Foresight MIT Shock (Forces Newborns to follow solution path of the agent they replaced if True).
1103 NewbornTransShk: boolean
1104 Whether Newborns have transitory shock.
1106 Attributes
1107 ----------
1108 solution: list[Consumer solution object]
1109 Created by the :func:`.solve` method. Finite horizon models create a list with T_cycle+1 elements, for each period in the solution.
1110 Infinite horizon solutions return a list with T_cycle elements for each period in the cycle.
1112 Unlike other models with this solution type, this model's variables are NOT normalized.
1113 The solution functions also depend on the permanent income level. For example, :math:`C=\text{cFunc}(M,P)`.
1114 hNrm has been replaced by hLvl which is a function of permanent income.
1115 MPC max has not yet been implemented for this class. It will be a function of permanent income.
1117 Visit :class:`HARK.ConsumptionSaving.ConsIndShockModel.ConsumerSolution` for more information about the solution.
1119 history: Dict[Array]
1120 Created by running the :func:`.simulate()` method.
1121 Contains the variables in track_vars. Each item in the dictionary is an array with the shape (T_sim,AgentCount).
1122 Visit :class:`HARK.core.AgentType.simulate` for more information.
1123 """
1125 default_ = {
1126 "params": init_explicit_perm_inc,
1127 "solver": solve_one_period_ConsGenIncProcess,
1128 "model": "ConsGenIncProcess.yaml",
1129 "track_vars": ["aLvl", "cLvl", "mLvl", "pLvl"],
1130 }
1133###############################################################################
1135# Make a dictionary for the "persistent idiosyncratic shocks" consumer type; see parent dictionary above.
1137PersistentShockConsumerType_constructors_default = (
1138 GenIncProcessConsumerType_constructors_default.copy()
1139)
1140PersistentShockConsumerType_constructors_default["pLvlNextFunc"] = (
1141 make_AR1_style_pLvlNextFunc
1142)
1143PersistentShockConsumerType_kNrmInitDstn_default = (
1144 IndShockExplicitPermIncConsumerType_kNrmInitDstn_default.copy()
1145)
1146PersistentShockConsumerType_pLvlInitDstn_default = (
1147 IndShockExplicitPermIncConsumerType_pLvlInitDstn_default.copy()
1148)
1149PersistentShockConsumerType_IncShkDstn_default = (
1150 IndShockExplicitPermIncConsumerType_IncShkDstn_default.copy()
1151)
1152PersistentShockConsumerType_aXtraGrid_default = (
1153 IndShockExplicitPermIncConsumerType_aXtraGrid_default.copy()
1154)
1155PersistentShockConsumerType_pLvlNextFunc_default = (
1156 IndShockExplicitPermIncConsumerType_pLvlNextFunc_default.copy()
1157)
1158PersistentShockConsumerType_pLvlGrid_default = (
1159 IndShockExplicitPermIncConsumerType_pLvlGrid_default.copy()
1160)
1161PersistentShockConsumerType_pLvlPctiles_default = (
1162 IndShockExplicitPermIncConsumerType_pLvlPctiles_default.copy()
1163)
1164PersistentShockConsumerType_solving_default = (
1165 IndShockExplicitPermIncConsumerType_solving_default.copy()
1166)
1167PersistentShockConsumerType_solving_default["constructors"] = (
1168 PersistentShockConsumerType_constructors_default
1169)
1170PersistentShockConsumerType_pLvlNextFunc_default["PrstIncCorr"] = 0.98
1171PersistentShockConsumerType_simulation_default = (
1172 IndShockExplicitPermIncConsumerType_simulation_default.copy()
1173)
1175PersistentShockConsumerType_default = {}
1176PersistentShockConsumerType_default.update(
1177 PersistentShockConsumerType_IncShkDstn_default
1178)
1179PersistentShockConsumerType_default.update(
1180 PersistentShockConsumerType_kNrmInitDstn_default
1181)
1182PersistentShockConsumerType_default.update(
1183 PersistentShockConsumerType_pLvlInitDstn_default
1184)
1185PersistentShockConsumerType_default.update(
1186 PersistentShockConsumerType_aXtraGrid_default
1187)
1188PersistentShockConsumerType_default.update(
1189 PersistentShockConsumerType_pLvlNextFunc_default
1190)
1191PersistentShockConsumerType_default.update(PersistentShockConsumerType_pLvlGrid_default)
1192PersistentShockConsumerType_default.update(
1193 PersistentShockConsumerType_pLvlPctiles_default
1194)
1195PersistentShockConsumerType_default.update(PersistentShockConsumerType_solving_default)
1196PersistentShockConsumerType_default.update(
1197 PersistentShockConsumerType_simulation_default
1198)
1199init_persistent_shocks = PersistentShockConsumerType_default
1202class PersistentShockConsumerType(GenIncProcessConsumerType):
1203 r"""
1204 A consumer type based on GenIncProcessModel, where the log permanent income follows an AR1 process.
1205 If you would like to use a different income process, use
1206 :class:`HARK.ConsumptionSaving.ConsGenIncProcessModel.GenIncProcessConsumerType`
1208 .. math::
1209 \begin{eqnarray*}
1210 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}) ], \\
1211 A_t &=& M_t - C_t, \\
1212 A_t/P_t &\geq& \underline{a}, \\
1213 M_{t+1} &=& R A_t + \theta_{t+1}, \\
1214 p_{t+1} &=& G_{t+1}(P_t)\psi_{t+1}, \\
1215 (\psi_{t+1},\theta_{t+1}) &\sim& F_{t+1}, \\
1216 \mathbb{E} [F_{t+1}] &=& 1, \\
1217 U(C) &=& \frac{C^{1-\rho}}{1-\rho}, \\
1218 log(G_{t+1} (x)) &=&\varphi log(x) + (1-\varphi) log(\overline{P}_{t})+log(\Gamma_{t+1}) + log(\psi_{t+1}), \\
1219 \overline{P}_{t+1} &=& \overline{P}_{t} \Gamma_{t+1} \\
1220 \end{eqnarray*}
1222 Constructors
1223 ------------
1224 IncShkDstn: Constructor, :math:`\psi`, :math:`\theta`
1225 The agent's income shock distributions.
1226 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.construct_lognormal_income_process_unemployment`
1227 aXtraGrid: Constructor
1228 The agent's asset grid.
1229 Its default constructor is :func:`HARK.utilities.make_assets_grid`
1230 pLvlNextFunc: Constructor, (:math:`\Gamma`, :math:`\varphi`)
1231 An arbitrary function used to evolve the GenIncShockConsumerType's permanent income
1232 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_AR1_style_pLvlNextFunc`
1233 pLvlGrid: Constructor
1234 The agent's pLvl grid
1235 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_pLvlGrid_by_simulation`
1236 pLvlPctiles: Constructor
1237 The agents income level percentile grid
1238 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_basic_pLvlPctiles`
1240 Solving Parameters
1241 ------------------
1242 cycles: int
1243 0 specifies an infinite horizon model, 1 specifies a finite model.
1244 T_cycle: int
1245 Number of periods in the cycle for this agent type.
1246 CRRA: float, :math:`\rho`
1247 Coefficient of Relative Risk Aversion.
1248 Rfree: list[float], time varying, :math:`\mathsf{R}`
1249 Risk Free interest rate. Pass a list of floats to make Rfree time varying.
1250 DiscFac: float, :math:`\beta`
1251 Intertemporal discount factor.
1252 LivPrb: list[float], time varying, :math:`1-\mathsf{D}`
1253 Survival probability after each period.
1254 PermGroFac: list[float], time varying, :math:`\Gamma`
1255 Permanent income growth factor.
1256 BoroCnstArt: float, :math:`\underline{a}`
1257 The minimum Asset/Perminant Income ratio, None to ignore.
1258 vFuncBool: bool
1259 Whether to calculate the value function during solution.
1260 CubicBool: bool
1261 Whether to use cubic spline interpoliation.
1263 Simulation Parameters
1264 ---------------------
1265 AgentCount: int
1266 Number of agents of this kind that are created during simulations.
1267 T_age: int
1268 Age after which to automatically kill agents, None to ignore.
1269 T_sim: int, required for simulation
1270 Number of periods to simulate.
1271 track_vars: list[strings]
1272 List of variables that should be tracked when running the simulation.
1273 For this agent, the options are 'PermShk', 'TranShk', 'aLvl', 'cLvl', 'mLvl', 'pLvl', and 'who_dies'.
1275 PermShk is the agent's permanent income shock
1277 TranShk is the agent's transitory income shock
1279 aLvl is the nominal asset level
1281 cLvl is the nominal consumption level
1283 mLvl is the nominal market resources
1285 pLvl is the permanent income level
1287 who_dies is the array of which agents died
1288 kLogInitMean: float
1289 Mean of Log initial Normalized Assets.
1290 kLogInitStd: float
1291 Std of Log initial Normalized Assets.
1292 pLogInitMean: float
1293 Mean of Log initial permanent income.
1294 pLogInitStd: float
1295 Std of Log initial permanent income.
1296 PermGroFacAgg: float
1297 Aggregate permanent income growth factor (The portion of PermGroFac attributable to aggregate productivity growth).
1298 PerfMITShk: boolean
1299 Do Perfect Foresight MIT Shock (Forces Newborns to follow solution path of the agent they replaced if True).
1300 NewbornTransShk: boolean
1301 Whether Newborns have transitory shock.
1303 Attributes
1304 ----------
1305 solution: list[Consumer solution object]
1306 Created by the :func:`.solve` method. Finite horizon models create a list with T_cycle+1 elements, for each period in the solution.
1307 Infinite horizon solutions return a list with T_cycle elements for each period in the cycle.
1309 Unlike other models with this solution type, this model's variables are NOT normalized.
1310 The solution functions also depend on the permanent income level. For example, :math:`C=\text{cFunc}(M,P)`.
1311 hNrm has been replaced by hLvl which is a function of permanent income.
1312 MPC max has not yet been implemented for this class. It will be a function of permanent income.
1314 Visit :class:`HARK.ConsumptionSaving.ConsIndShockModel.ConsumerSolution` for more information about the solution.
1316 history: Dict[Array]
1317 Created by running the :func:`.simulate()` method.
1318 Contains the variables in track_vars. Each item in the dictionary is an array with the shape (T_sim,AgentCount).
1319 Visit :class:`HARK.core.AgentType.simulate` for more information.
1320 """
1322 default_ = {
1323 "params": init_persistent_shocks,
1324 "solver": solve_one_period_ConsGenIncProcess,
1325 "model": "ConsGenIncProcess.yaml",
1326 "track_vars": ["aLvl", "cLvl", "mLvl", "pLvl"],
1327 }