Skip to content

Commit

Permalink
fix kink in cons Bequest model
Browse files Browse the repository at this point in the history
  • Loading branch information
alanlujan91 committed Mar 1, 2024
1 parent 649d8c6 commit bb44496
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 294 deletions.
65 changes: 40 additions & 25 deletions HARK/ConsumptionSaving/ConsBequestModel.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""
Classes to solve consumption-saving models with a bequest motive and
"""Classes to solve consumption-saving models with a bequest motive and
idiosyncratic shocks to income and wealth. All models here assume
separable CRRA utility of consumption and Stone-Geary utility of
savings with geometric discounting of the continuation value and
Expand All @@ -11,7 +10,6 @@
"""

import numpy as np

from HARK.ConsumptionSaving.ConsIndShockModel import (
ConsIndShockSolver,
IndShockConsumerType,
Expand All @@ -37,51 +35,44 @@


class BequestWarmGlowConsumerType(IndShockConsumerType):
time_vary_ = IndShockConsumerType.time_vary_ + [
time_inv_ = IndShockConsumerType.time_inv_ + [
"BeqCRRA",
"BeqFac",
"BeqShift",
]

time_vary_ = IndShockConsumerType.time_vary_ + [
"BeqFac",
]

def __init__(self, **kwds):
params = init_wealth_in_utility.copy()
params.update(kwds)

super().__init__(**params)

self.solve_one_period = make_one_period_oo_solver(BequestWarmGlowConsumerSolver)
self.solve_one_period = make_one_period_oo_solver(
BequestWarmGlowConsumerSolver,
)

def update(self):
super().update()
self.update_parameters()

def update_parameters(self):
if isinstance(self.BeqCRRA, (int, float)):
self.BeqCRRA = [self.BeqCRRA] * self.T_cycle
elif len(self.BeqCRRA) == 1:
self.BeqCRRA *= self.T_cycle
elif len(self.BeqCRRA) != self.T_cycle:
raise ValueError(
"Bequest CRRA parameter must be a single value or a list of length T_cycle"
)
if not isinstance(self.BeqCRRA, (int, float)):
raise ValueError("Bequest CRRA parameter must be a single value.")

if isinstance(self.BeqFac, (int, float)):
self.BeqFac = [self.BeqFac] * self.T_cycle
elif len(self.BeqFac) == 1:
self.BeqFac *= self.T_cycle
elif len(self.BeqFac) != self.T_cycle:
raise ValueError(
"Bequest relative value parameter must be a single value or a list of length T_cycle"
"Bequest relative value parameter must be a single value or a list of length T_cycle",
)

if isinstance(self.BeqShift, (int, float)):
self.BeqShift = [self.BeqShift] * self.T_cycle
elif len(self.BeqShift) == 1:
self.BeqShift *= self.T_cycle
elif len(self.BeqShift) != self.T_cycle:
raise ValueError(
"Bequest Stone-Geary parameter must be a single value or a list of length T_cycle"
)
if not isinstance(self.BeqShift, (int, float)):
raise ValueError("Bequest Stone-Geary parameter must be a single value.")

def update_solution_terminal(self):
if self.TermBeqFac == 0.0: # No terminal bequest
Expand All @@ -90,7 +81,9 @@ def update_solution_terminal(self):
utility = UtilityFuncCRRA(self.CRRA)

warm_glow = UtilityFuncStoneGeary(
self.TermBeqCRRA, factor=self.TermBeqFac, shifter=self.TermBeqShift
self.TermBeqCRRA,
factor=self.TermBeqFac,
shifter=self.TermBeqShift,
)

aNrmGrid = (
Expand Down Expand Up @@ -127,7 +120,7 @@ def __init__(self, **kwds):
super().__init__(**params)

self.solve_one_period = make_one_period_oo_solver(
BequestWarmGlowPortfolioSolver
BequestWarmGlowPortfolioSolver,
)

def update(self):
Expand Down Expand Up @@ -212,6 +205,28 @@ def def_utility_funcs(self):

self.warm_glow = UtilityFuncStoneGeary(self.BeqCRRA, BeqFacEff, self.BeqShift)

def def_BoroCnst(self, BoroCnstArt):
self.BoroCnstNat = (
(self.solution_next.mNrmMin - self.TranShkMinNext)
* (self.PermGroFac * self.PermShkMinNext)
/ self.Rfree
)

self.BoroCnstNat = np.max([self.BoroCnstNat, -self.BeqShift])

if BoroCnstArt is None:
self.mNrmMinNow = self.BoroCnstNat
else:
self.mNrmMinNow = np.max([self.BoroCnstNat, BoroCnstArt])
if self.BoroCnstNat < self.mNrmMinNow:
self.MPCmaxEff = 1.0
else:
self.MPCmaxEff = self.MPCmaxNow

self.cFuncNowCnst = LinearInterp(
np.array([self.mNrmMinNow, self.mNrmMinNow + 1]), np.array([0.0, 1.0])
)

def calc_EndOfPrdvP(self):
EndofPrdvP = super().calc_EndOfPrdvP()

Expand Down
27 changes: 14 additions & 13 deletions HARK/ConsumptionSaving/ConsIndShockModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,10 @@
See NARK https://github.com/econ-ark/HARK/blob/master/Documentation/NARK/NARK.pdf for information on variable naming conventions.
See HARK documentation for mathematical descriptions of the models being solved.
"""

from copy import copy, deepcopy

import numpy as np
from scipy import sparse as sp
from scipy.optimize import newton

from HARK import (
AgentType,
NullFunc,
_log,
make_one_period_oo_solver,
set_verbosity_level,
)
from HARK.Calibration.Income.IncomeTools import (
Cagetti_income,
parse_income_spec,
Expand Down Expand Up @@ -71,6 +62,16 @@
jump_to_grid_2D,
make_grid_exp_mult,
)
from scipy import sparse as sp
from scipy.optimize import newton

from HARK import (
AgentType,
NullFunc,
_log,
make_one_period_oo_solver,
set_verbosity_level,
)

__all__ = [
"ConsumerSolution",
Expand Down Expand Up @@ -2221,8 +2222,8 @@ def check_conditions(self, verbose=None):


# Make a dictionary to specify an idiosyncratic income shocks consumer
init_idiosyncratic_shocks = dict(
init_perfect_foresight,
init_idiosyncratic_shocks = {
**init_perfect_foresight,
**{ # assets above grid parameters
"aXtraMin": 0.001, # Minimum end-of-period "assets above minimum" value
"aXtraMax": 20, # Maximum end-of-period "assets above minimum" value
Expand Down Expand Up @@ -2255,7 +2256,7 @@ def check_conditions(self, verbose=None):
# Whether Newborns have transitory shock. The default is False.
"NewbornTransShk": False,
},
)
}


class IndShockConsumerType(PerfForesightConsumerType):
Expand Down
117 changes: 62 additions & 55 deletions examples/ConsBequestModel/example_AccidentalBequest.ipynb

Large diffs are not rendered by default.

150 changes: 4 additions & 146 deletions examples/ConsBequestModel/example_ConsIndShockComp.ipynb

Large diffs are not rendered by default.

117 changes: 62 additions & 55 deletions examples/ConsBequestModel/example_TerminalBequest.ipynb

Large diffs are not rendered by default.

0 comments on commit bb44496

Please sign in to comment.