Skip to content

Commit

Permalink
Merge branch 'master' into i583-bl
Browse files Browse the repository at this point in the history
  • Loading branch information
sbenthall committed Apr 23, 2020
2 parents d54730f + fc75df4 commit c5be5a5
Show file tree
Hide file tree
Showing 24 changed files with 1,278 additions and 625 deletions.
2 changes: 1 addition & 1 deletion Documentation/packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Follow the directions within https://packaging.python.org/tutorials/packaging-pr
Deactivate the virtualenv, and make or use a different Python 2.7 virtualenv to test that you can `pip install` the `sdist` you've just made. One thing you can do to quickly verify that the package installs OK:

`>>> import HARK.simulation`
`>>> HARK.simulation.drawBernoulli(5)`
`>>> HARK.simulation.Bernoulli().draw(5)`

You should get something like:

Expand Down
8 changes: 4 additions & 4 deletions HARK/ConsumptionSaving/ConsAggShockModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
VariableLowerBoundFunc2D, BilinearInterp, LowerEnvelope2D, UpperEnvelope
from HARK.utilities import CRRAutility, CRRAutilityP, CRRAutilityPP, CRRAutilityP_inv,\
CRRAutility_invP, CRRAutility_inv
from HARK.simulation import drawUniform
from HARK.distribution import Uniform
from HARK.ConsumptionSaving.ConsIndShockModel import ConsumerSolution, IndShockConsumerType, init_idiosyncratic_shocks
from HARK import HARKobject, Market, AgentType
from copy import deepcopy
Expand Down Expand Up @@ -89,7 +89,7 @@ class AggShockConsumerType(IndShockConsumerType):
evolves over time and take aggregate shocks into account when making their
decision about how much to consume.
'''
def __init__(self, time_flow=True, **kwds):
def __init__(self, **kwds):
'''
Make a new instance of AggShockConsumerType, an extension of
IndShockConsumerType. Sets appropriate solver and input lists.
Expand All @@ -98,7 +98,7 @@ def __init__(self, time_flow=True, **kwds):
params.update(kwds)

AgentType.__init__(self, solution_terminal=deepcopy(IndShockConsumerType.solution_terminal_),
time_flow=time_flow, pseudo_terminal=False, **params)
pseudo_terminal=False, **params)

# Add consumer-type specific objects, copying to create independent versions
self.time_vary = deepcopy(IndShockConsumerType.time_vary_)
Expand Down Expand Up @@ -1629,7 +1629,7 @@ def makeMrkvHist(self):

# Add histories until each state has been visited at least state_T_min times
while go:
draws = drawUniform(N=self.act_T_orig, seed=loops)
draws = Uniform().draw(N=self.act_T_orig, seed=loops)
for s in range(draws.size): # Add act_T_orig more periods
MrkvNow_hist[t] = MrkvNow
MrkvNow = np.searchsorted(cutoffs[MrkvNow, :], draws[s])
Expand Down
44 changes: 16 additions & 28 deletions HARK/ConsumptionSaving/ConsGenIncProcessModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from HARK.utilities import CRRAutility, CRRAutilityP, CRRAutilityPP, CRRAutilityP_inv, \
CRRAutility_invP, CRRAutility_inv, CRRAutilityP_invP,\
getPercentiles
from HARK.simulation import drawLognormal, drawUniform
from HARK.distribution import Lognormal, Uniform
from HARK.ConsumptionSaving.ConsIndShockModel import ConsIndShockSetup, ConsumerSolution, IndShockConsumerType, init_idiosyncratic_shocks

__all__ = ['ValueFunc2D', 'MargValueFunc2D', 'MargMargValueFunc2D', 'pLvlFuncAR1',
Expand Down Expand Up @@ -985,7 +985,7 @@ class GenIncProcessConsumerType(IndShockConsumerType):
solution_terminal_ = ConsumerSolution(cFunc=cFunc_terminal_, mNrmMin=0.0, hNrm=0.0, MPCmin=1.0, MPCmax=1.0)
poststate_vars_ = ['aLvlNow', 'pLvlNow']

def __init__(self, cycles=0, time_flow=True, **kwds):
def __init__(self, cycles=0, **kwds):
'''
Instantiate a new ConsumerType with given data.
See ConsumerParameters.init_explicit_perm_inc for a dictionary of the
Expand All @@ -995,8 +995,6 @@ def __init__(self, cycles=0, time_flow=True, **kwds):
----------
cycles : int
Number of times the sequence of periods should be solved.
time_flow : boolean
Whether time is currently "flowing" forward for this instance.
Returns
-------
Expand All @@ -1006,7 +1004,7 @@ def __init__(self, cycles=0, time_flow=True, **kwds):
params.update(kwds)

# Initialize a basic ConsumerType
IndShockConsumerType.__init__(self, cycles=cycles, time_flow=time_flow, **params)
IndShockConsumerType.__init__(self, cycles=cycles, **params)
self.solveOnePeriod = solveConsGenIncProcess # idiosyncratic shocks solver with explicit persistent income

def preSolve(self):
Expand Down Expand Up @@ -1109,13 +1107,12 @@ def updatepLvlGrid(self):
-------
None
'''
orig_time = self.time_flow
self.timeFwd()
LivPrbAll = np.array(self.LivPrb)

# Simulate the distribution of persistent income levels by t_cycle in a lifecycle model
if self.cycles == 1:
pLvlNow = drawLognormal(self.AgentCount, mu=self.pLvlInitMean, sigma=self.pLvlInitStd, seed=31382)
pLvlNow = Lognormal(self.pLvlInitMean,
sigma=self.pLvlInitStd,).draw(self.AgentCount, seed=31382)
pLvlGrid = [] # empty list of time-varying persistent income grids
# Calculate distribution of persistent income in each period of lifecycle
for t in range(len(self.PermShkStd)):
Expand All @@ -1129,14 +1126,15 @@ def updatepLvlGrid(self):
# Calculate "stationary" distribution in infinite horizon (might vary across periods of cycle)
elif self.cycles == 0:
T_long = 1000 # Number of periods to simulate to get to "stationary" distribution
pLvlNow = drawLognormal(self.AgentCount, mu=self.pLvlInitMean, sigma=self.pLvlInitStd, seed=31382)
pLvlNow = Lognormal(mu=self.pLvlInitMean,
sigma=self.pLvlInitStd).draw(self.AgentCount, seed=31382)
t_cycle = np.zeros(self.AgentCount, dtype=int)
for t in range(T_long):
LivPrb = LivPrbAll[t_cycle] # Determine who dies and replace them with newborns
draws = drawUniform(self.AgentCount, seed=t)
draws = Uniform().draw(self.AgentCount, seed=t)
who_dies = draws > LivPrb
pLvlNow[who_dies] = drawLognormal(np.sum(who_dies), mu=self.pLvlInitMean,
sigma=self.pLvlInitStd, seed=t+92615)
pLvlNow[who_dies] = Lognormal(self.pLvlInitMean,
self.pLvlInitStd).draw(np.sum(who_dies), seed=t+92615)
t_cycle[who_dies] = 0

for j in range(self.T_cycle): # Update persistent income
Expand All @@ -1161,8 +1159,6 @@ def updatepLvlGrid(self):
# Store the result and add attribute to time_vary
self.pLvlGrid = pLvlGrid
self.addToTimeVary('pLvlGrid')
if not orig_time:
self.timeRev()

def simBirth(self, which_agents):
'''
Expand All @@ -1181,10 +1177,13 @@ def simBirth(self, which_agents):
'''
# Get and store states for newly born agents
N = np.sum(which_agents) # Number of new consumers to make
aNrmNow_new = drawLognormal(N, mu=self.aNrmInitMean, sigma=self.aNrmInitStd,
aNrmNow_new = Lognormal(self.aNrmInitMean,
self.aNrmInitStd).draw(
N,
seed=self.RNG.randint(0, 2**31-1))
self.pLvlNow[which_agents] = drawLognormal(N, mu=self.pLvlInitMean, sigma=self.pLvlInitStd,
seed=self.RNG.randint(0, 2**31-1))
self.pLvlNow[which_agents] = Lognormal(self.pLvlInitMean,
self.pLvlInitStd).draw(N,
seed=self.RNG.randint(0, 2**31-1))
self.aLvlNow[which_agents] = aNrmNow_new*self.pLvlNow[which_agents]
self.t_age[which_agents] = 0 # How many periods since each agent was born
self.t_cycle[which_agents] = 0 # Which period of the cycle each agent is currently in
Expand Down Expand Up @@ -1278,18 +1277,12 @@ def updatepLvlNextFunc(self):
-------
None
'''
orig_time = self.time_flow
self.timeFwd()

pLvlNextFunc = []
for t in range(self.T_cycle):
pLvlNextFunc.append(LinearInterp(np.array([0., 1.]), np.array([0., self.PermGroFac[t]])))

self.pLvlNextFunc = pLvlNextFunc
self.addToTimeVary('pLvlNextFunc')
if not orig_time:
self.timeRev()


###############################################################################

Expand Down Expand Up @@ -1330,7 +1323,6 @@ def __init__(self, cycles=0, time_flow=True, **kwds):

GenIncProcessConsumerType.__init__(self,
cycles=cycles,
time_flow=time_flow,
**params)

def updatepLvlNextFunc(self):
Expand All @@ -1348,8 +1340,6 @@ def updatepLvlNextFunc(self):
-------
None
'''
orig_time = self.time_flow
self.timeFwd()

pLvlNextFunc = []
pLogMean = self.pLvlInitMean # Initial mean (log) persistent income
Expand All @@ -1360,5 +1350,3 @@ def updatepLvlNextFunc(self):

self.pLvlNextFunc = pLvlNextFunc
self.addToTimeVary('pLvlNextFunc')
if not orig_time:
self.timeRev()
32 changes: 13 additions & 19 deletions HARK/ConsumptionSaving/ConsIndShockModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from HARK import AgentType, Solution, NullFunc, HARKobject
from HARK.utilities import warnings # Because of "patch" to warnings modules
from HARK.interpolation import CubicInterp, LowerEnvelope, LinearInterp
from HARK.simulation import drawLognormal, drawUniform
from HARK.distribution import Lognormal, Uniform
from HARK.distribution import DiscreteDistribution, approxMeanOneLognormal, addDiscreteOutcomeConstantMean, combineIndepDstns
from HARK.utilities import makeGridExpMult, CRRAutility, CRRAutilityP, \
CRRAutilityPP, CRRAutilityP_inv, CRRAutility_invP, CRRAutility_inv, \
Expand Down Expand Up @@ -1621,7 +1621,6 @@ class PerfForesightConsumerType(AgentType):

def __init__(self,
cycles=1,
time_flow=True,
verbose=False,
quiet=False,
**kwds):
Expand All @@ -1634,8 +1633,6 @@ def __init__(self,
----------
cycles : int
Number of times the sequence of periods should be solved.
time_flow : boolean
Whether time is currently "flowing" forward for this instance.
Returns
-------
Expand All @@ -1648,7 +1645,8 @@ def __init__(self,

# Initialize a basic AgentType
AgentType.__init__(self,solution_terminal=deepcopy(self.solution_terminal_),
cycles=cycles,time_flow=time_flow,pseudo_terminal=False,**kwds)
cycles=cycles,
pseudo_terminal=False,**kwds)

# Add consumer-type specific objects, copying to create independent versions
self.time_vary = deepcopy(self.time_vary_)
Expand Down Expand Up @@ -1745,9 +1743,11 @@ 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.aNrmNow[which_agents] = drawLognormal(N,mu=self.aNrmInitMean,sigma=self.aNrmInitStd,seed=self.RNG.randint(0,2**31-1))
self.aNrmNow[which_agents] = Lognormal(mu=self.aNrmInitMean,
sigma=self.aNrmInitStd).draw(N,seed=self.RNG.randint(0,2**31-1))
pLvlInitMeanNow = self.pLvlInitMean + np.log(self.PlvlAggNow) # Account for newer cohorts having higher permanent income
self.pLvlNow[which_agents] = drawLognormal(N,mu=pLvlInitMeanNow,sigma=self.pLvlInitStd,seed=self.RNG.randint(0,2**31-1))
self.pLvlNow[which_agents] = Lognormal(pLvlInitMeanNow,
self.pLvlInitStd,).draw(N,seed=self.RNG.randint(0,2**31-1))
self.t_age[which_agents] = 0 # How many periods since each agent was born
self.t_cycle[which_agents] = 0 # Which period of the cycle each agent is currently in
return None
Expand All @@ -1769,7 +1769,7 @@ def simDeath(self):
# Determine who dies
DiePrb_by_t_cycle = 1.0 - np.asarray(self.LivPrb)
DiePrb = DiePrb_by_t_cycle[self.t_cycle-1] # Time has already advanced, so look back one
DeathShks = drawUniform(N=self.AgentCount,seed=self.RNG.randint(0,2**31-1))
DeathShks = Uniform().draw(N=self.AgentCount,seed=self.RNG.randint(0,2**31-1))
which_agents = DeathShks < DiePrb
if self.T_age is not None: # Kill agents that have lived for too many periods
too_old = self.t_age >= self.T_age
Expand Down Expand Up @@ -2045,7 +2045,6 @@ class IndShockConsumerType(PerfForesightConsumerType):

def __init__(self,
cycles=1,
time_flow=True,
verbose=False,
quiet=False,
**kwds):
Expand All @@ -2072,7 +2071,6 @@ def __init__(self,
# Initialize a basic AgentType
PerfForesightConsumerType.__init__(self,
cycles=cycles,
time_flow=time_flow,
verbose=verbose,
quiet=quiet,
**params)
Expand All @@ -2094,15 +2092,11 @@ def updateIncomeProcess(self):
-----------
none
'''
original_time = self.time_flow
self.timeFwd()
IncomeDstn, PermShkDstn, TranShkDstn = constructLognormalIncomeProcessUnemployment(self)
self.IncomeDstn = IncomeDstn
self.PermShkDstn = PermShkDstn
self.TranShkDstn = TranShkDstn
self.addToTimeVary('IncomeDstn','PermShkDstn','TranShkDstn')
if not original_time:
self.timeRev()

def updateAssetsGrid(self):
'''
Expand Down Expand Up @@ -2558,7 +2552,7 @@ class KinkedRconsumerType(IndShockConsumerType):
time_inv_.remove('Rfree')
time_inv_ += ['Rboro', 'Rsave']

def __init__(self,cycles=1,time_flow=True,**kwds):
def __init__(self,cycles=1,**kwds):
'''
Instantiate a new ConsumerType with given data.
See ConsumerParameters.init_kinked_R for a dictionary of
Expand All @@ -2568,8 +2562,6 @@ def __init__(self,cycles=1,time_flow=True,**kwds):
----------
cycles : int
Number of times the sequence of periods should be solved.
time_flow : boolean
Whether time is currently "flowing" forward for this instance.
Returns
-------
Expand All @@ -2579,7 +2571,9 @@ def __init__(self,cycles=1,time_flow=True,**kwds):
params.update(kwds)

# Initialize a basic AgentType
PerfForesightConsumerType.__init__(self,cycles=cycles,time_flow=time_flow,**params)
PerfForesightConsumerType.__init__(self,
cycles=cycles,
**params)

# Add consumer-type specific objects, copying to create independent versions
self.solveOnePeriod = solveConsKinkedR # kinked R solver
Expand Down Expand Up @@ -2901,6 +2895,7 @@ def constructAssetsGrid(parameters):

return aXtraGrid


# Make a dictionary to specify a lifecycle consumer with a finite horizon
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]
Expand All @@ -2918,4 +2913,3 @@ def constructAssetsGrid(parameters):
init_cyclical['TranShkStd'] = [0.1,0.1,0.1,0.1]
init_cyclical['LivPrb'] = 4*[0.98]
init_cyclical['T_cycle'] = 4

Loading

0 comments on commit c5be5a5

Please sign in to comment.