Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ConsIndShock's init_lifecycle #951

Merged
merged 5 commits into from
Feb 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Documentation/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interpolation for problems with CRRA utility. See [#888](https://github.com/econ
* Adds a module with tools for parsing and using various income calibrations from the literature. It includes the option of using life-cycle profiles of income shock variances from [Sabelhaus and Song (2010)](https://www.sciencedirect.com/science/article/abs/pii/S0304393210000358). See [#921](https://github.com/econ-ark/HARK/pull/921), [#941](https://github.com/econ-ark/HARK/pull/941).
* remove "Now" from model variable names [#936](https://github.com/econ-ark/HARK/pull/936)
* Moves state MrkvNow to shocks['Mrkv'] in AggShockMarkov and KrusellSmith models [#935](https://github.com/econ-ark/HARK/pull/935)
* Replaces `ConsIndShock`'s `init_lifecycle` with an actual life-cycle calibration [#951](https://github.com/econ-ark/HARK/pull/951).

#### Minor Changes

Expand Down
62 changes: 42 additions & 20 deletions HARK/ConsumptionSaving/ConsIndShockModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
from HARK import _log
from HARK import set_verbosity_level

from HARK.Calibration.Income.IncomeTools import ParseIncomeSpec, ParseTimeParams, Cagetti_income
from HARK.datasets.SCF.WealthIncomeDist.SCFDistTools import income_wealth_dists_from_scf
from HARK.datasets.life_tables.us_ssa.SSATools import parse_ssa_life_table

__all__ = [
"ConsumerSolution",
Expand Down Expand Up @@ -2825,27 +2828,46 @@ def constructAssetsGrid(parameters):


# Make a dictionary to specify a lifecycle consumer with a finite horizon

# Main calibration characteristics
birth_age = 25
death_age = 90
adjust_infl_to = 1992
# Use income estimates from Cagetti (2003) for High-school graduates
education = "HS"
income_calib = Cagetti_income[education]

# Income specification
income_params = ParseIncomeSpec(
age_min=birth_age,
age_max=death_age,
adjust_infl_to=adjust_infl_to,
**income_calib,
SabelhausSong=True
)

# Initial distribution of wealth and permanent income
dist_params = income_wealth_dists_from_scf(
base_year=adjust_infl_to, age=birth_age, education=education, wave=1995
)

# We need survival probabilities only up to death_age-1, because survival
# probability at death_age is 1.
liv_prb = parse_ssa_life_table(
female=False, cross_sec=True, year=2004, min_age=birth_age, max_age=death_age - 1
)

# Parameters related to the number of periods implied by the calibration
time_params = ParseTimeParams(age_birth=birth_age, age_death=death_age)

# Update all the new parameters
init_lifecycle = copy(init_idiosyncratic_shocks)
init_lifecycle["PermGroFac"] = [
1.01,
1.01,
1.01,
1.01,
1.01,
1.02,
1.02,
1.02,
1.02,
1.02,
]
init_lifecycle["PermShkStd"] = [0.1, 0.2, 0.1, 0.2, 0.1, 0.2, 0.1, 0, 0, 0]
init_lifecycle["TranShkStd"] = [0.3, 0.2, 0.1, 0.3, 0.2, 0.1, 0.3, 0, 0, 0]
init_lifecycle["LivPrb"] = [0.99, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1]
init_lifecycle["T_cycle"] = 10
init_lifecycle["T_retire"] = 7
init_lifecycle[
"T_age"
] = 11 # Make sure that old people die at terminal age and don't turn into newborns!
init_lifecycle.update(time_params)
init_lifecycle.update(dist_params)
# Note the income specification overrides the pLvlInitMean from the SCF.
init_lifecycle.update(income_params)
init_lifecycle.update({"LivPrb": liv_prb})


# Make a dictionary to specify an infinite consumer with a four period cycle
init_cyclical = copy(init_idiosyncratic_shocks)
Expand Down
28 changes: 14 additions & 14 deletions HARK/ConsumptionSaving/tests/test_IndShockConsumerType.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,20 @@ def test_ConsIndShockSolverBasic(self):
LifecycleExample.solve()

# test the solution_terminal
self.assertAlmostEqual(LifecycleExample.solution[10].cFunc(2).tolist(), 2)
self.assertAlmostEqual(LifecycleExample.solution[-1].cFunc(2).tolist(), 2)

self.assertAlmostEqual(LifecycleExample.solution[9].cFunc(1), 0.97769632)
self.assertAlmostEqual(LifecycleExample.solution[8].cFunc(1), 0.96624445)
self.assertAlmostEqual(LifecycleExample.solution[7].cFunc(1), 0.95691449)
self.assertAlmostEqual(LifecycleExample.solution[9].cFunc(1), 0.89066194)
self.assertAlmostEqual(LifecycleExample.solution[8].cFunc(1), 0.89144313)
self.assertAlmostEqual(LifecycleExample.solution[7].cFunc(1), 0.89210133)

self.assertAlmostEqual(
LifecycleExample.solution[0].cFunc(1).tolist(), 0.87362789
LifecycleExample.solution[0].cFunc(1).tolist(), 0.8928547282397321
)
self.assertAlmostEqual(
LifecycleExample.solution[1].cFunc(1).tolist(), 0.9081621
LifecycleExample.solution[1].cFunc(1).tolist(), 0.8930303445748624
)
self.assertAlmostEqual(
LifecycleExample.solution[2].cFunc(1).tolist(), 0.9563899
LifecycleExample.solution[2].cFunc(1).tolist(), 0.8933075371183773
)

solver = ConsIndShockSolverBasic(
Expand All @@ -65,23 +65,23 @@ def test_ConsIndShockSolverBasic(self):

solver.prepareToSolve()

self.assertAlmostEqual(solver.DiscFacEff, 0.9503999999999999)
self.assertAlmostEqual(solver.PermShkMinNext, 0.850430160026919)
self.assertAlmostEqual(solver.DiscFacEff, 0.9586233599999999)
self.assertAlmostEqual(solver.PermShkMinNext, 0.9037554719886154)
self.assertAlmostEqual(solver.cFuncNowCnst(4).tolist(), 4.0)
self.assertAlmostEqual(solver.prepareToCalcEndOfPrdvP()[0], -0.2491750859108316)
self.assertAlmostEqual(solver.prepareToCalcEndOfPrdvP()[-1], 19.74982491408914)
self.assertAlmostEqual(solver.prepareToCalcEndOfPrdvP()[0], -0.2732742703949109)
self.assertAlmostEqual(solver.prepareToCalcEndOfPrdvP()[-1], 19.72572572960506)

EndOfPrdvP = solver.calcEndOfPrdvP()

self.assertAlmostEqual(EndOfPrdvP[0], 6622.251864311334)
self.assertAlmostEqual(EndOfPrdvP[-1], 0.026301061207747087)
self.assertAlmostEqual(EndOfPrdvP[0], 6710.672670733023)
self.assertAlmostEqual(EndOfPrdvP[-1], 0.14122987153089447)

solution = solver.makeBasicSolution(
EndOfPrdvP, solver.aNrmNow, solver.makeLinearcFunc
)
solver.addMPCandHumanWealth(solution)

self.assertAlmostEqual(solution.cFunc(4).tolist(), 1.7391265696400773)
self.assertAlmostEqual(solution.cFunc(4).tolist(), 1.484118342351686)

def test_simulated_values(self):
self.agent.initializeSim()
Expand Down
14 changes: 7 additions & 7 deletions HARK/ConsumptionSaving/tests/test_IndShockConsumerTypeFast.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,20 @@ def test_ConsIndShockSolverBasic(self):
LifecycleExample.solve()

# test the solution_terminal
self.assertAlmostEqual(LifecycleExample.solution[10].cFunc(2).tolist(), 2)
self.assertAlmostEqual(LifecycleExample.solution[-1].cFunc(2).tolist(), 2)

self.assertAlmostEqual(LifecycleExample.solution[9].cFunc(1), 0.97769632)
self.assertAlmostEqual(LifecycleExample.solution[8].cFunc(1), 0.96624445)
self.assertAlmostEqual(LifecycleExample.solution[7].cFunc(1), 0.95691449)
self.assertAlmostEqual(LifecycleExample.solution[9].cFunc(1), 0.89066194)
self.assertAlmostEqual(LifecycleExample.solution[8].cFunc(1), 0.89144313)
self.assertAlmostEqual(LifecycleExample.solution[7].cFunc(1), 0.89210133)

self.assertAlmostEqual(
LifecycleExample.solution[0].cFunc(1).tolist(), 0.87362789
LifecycleExample.solution[0].cFunc(1).tolist(), 0.8928547282397321
)
self.assertAlmostEqual(
LifecycleExample.solution[1].cFunc(1).tolist(), 0.9081621
LifecycleExample.solution[1].cFunc(1).tolist(), 0.8930303445748624
)
self.assertAlmostEqual(
LifecycleExample.solution[2].cFunc(1).tolist(), 0.9563899
LifecycleExample.solution[2].cFunc(1).tolist(), 0.8933075371183773
)

def test_simulated_values(self):
Expand Down