Coverage for HARK / ConsumptionSaving / ConsGenIncProcessModel.py: 97%
309 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-12-07 05:16 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2025-12-07 05:16 +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 \mathsf{S}_{t} \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_{t+1} 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} [\psi_{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}_t`
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:`\mathsf{S}_t`
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 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 RfreeNow = self.get_Rfree()
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 = RfreeNow * 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()
912 def calc_limiting_values(self):
913 raise NotImplementedError()
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 IncShkDstn_default = GenIncProcessConsumerType_IncShkDstn_default
1126 aXtraGrid_default = GenIncProcessConsumerType_aXtraGrid_default
1127 pLvlNextFunc_default = GenIncProcessConsumerType_pLvlNextFunc_default
1128 pLvlGrid_default = GenIncProcessConsumerType_pLvlGrid_default
1129 pLvlPctiles_default = GenIncProcessConsumerType_pLvlPctiles_default
1130 solving_default = GenIncProcessConsumerType_solving_default
1131 simulation_default = GenIncProcessConsumerType_simulation_default
1133 default_ = {
1134 "params": init_explicit_perm_inc,
1135 "solver": solve_one_period_ConsGenIncProcess,
1136 }
1139###############################################################################
1141# Make a dictionary for the "persistent idiosyncratic shocks" consumer type; see parent dictionary above.
1143PersistentShockConsumerType_constructors_default = (
1144 GenIncProcessConsumerType_constructors_default.copy()
1145)
1146PersistentShockConsumerType_constructors_default["pLvlNextFunc"] = (
1147 make_AR1_style_pLvlNextFunc
1148)
1149PersistentShockConsumerType_kNrmInitDstn_default = (
1150 IndShockExplicitPermIncConsumerType_kNrmInitDstn_default.copy()
1151)
1152PersistentShockConsumerType_pLvlInitDstn_default = (
1153 IndShockExplicitPermIncConsumerType_pLvlInitDstn_default.copy()
1154)
1155PersistentShockConsumerType_IncShkDstn_default = (
1156 IndShockExplicitPermIncConsumerType_IncShkDstn_default.copy()
1157)
1158PersistentShockConsumerType_aXtraGrid_default = (
1159 IndShockExplicitPermIncConsumerType_aXtraGrid_default.copy()
1160)
1161PersistentShockConsumerType_pLvlNextFunc_default = (
1162 IndShockExplicitPermIncConsumerType_pLvlNextFunc_default.copy()
1163)
1164PersistentShockConsumerType_pLvlGrid_default = (
1165 IndShockExplicitPermIncConsumerType_pLvlGrid_default.copy()
1166)
1167PersistentShockConsumerType_pLvlPctiles_default = (
1168 IndShockExplicitPermIncConsumerType_pLvlPctiles_default.copy()
1169)
1170PersistentShockConsumerType_solving_default = (
1171 IndShockExplicitPermIncConsumerType_solving_default.copy()
1172)
1173PersistentShockConsumerType_solving_default["constructors"] = (
1174 PersistentShockConsumerType_constructors_default
1175)
1176PersistentShockConsumerType_pLvlNextFunc_default["PrstIncCorr"] = 0.98
1177PersistentShockConsumerType_simulation_default = (
1178 IndShockExplicitPermIncConsumerType_simulation_default.copy()
1179)
1181PersistentShockConsumerType_default = {}
1182PersistentShockConsumerType_default.update(
1183 PersistentShockConsumerType_IncShkDstn_default
1184)
1185PersistentShockConsumerType_default.update(
1186 PersistentShockConsumerType_kNrmInitDstn_default
1187)
1188PersistentShockConsumerType_default.update(
1189 PersistentShockConsumerType_pLvlInitDstn_default
1190)
1191PersistentShockConsumerType_default.update(
1192 PersistentShockConsumerType_aXtraGrid_default
1193)
1194PersistentShockConsumerType_default.update(
1195 PersistentShockConsumerType_pLvlNextFunc_default
1196)
1197PersistentShockConsumerType_default.update(PersistentShockConsumerType_pLvlGrid_default)
1198PersistentShockConsumerType_default.update(
1199 PersistentShockConsumerType_pLvlPctiles_default
1200)
1201PersistentShockConsumerType_default.update(PersistentShockConsumerType_solving_default)
1202PersistentShockConsumerType_default.update(
1203 PersistentShockConsumerType_simulation_default
1204)
1205init_persistent_shocks = PersistentShockConsumerType_default
1208class PersistentShockConsumerType(GenIncProcessConsumerType):
1209 r"""
1210 A consumer type based on GenIncProcessModel, where the log permanent income follows an AR1 process.
1211 If you would like to use a different income process, use
1212 :class:`HARK.ConsumptionSaving.ConsGenIncProcessModel.GenIncProcessConsumerType`
1214 .. math::
1215 \begin{eqnarray*}
1216 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}) ], \\
1217 A_t &=& M_t - C_t, \\
1218 A_t/P_t &\geq& \underline{a}, \\
1219 M_{t+1} &=& R A_t + \theta_{t+1}, \\
1220 p_{t+1} &=& G_{t+1}(P_t)\psi_{t+1}, \\
1221 (\psi_{t+1},\theta_{t+1}) &\sim& F_{t+1}, \\
1222 \mathbb{E} [F_{t+1}] &=& 1, \\
1223 U(C) &=& \frac{C^{1-\rho}}{1-\rho}, \\
1224 log(G_{t+1} (x)) &=&\varphi log(x) + (1-\varphi) log(\overline{P}_{t})+log(\Gamma_{t+1}) + log(\psi_{t+1}), \\
1225 \overline{P}_{t+1} &=& \overline{P}_{t} \Gamma_{t+1} \\
1226 \end{eqnarray*}
1229 Constructors
1230 ------------
1231 IncShkDstn: Constructor, :math:`\psi`, :math:`\theta`
1232 The agent's income shock distributions.
1234 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.construct_lognormal_income_process_unemployment`
1235 aXtraGrid: Constructor
1236 The agent's asset grid.
1238 Its default constructor is :func:`HARK.utilities.make_assets_grid`
1239 pLvlNextFunc: Constructor, (:math:`\Gamma`, :math:`\varphi`)
1240 An arbitrary function used to evolve the GenIncShockConsumerType's permanent income
1242 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_AR1_style_pLvlNextFunc`
1243 pLvlGrid: Constructor
1244 The agent's pLvl grid
1246 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_pLvlGrid_by_simulation`
1247 pLvlPctiles: Constructor
1248 The agents income level percentile grid
1250 Its default constructor is :func:`HARK.Calibration.Income.IncomeProcesses.make_basic_pLvlPctiles`
1252 Solving Parameters
1253 ------------------
1254 cycles: int
1255 0 specifies an infinite horizon model, 1 specifies a finite model.
1256 T_cycle: int
1257 Number of periods in the cycle for this agent type.
1258 CRRA: float, :math:`\rho`
1259 Coefficient of Relative Risk Aversion.
1260 Rfree: float or list[float], time varying, :math:`\mathsf{R}`
1261 Risk Free interest rate. Pass a list of floats to make Rfree time varying.
1262 DiscFac: float, :math:`\beta`
1263 Intertemporal discount factor.
1264 LivPrb: list[float], time varying, :math:`1-\mathsf{D}`
1265 Survival probability after each period.
1266 PermGroFac: list[float], time varying, :math:`\Gamma`
1267 Permanent income growth factor.
1268 BoroCnstArt: float, :math:`\underline{a}`
1269 The minimum Asset/Perminant Income ratio, None to ignore.
1270 vFuncBool: bool
1271 Whether to calculate the value function during solution.
1272 CubicBool: bool
1273 Whether to use cubic spline interpoliation.
1275 Simulation Parameters
1276 ---------------------
1277 AgentCount: int
1278 Number of agents of this kind that are created during simulations.
1279 T_age: int
1280 Age after which to automatically kill agents, None to ignore.
1281 T_sim: int, required for simulation
1282 Number of periods to simulate.
1283 track_vars: list[strings]
1284 List of variables that should be tracked when running the simulation.
1285 For this agent, the options are 'PermShk', 'TranShk', 'aLvl', 'cLvl', 'mLvl', 'pLvl', and 'who_dies'.
1287 PermShk is the agent's permanent income shock
1289 TranShk is the agent's transitory income shock
1291 aLvl is the nominal asset level
1293 cLvl is the nominal consumption level
1295 mLvl is the nominal market resources
1297 pLvl is the permanent income level
1299 who_dies is the array of which agents died
1300 aNrmInitMean: float
1301 Mean of Log initial Normalized Assets.
1302 aNrmInitStd: float
1303 Std of Log initial Normalized Assets.
1304 pLvlInitMean: float
1305 Mean of Log initial permanent income.
1306 pLvlInitStd: float
1307 Std of Log initial permanent income.
1308 PermGroFacAgg: float
1309 Aggregate permanent income growth factor (The portion of PermGroFac attributable to aggregate productivity growth).
1310 PerfMITShk: boolean
1311 Do Perfect Foresight MIT Shock (Forces Newborns to follow solution path of the agent they replaced if True).
1312 NewbornTransShk: boolean
1313 Whether Newborns have transitory shock.
1315 Attributes
1316 ----------
1317 solution: list[Consumer solution object]
1318 Created by the :func:`.solve` method. Finite horizon models create a list with T_cycle+1 elements, for each period in the solution.
1319 Infinite horizon solutions return a list with T_cycle elements for each period in the cycle.
1321 Unlike other models with this solution type, this model's variables are NOT normalized.
1322 The solution functions also depend on the permanent income level. For example, :math:`C=\text{cFunc}(M,P)`.
1323 hNrm has been replaced by hLvl which is a function of permanent income.
1324 MPC max has not yet been implemented for this class. It will be a function of permanent income.
1326 Visit :class:`HARK.ConsumptionSaving.ConsIndShockModel.ConsumerSolution` for more information about the solution.
1328 history: Dict[Array]
1329 Created by running the :func:`.simulate()` method.
1330 Contains the variables in track_vars. Each item in the dictionary is an array with the shape (T_sim,AgentCount).
1331 Visit :class:`HARK.core.AgentType.simulate` for more information.
1332 """
1334 IncShkDstn_default = PersistentShockConsumerType_IncShkDstn_default
1335 aXtraGrid_default = PersistentShockConsumerType_aXtraGrid_default
1336 pLvlNextFunc_default = PersistentShockConsumerType_pLvlNextFunc_default
1337 pLvlGrid_default = PersistentShockConsumerType_pLvlGrid_default
1338 pLvlPctiles_default = PersistentShockConsumerType_pLvlPctiles_default
1339 solving_default = PersistentShockConsumerType_solving_default
1340 simulation_default = PersistentShockConsumerType_simulation_default
1342 default_ = {
1343 "params": init_persistent_shocks,
1344 "solver": solve_one_period_ConsGenIncProcess,
1345 }