Skip to content

Commit

Permalink
Merge pull request #951 from Mv77/Calibration/init_lifecycle
Browse files Browse the repository at this point in the history
Update ConsIndShock's init_lifecycle
  • Loading branch information
sbenthall authored Feb 14, 2021
2 parents a9f10c3 + a05cde9 commit 4ff6ea8
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 41 deletions.
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

0 comments on commit 4ff6ea8

Please sign in to comment.