Skip to content

Commit

Permalink
Merge pull request econ-ark#936 from sbenthall/i920
Browse files Browse the repository at this point in the history
Remove "Now" from model variables
  • Loading branch information
sbenthall authored Feb 8, 2021
2 parents 0a0daf8 + fd82555 commit f880be6
Show file tree
Hide file tree
Showing 39 changed files with 262 additions and 251 deletions.
1 change: 1 addition & 0 deletions Documentation/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ interpolation for problems with CRRA utility. See [#888](https://github.com/econ
* Fix the return fields of `dcegm/calcCrossPoints`[#909](https://github.com/econ-ark/HARK/pull/909).
* Corrects location of constructor documentation to class string for Sphinx rendering [#908](https://github.com/econ-ark/HARK/pull/908)
* Adds a module for producing 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).
* 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)

#### Minor Changes
Expand Down
55 changes: 30 additions & 25 deletions HARK/ConsumptionSaving/ConsAggShockModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def reset(self):
"""
self.initializeSim()
self.state_now['aLvlNow'] = self.kInit * np.ones(self.AgentCount) # Start simulation near SS
self.state_now['aNrmNow'] = self.state_now['aLvlNow'] / self.state_now['pLvlNow'] # ???
self.state_now['aNrm'] = self.state_now['aLvlNow'] / self.state_now['pLvl'] # ???

def preSolve(self):
# AgentType.preSolve()
Expand Down Expand Up @@ -283,12 +283,12 @@ def simBirth(self, which_agents):
None
"""
IndShockConsumerType.simBirth(self, which_agents)
if "aLvlNow" in self.state_now and self.state_now["aLvlNow"] is not None:
self.state_now["aLvlNow"][which_agents] = (
self.state_now["aNrmNow"][which_agents] * self.state_now["pLvlNow"][which_agents]
if 'aLvl' in self.state_now and self.state_now['aLvl'] is not None:
self.state_now['aLvl'][which_agents] = (
self.state_now['aNrm'][which_agents] * self.state_now['pLvl'][which_agents]
)
else:
self.state_now["aLvlNow"] = self.state_now['aNrmNow'] * self.state_now['pLvlNow']
self.state_now['aLvl'] = self.state_now['aNrm'] * self.state_now['pLvl']

def simDeath(self):
"""
Expand Down Expand Up @@ -323,11 +323,11 @@ def simDeath(self):

# Divide up the wealth of those who die, giving it to those who survive
who_lives = np.logical_not(who_dies)
wealth_living = np.sum(self.state_now["aLvlNow"][who_lives])
wealth_dead = np.sum(self.state_now["aLvlNow"][who_dies])
wealth_living = np.sum(self.state_now['aLvl'][who_lives])
wealth_dead = np.sum(self.state_now['aLvl'][who_dies])
Ractuarial = 1.0 + wealth_dead / wealth_living
self.state_now['aNrmNow'][who_lives] = self.state_now['aNrmNow'][who_lives] * Ractuarial
self.state_now["aLvlNow"][who_lives] = self.state_now["aLvlNow"][who_lives] * Ractuarial
self.state_now['aNrm'][who_lives] = self.state_now['aNrm'][who_lives] * Ractuarial
self.state_now['aLvl'][who_lives] = self.state_now['aLvl'][who_lives] * Ractuarial
return who_dies

def getRfree(self):
Expand Down Expand Up @@ -360,10 +360,10 @@ def getShocks(self):
None
"""
IndShockConsumerType.getShocks(self) # Update idiosyncratic shocks
self.shocks["TranShkNow"] = (
self.shocks["TranShkNow"] * self.TranShkAggNow * self.wRteNow
self.shocks['TranShk'] = (
self.shocks['TranShk'] * self.TranShkAggNow * self.wRteNow
)
self.shocks["PermShkNow"] = self.shocks["PermShkNow"] * self.PermShkAggNow
self.shocks['PermShk'] = self.shocks['PermShk'] * self.PermShkAggNow

def getControls(self):
"""
Expand All @@ -382,12 +382,12 @@ def getControls(self):
MaggNow = self.getMaggNow()
for t in range(self.T_cycle):
these = t == self.t_cycle
cNrmNow[these] = self.solution[t].cFunc(self.state_now["mNrmNow"][these], MaggNow[these])
cNrmNow[these] = self.solution[t].cFunc(self.state_now['mNrm'][these], MaggNow[these])
MPCnow[these] = self.solution[t].cFunc.derivativeX(
self.state_now["mNrmNow"][these], MaggNow[these]
self.state_now['mNrm'][these], MaggNow[these]
) # Marginal propensity to consume

self.controls["cNrmNow"] = cNrmNow
self.controls['cNrm'] = cNrmNow
self.MPCnow = MPCnow
return None

Expand Down Expand Up @@ -599,8 +599,8 @@ def getShocks(self):
# Store the shocks in self
self.EmpNow = np.ones(self.AgentCount, dtype=bool)
self.EmpNow[TranShkNow == self.IncUnemp] = False
self.shocks["TranShkNow"] = TranShkNow * self.TranShkAggNow * self.wRteNow
self.shocks["PermShkNow"] = PermShkNow * self.PermShkAggNow
self.shocks['TranShk'] = TranShkNow * self.TranShkAggNow * self.wRteNow
self.shocks['PermShk'] = PermShkNow * self.PermShkAggNow

def getControls(self):
"""
Expand Down Expand Up @@ -632,15 +632,15 @@ def getControls(self):
for i in range(StateCount):
those = np.logical_and(these, MrkvBoolArray[i, :])
cNrmNow[those] = self.solution[t].cFunc[i](
self.state_now["mNrmNow"][those], MaggNow[those]
self.state_now['mNrm'][those], MaggNow[those]
)
# Marginal propensity to consume
MPCnow[those] = (
self.solution[t]
.cFunc[i]
.derivativeX(self.state_now["mNrmNow"][those], MaggNow[those])
.derivativeX(self.state_now['mNrm'][those], MaggNow[those])
)
self.controls["cNrmNow"] = cNrmNow
self.controls['cNrm'] = cNrmNow
self.MPCnow = MPCnow
return None

Expand Down Expand Up @@ -1875,7 +1875,7 @@ def __init__(self, agents=None, tolerance=0.0001, act_T=1200, **kwds):
Market.__init__(
self,
agents=agents,
reap_vars=["aLvlNow", "pLvlNow"],
reap_vars=['aLvl', 'pLvl'],
track_vars=["MaggNow", "AaggNow"],
dyn_vars=["AFunc"],
tolerance=tolerance,
Expand All @@ -1896,14 +1896,14 @@ def __init__(self, agents=None, tolerance=0.0001, act_T=1200, **kwds):
if not hasattr(self, "verbose"):
self.verbose = True

def millRule(self, aLvlNow, pLvlNow):
def millRule(self, aLvl, pLvl):
"""
Function to calculate the capital to labor ratio, interest factor, and
wage rate based on each agent's current state. Just calls calcRandW().
See documentation for calcRandW for more information.
"""
return self.calcRandW(aLvlNow, pLvlNow)
return self.calcRandW(aLvl, pLvl)

def calcDynamics(self, MaggNow, AaggNow):
"""
Expand Down Expand Up @@ -2651,14 +2651,19 @@ def makeMrkvHist(self):
self.MrkvNow_hist = MrkvNow_hist
self.act_T = act_T

def millRule(self, aLvlNow, pLvlNow):
def millRule(self, aLvl, pLvl):
"""
Function to calculate the capital to labor ratio, interest factor, and
wage rate based on each agent's current state. Just calls calcRandW()
and adds the Markov state index.
See documentation for calcRandW for more information.
Params
-------
aLvl : float
pLvl : float
Returns
-------
Mnow : float
Expand All @@ -2675,7 +2680,7 @@ def millRule(self, aLvlNow, pLvlNow):
Binary indicator for bad (0) or good (1) macroeconomic state.
"""
MrkvNow = self.MrkvNow_hist[self.Shk_idx]
temp = self.calcRandW(aLvlNow, pLvlNow)
temp = self.calcRandW(aLvl, pLvl)

return temp + (MrkvNow,)

Expand Down
30 changes: 15 additions & 15 deletions HARK/ConsumptionSaving/ConsGenIncProcessModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ class GenIncProcessConsumerType(IndShockConsumerType):
cFunc=cFunc_terminal_, mNrmMin=0.0, hNrm=0.0, MPCmin=1.0, MPCmax=1.0
)

state_vars = ["pLvlNow","mLvlNow","aLvlNow"]
state_vars = ['pLvl',"mLvl",'aLvl']

def __init__(self, cycles=0, **kwds):
params = init_explicit_perm_inc.copy()
Expand All @@ -915,12 +915,12 @@ def __init__(self, cycles=0, **kwds):
self.solveOnePeriod = makeOnePeriodOOSolver(ConsGenIncProcessSolver)

# a poststate?
self.state_now["aLvlNow"] = None
self.state_prev["aLvlNow"] = None
self.state_now['aLvl'] = None
self.state_prev['aLvl'] = None

# better way to do this...
self.state_now["mLvlNow"] = None
self.state_prev["mLvlNow"] = None
self.state_now["mLvl"] = None
self.state_prev["mLvl"] = None

def preSolve(self):
# AgentType.preSolve()
Expand Down Expand Up @@ -1100,10 +1100,10 @@ def simBirth(self, which_agents):
aNrmNow_new = Lognormal(
self.aNrmInitMean, self.aNrmInitStd, seed=self.RNG.randint(0, 2 ** 31 - 1)
).draw(N)
self.state_now['pLvlNow'][which_agents] = Lognormal(
self.state_now['pLvl'][which_agents] = Lognormal(
self.pLvlInitMean, self.pLvlInitStd, seed=self.RNG.randint(0, 2 ** 31 - 1)
).draw(N)
self.state_now['aLvlNow'][which_agents] = aNrmNow_new * self.state_now['pLvlNow'][which_agents]
self.state_now['aLvl'][which_agents] = aNrmNow_new * self.state_now['pLvl'][which_agents]
self.t_age[which_agents] = 0 # How many periods since each agent was born
self.t_cycle[
which_agents
Expand All @@ -1124,7 +1124,7 @@ def transition(self):
pLvlNow
mLvlNow
"""
aLvlPrev = self.state_prev['aLvlNow']
aLvlPrev = self.state_prev['aLvl']
RfreeNow = self.getRfree()

# Calculate new states: normalized market resources
Expand All @@ -1134,16 +1134,16 @@ def transition(self):
for t in range(self.T_cycle):
these = t == self.t_cycle
pLvlNow[these] = (
self.pLvlNextFunc[t - 1](self.state_prev['pLvlNow'][these])
* self.shocks["PermShkNow"][these]
self.pLvlNextFunc[t - 1](self.state_prev['pLvl'][these])
* self.shocks['PermShk'][these]
)

#state value
bLvlNow = RfreeNow * aLvlPrev # Bank balances before labor income

# Market resources after income - state value
mLvlNow = bLvlNow + \
self.shocks["TranShkNow"] * \
self.shocks['TranShk'] * \
pLvlNow

return (pLvlNow,
Expand All @@ -1168,12 +1168,12 @@ def getControls(self):
for t in range(self.T_cycle):
these = t == self.t_cycle
cLvlNow[these] = self.solution[t].cFunc(
self.state_now["mLvlNow"][these], self.state_now["pLvlNow"][these]
self.state_now["mLvl"][these], self.state_now['pLvl'][these]
)
MPCnow[these] = self.solution[t].cFunc.derivativeX(
self.state_now["mLvlNow"][these], self.state_now["pLvlNow"][these]
self.state_now["mLvl"][these], self.state_now['pLvl'][these]
)
self.controls["cLvlNow"] = cLvlNow
self.controls["cLvl"] = cLvlNow
self.MPCnow = MPCnow

def getPostStates(self):
Expand All @@ -1189,7 +1189,7 @@ def getPostStates(self):
-------
None
"""
self.state_now['aLvlNow'] = self.state_now["mLvlNow"] - self.controls["cLvlNow"]
self.state_now['aLvl'] = self.state_now["mLvl"] - self.controls["cLvl"]
# moves now to prev
AgentType.getPostStates(self)

Expand Down
42 changes: 21 additions & 21 deletions HARK/ConsumptionSaving/ConsIndShockModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -1392,7 +1392,7 @@ class PerfForesightConsumerType(AgentType):
)
time_vary_ = ["LivPrb", "PermGroFac"]
time_inv_ = ["CRRA", "Rfree", "DiscFac", "MaxKinks", "BoroCnstArt"]
state_vars = ['pLvlNow', 'PlvlAggNow', 'bNrmNow', 'mNrmNow', "aNrmNow"]
state_vars = ['pLvl', 'PlvlAgg', 'bNrm', 'mNrm', "aNrm"]
shock_vars_ = []

def __init__(self, cycles=1, verbose=1, quiet=False, **kwds):
Expand Down Expand Up @@ -1487,7 +1487,7 @@ def unpackcFunc(self):

def initializeSim(self):
self.PermShkAggNow = self.PermGroFacAgg # This never changes during simulation
self.state_now['PlvlAggNow'] = 1.0
self.state_now['PlvlAgg'] = 1.0
AgentType.initializeSim(self)

def simBirth(self, which_agents):
Expand All @@ -1507,16 +1507,16 @@ def simBirth(self, which_agents):
"""
# Get and store states for newly born agents
N = np.sum(which_agents) # Number of new consumers to make
self.state_now["aNrmNow"][which_agents] = Lognormal(
self.state_now['aNrm'][which_agents] = Lognormal(
mu=self.aNrmInitMean,
sigma=self.aNrmInitStd,
seed=self.RNG.randint(0, 2 ** 31 - 1),
).draw(N)
# why is a now variable set here? Because it's an aggregate.
pLvlInitMeanNow = self.pLvlInitMean + np.log(
self.state_now["PlvlAggNow"]
self.state_now['PlvlAgg']
) # Account for newer cohorts having higher permanent income
self.state_now["pLvlNow"][which_agents] = Lognormal(
self.state_now['pLvl'][which_agents] = Lognormal(
pLvlInitMeanNow,
self.pLvlInitStd,
seed=self.RNG.randint(0, 2 ** 31 - 1)
Expand Down Expand Up @@ -1570,10 +1570,10 @@ def getShocks(self):
None
"""
PermGroFac = np.array(self.PermGroFac)
self.shocks["PermShkNow"] = PermGroFac[
self.shocks['PermShk'] = PermGroFac[
self.t_cycle - 1
] # cycle time has already been advanced
self.shocks["TranShkNow"] = np.ones(self.AgentCount)
self.shocks['TranShk'] = np.ones(self.AgentCount)

def getRfree(self):
"""
Expand All @@ -1592,16 +1592,16 @@ def getRfree(self):
return RfreeNow

def transition(self):
pLvlPrev = self.state_prev['pLvlNow']
aNrmPrev = self.state_prev['aNrmNow']
pLvlPrev = self.state_prev['pLvl']
aNrmPrev = self.state_prev['aNrm']
RfreeNow = self.getRfree()

# Calculate new states: normalized market resources and permanent income level
pLvlNow = pLvlPrev*self.shocks['PermShkNow'] # Updated permanent income level
PlvlAggNow = self.state_prev['PlvlAggNow']*self.PermShkAggNow # Updated aggregate permanent productivity level
ReffNow = RfreeNow/self.shocks['PermShkNow'] # "Effective" interest factor on normalized assets
pLvlNow = pLvlPrev*self.shocks['PermShk'] # Updated permanent income level
PlvlAggNow = self.state_prev['PlvlAgg']*self.PermShkAggNow # Updated aggregate permanent productivity level
ReffNow = RfreeNow/self.shocks['PermShk'] # "Effective" interest factor on normalized assets
bNrmNow = ReffNow*aNrmPrev # Bank balances before labor income
mNrmNow = bNrmNow + self.shocks['TranShkNow'] # Market resources after income
mNrmNow = bNrmNow + self.shocks['TranShk'] # Market resources after income

return pLvlNow, PlvlAggNow, bNrmNow, mNrmNow, None

Expand All @@ -1623,9 +1623,9 @@ def getControls(self):
for t in range(self.T_cycle):
these = t == self.t_cycle
cNrmNow[these], MPCnow[these] = self.solution[t].cFunc.eval_with_derivative(
self.state_now['mNrmNow'][these]
self.state_now['mNrm'][these]
)
self.controls['cNrmNow'] = cNrmNow
self.controls['cNrm'] = cNrmNow

# MPCnow is not really a control
self.MPCnow = MPCnow
Expand All @@ -1644,9 +1644,9 @@ def getPostStates(self):
None
"""
# should this be "Now", or "Prev"?!?
self.state_now['aNrmNow'] = self.state_now['mNrmNow'] - self.controls['cNrmNow']
self.state_now['aNrm'] = self.state_now['mNrm'] - self.controls['cNrm']
# Useful in some cases to precalculate asset level
self.state_now['aLvlNow'] = self.state_now['aNrmNow'] * self.state_now['pLvlNow']
self.state_now['aLvl'] = self.state_now['aNrm'] * self.state_now['pLvl']

# moves now to prev
super().getPostStates()
Expand Down Expand Up @@ -1865,7 +1865,7 @@ class IndShockConsumerType(PerfForesightConsumerType):
time_inv_.remove(
"MaxKinks"
) # This is in the PerfForesight model but not ConsIndShock
shock_vars_ = ["PermShkNow", "TranShkNow"]
shock_vars_ = ['PermShk', 'TranShk']

def __init__(self, cycles=1, verbose=1, quiet=False, **kwds):
params = init_idiosyncratic_shocks.copy()
Expand Down Expand Up @@ -2014,8 +2014,8 @@ def getShocks(self):
# Store the shocks in self
self.EmpNow = np.ones(self.AgentCount, dtype=bool)
self.EmpNow[TranShkNow == self.IncUnemp] = False
self.shocks["PermShkNow"] = PermShkNow
self.shocks["TranShkNow"] = TranShkNow
self.shocks['PermShk'] = PermShkNow
self.shocks['TranShk'] = TranShkNow

def calcBoundingValues(self):
"""
Expand Down Expand Up @@ -2701,7 +2701,7 @@ def getRfree(self):
Array of size self.AgentCount with risk free interest rate for each agent.
"""
RfreeNow = self.Rboro * np.ones(self.AgentCount)
RfreeNow[self.state_prev['aNrmNow'] > 0] = self.Rsave
RfreeNow[self.state_prev['aNrm'] > 0] = self.Rsave
return RfreeNow

def checkConditions(self):
Expand Down
Loading

0 comments on commit f880be6

Please sign in to comment.