Skip to content

Commit

Permalink
Merge pull request #570 from sbenthall/i569-timing
Browse files Browse the repository at this point in the history
Removing time flipping and time flow state
  • Loading branch information
mnwhite authored Apr 23, 2020
2 parents bc872eb + 4f325e2 commit 78d1981
Show file tree
Hide file tree
Showing 19 changed files with 808 additions and 287 deletions.
4 changes: 2 additions & 2 deletions HARK/ConsumptionSaving/ConsAggShockModel.py
Original file line number Diff line number Diff line change
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
21 changes: 2 additions & 19 deletions HARK/ConsumptionSaving/ConsGenIncProcessModel.py
Original file line number Diff line number Diff line change
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,8 +1107,6 @@ 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
Expand Down Expand Up @@ -1163,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 Down Expand Up @@ -1283,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 @@ -1335,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 @@ -1353,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 @@ -1365,5 +1350,3 @@ def updatepLvlNextFunc(self):

self.pLvlNextFunc = pLvlNextFunc
self.addToTimeVary('pLvlNextFunc')
if not orig_time:
self.timeRev()
22 changes: 7 additions & 15 deletions HARK/ConsumptionSaving/ConsIndShockModel.py
Original file line number Diff line number Diff line change
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 @@ -2047,7 +2045,6 @@ class IndShockConsumerType(PerfForesightConsumerType):

def __init__(self,
cycles=1,
time_flow=True,
verbose=False,
quiet=False,
**kwds):
Expand All @@ -2074,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 @@ -2096,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 @@ -2560,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 @@ -2570,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 @@ -2581,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 @@ -2903,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 @@ -2920,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

52 changes: 5 additions & 47 deletions HARK/ConsumptionSaving/ConsLaborModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ def solveConsLaborIntMarg(solution_next,PermShkDstn,TranShkDstn,LivPrb,DiscFac,C

class LaborIntMargConsumerType(IndShockConsumerType):

'''
'''
A class representing agents who make a decision each period about how much
to consume vs save and how much labor to supply (as a fraction of their time).
They get CRRA utility from a composite good x_t = c_t*z_t^alpha, and discount
Expand All @@ -255,7 +255,7 @@ class LaborIntMargConsumerType(IndShockConsumerType):
time_vary_ += ['WageRte']
time_inv_ = copy(IndShockConsumerType.time_inv_)

def __init__(self,cycles=1,time_flow=True,**kwds):
def __init__(self,cycles=1,**kwds):
'''
Instantiate a new consumer type with given data.
See ConsumerParameters.init_labor_intensive for a dictionary of
Expand All @@ -265,8 +265,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 @@ -275,7 +273,7 @@ def __init__(self,cycles=1,time_flow=True,**kwds):
params = init_labor_intensive.copy()
params.update(kwds)

IndShockConsumerType.__init__(self,cycles = cycles,time_flow=time_flow,**params)
IndShockConsumerType.__init__(self,cycles = cycles,**params)
self.pseudo_terminal = False
self.solveOnePeriod = solveConsLaborIntMarg
self.update()
Expand Down Expand Up @@ -318,13 +316,8 @@ def updateLbrCost(self):
for n in range(N):
LbrCostBase += Coeffs[n]*age_vec**n
LbrCost = np.exp(LbrCostBase)
time_orig = self.time_flow
self.timeFwd()
self.LbrCost = LbrCost.tolist()
self.addToTimeVary('LbrCost')
if not time_orig:
self.timeRev()


def calcBoundingValues(self):
'''
Expand Down Expand Up @@ -456,18 +449,11 @@ def updateTranShkGrid(self):
-------
None
'''
time_orig=self.time_flow
self.timeFwd()

TranShkGrid = [] # Create an empty list for TranShkGrid that will be updated
for t in range(self.T_cycle):
TranShkGrid.append(self.TranShkDstn[t][1]) # Update/ Extend the list of TranShkGrid with the TranShkVals for each TranShkPrbs
self.TranShkGrid = TranShkGrid # Save that list in self (time-varying)
self.addToTimeVary('TranShkGrid') # Run the method addToTimeVary from AgentType to add TranShkGrid as one parameter of time_vary list

if not time_orig:
self.timeRev()


def updateSolutionTerminal(self):
'''
Expand All @@ -481,11 +467,8 @@ def updateSolutionTerminal(self):
Returns
-------
None
'''
if self.time_flow: # To make sure we pick the last element of the list, depending on the direction time is flowing
t=-1
else:
t=0
'''
t=-1
TranShkGrid = self.TranShkGrid[t]
LbrCost = self.LbrCost[t]
WageRte = self.WageRte[t]
Expand Down Expand Up @@ -613,28 +596,3 @@ def plotLbrFunc(self,t,bMin=None,bMax=None,ShkSet=None):
plt.xlabel('Beginning of period bank balances')
plt.ylabel('Labor supply')
plt.show()


# Make a default dictionary for the intensive margin labor supply model
init_labor_intensive = copy(init_idiosyncratic_shocks)
init_labor_intensive ['LbrCostCoeffs'] = [-1.0]
init_labor_intensive ['WageRte'] = [1.0]
init_labor_intensive['IncUnemp'] = 0.0
init_labor_intensive['TranShkCount'] = 15 # Crank up permanent shock count - Number of points in discrete approximation to transitory income shocks
init_labor_intensive['PermShkCount'] = 16 # Crank up permanent shock count
init_labor_intensive ['aXtraCount'] = 200 # May be important to have a larger number of gridpoints (than 48 initially)
init_labor_intensive ['aXtraMax'] = 80.
init_labor_intensive ['BoroCnstArt'] = None

# Make a dictionary for intensive margin labor supply model with finite lifecycle
init_labor_lifecycle = init_labor_intensive.copy()
init_labor_lifecycle['PermGroFac'] = [1.01,1.01,1.01,1.01,1.01,1.02,1.02,1.02,1.02,1.02]
init_labor_lifecycle['PermShkStd'] = [0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1]
init_labor_lifecycle['TranShkStd'] = [0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1]
init_labor_lifecycle['LivPrb'] = [0.99,0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1] # Living probability decreases as time moves forward.
init_labor_lifecycle['WageRte'] = [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0] # Wage rate in a lifecycle
init_labor_lifecycle['LbrCostCoeffs'] = [-2.0, 0.4] # Assume labor cost coeffs is a polynomial of degree 1
init_labor_lifecycle['T_cycle'] = 10
#init_labor_lifecycle['T_retire'] = 7 # IndexError at line 774 in interpolation.py.
init_labor_lifecycle['T_age'] = 11 # Make sure that old people die at terminal age and don't turn into newborns!

6 changes: 4 additions & 2 deletions HARK/ConsumptionSaving/ConsMarkovModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -683,8 +683,10 @@ class MarkovConsumerType(IndShockConsumerType):
time_vary_ = IndShockConsumerType.time_vary_ + ['MrkvArray']
shock_vars_ = IndShockConsumerType.shock_vars_ + ['MrkvNow']

def __init__(self,cycles=1,time_flow=True,**kwds):
IndShockConsumerType.__init__(self,cycles=1,time_flow=True,**kwds)
def __init__(self,
cycles=1,
**kwds):
IndShockConsumerType.__init__(self,cycles=1,**kwds)
self.solveOnePeriod = _solveConsMarkov
self.poststate_vars += ['MrkvNow']
if not hasattr(self, 'global_markov'):
Expand Down
15 changes: 4 additions & 11 deletions HARK/ConsumptionSaving/ConsMedModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ class MedShockConsumerType(PersistentShockConsumerType):
'''
shock_vars_ = PersistentShockConsumerType.shock_vars_ + ['MedShkNow']

def __init__(self,cycles=0,time_flow=True,**kwds):
def __init__(self,cycles=0,**kwds):
'''
Instantiate a new ConsumerType with given data, and construct objects
to be used during solution (income distribution, assets grid, etc).
Expand All @@ -545,8 +545,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 Down Expand Up @@ -624,14 +622,9 @@ def updateSolutionTerminal(self):
None
'''
# Take last period data, whichever way time is flowing
if self.time_flow:
MedPrice = self.MedPrice[-1]
MedShkVals = self.MedShkDstn[-1][1]
MedShkPrbs = self.MedShkDstn[-1][0]
else:
MedPrice = self.MedPrice[0]
MedShkVals = self.MedShkDstn[0][1]
MedShkPrbs = self.MedShkDstn[0][0]
MedPrice = self.MedPrice[-1]
MedShkVals = self.MedShkDstn[-1][1]
MedShkPrbs = self.MedShkDstn[-1][0]

# Initialize grids of medical need shocks, market resources, and optimal consumption
MedShkGrid = MedShkVals
Expand Down
Loading

0 comments on commit 78d1981

Please sign in to comment.