From 98fd4a453397cfc8f37c758f486ef6471d203d5e Mon Sep 17 00:00:00 2001 From: sb Date: Tue, 21 Jul 2020 12:30:45 -0400 Subject: [PATCH 01/11] storing sow_var states and initial values in namespace --- HARK/ConsumptionSaving/ConsAggShockModel.py | 41 +++++++++++++++------ HARK/core.py | 33 ++++++++++++----- 2 files changed, 52 insertions(+), 22 deletions(-) diff --git a/HARK/ConsumptionSaving/ConsAggShockModel.py b/HARK/ConsumptionSaving/ConsAggShockModel.py index 701a9d580..d172345c5 100644 --- a/HARK/ConsumptionSaving/ConsAggShockModel.py +++ b/HARK/ConsumptionSaving/ConsAggShockModel.py @@ -988,11 +988,12 @@ def __init__(self, ''' agents = agents if agents is not None else list() params = init_cobb_douglas.copy() + params['sow_vars'] = ['MaggNow', 'AaggNow', 'RfreeNow', + 'wRteNow', 'PermShkAggNow', + 'TranShkAggNow', 'KtoLnow'] params.update(kwds) Market.__init__(self, agents=agents, - sow_vars=['MaggNow', 'AaggNow', 'RfreeNow', - 'wRteNow', 'PermShkAggNow', 'TranShkAggNow', 'KtoLnow'], reap_vars=['aLvlNow', 'pLvlNow'], track_vars=['MaggNow', 'AaggNow'], dyn_vars=['AFunc'], @@ -1053,13 +1054,14 @@ def update(self): self.convertKtoY = lambda KtoY: KtoY**(1.0/(1.0 - self.CapShare)) # converts K/Y to K/L self.Rfunc = lambda k: (1.0 + self.CapShare*k**(self.CapShare-1.0) - self.DeprFac) self.wFunc = lambda k: ((1.0-self.CapShare)*k**(self.CapShare)) - self.KtoLnow_init = self.kSS - self.MaggNow_init = self.kSS - self.AaggNow_init = self.kSS - self.RfreeNow_init = self.Rfunc(self.kSS) - self.wRteNow_init = self.wFunc(self.kSS) - self.PermShkAggNow_init = 1.0 - self.TranShkAggNow_init = 1.0 + + self.sow_init['KtoLnow'] = self.kSS + self.sow_init['MaggNow'] = self.kSS + self.sow_init['AaggNow'] = self.kSS + self.sow_init['RfreeNow'] = self.Rfunc(self.kSS) + self.sow_init['wRteNow'] = self.wFunc(self.kSS) + self.sow_init['PermShkAggNow'] = 1.0 + self.sow_init['TranShkAggNow'] = 1.0 self.makeAggShkDstn() self.AFunc = AggregateSavingRule(self.intercept_prev, self.slope_prev) @@ -1436,6 +1438,15 @@ def __init__(self, agents=None, tolerance=0.0001, act_T=1200, + sow_vars=['MaggNow', + 'AaggNow', + 'RfreeNow', + 'wRteNow', + 'PermShkAggNow', + 'TranShkAggNow', + 'KtoLnow', + 'MrkvNow' # This one is new + ], **kwds): ''' Make a new instance of CobbDouglasMarkovEconomy by filling in attributes @@ -1460,8 +1471,14 @@ def __init__(self, params = init_mrkv_cobb_douglas.copy() params.update(kwds) - CobbDouglasEconomy.__init__(self, agents=agents, tolerance=tolerance, act_T=act_T, **params) - self.sow_vars.append('MrkvNow') + CobbDouglasEconomy.__init__(self, + agents=agents, + tolerance=tolerance, + act_T=act_T, + sow_vars = sow_vars, + **params) + + self.sow_init['MrkvNow'] = params['MrkvNow_init'] def update(self): ''' @@ -1622,7 +1639,7 @@ def makeMrkvHist(self): cutoffs = np.cumsum(self.MrkvArray, axis=1) loops = 0 go = True - MrkvNow = self.MrkvNow_init + MrkvNow = self.sow_init['MrkvNow'] t = 0 StateCount = self.MrkvArray.shape[0] diff --git a/HARK/core.py b/HARK/core.py index 269f8b926..3538b1765 100644 --- a/HARK/core.py +++ b/HARK/core.py @@ -12,6 +12,7 @@ from builtins import str from builtins import range from builtins import object +from collections import OrderedDict import sys import os from distutils.dir_util import copy_tree @@ -944,6 +945,15 @@ def __init__(self, agents=None, sow_vars=None, reap_vars=None, const_vars=None, # "solveAgents" one time. If set to false, the error will never # print. See "solveAgents" for why this prints once or never. + # dictionaries for tracking initial and current values + # of the sow variables. + self.sow_init = OrderedDict({sow : None + for sow + in self.sow_vars}) + self.sow_state = OrderedDict({sow: None + for sow + in self.sow_vars}) + def solveAgents(self): ''' Solves the microeconomic problem for all AgentTypes in this market. @@ -1037,10 +1047,11 @@ def sow(self): ------- none ''' - for var_name in self.sow_vars: - this_seed = getattr(self, var_name) + for sow_var in self.sow_state: for this_type in self.agents: - setattr(this_type, var_name, this_seed) + setattr(this_type, + sow_var, + self.sow_state[sow_var]) def mill(self): ''' @@ -1066,10 +1077,10 @@ def mill(self): # Run the millRule and store its output in self product = self.millRule(**mill_dict) - for j in range(len(self.sow_vars)): - this_var = self.sow_vars[j] - this_product = getattr(product, this_var) - setattr(self, this_var, this_product) + + for sow_var in self.sow_state: + this_product = getattr(product, sow_var) + self.sow_state[sow_var] = this_product def cultivate(self): ''' @@ -1105,8 +1116,7 @@ def reset(self): for var_name in self.track_vars: # Reset the history of tracked variables self.history[var_name] = [] for var_name in self.sow_vars: # Set the sow variables to their initial levels - initial_val = getattr(self, var_name + '_init') - setattr(self, var_name, initial_val) + self.sow_state[var_name] = self.sow_init[var_name] for this_type in self.agents: # Reset each AgentType in the market this_type.reset() @@ -1124,7 +1134,10 @@ def store(self): none ''' for var_name in self.track_vars: - value_now = getattr(self, var_name) + try: + value_now = getattr(self, var_name) + except: + value_now = self.sow_state[var_name] self.history[var_name].append(value_now) def makeHistory(self): From fabec0cfd20d90d44279838d5257cb42f5466299 Mon Sep 17 00:00:00 2001 From: sb Date: Wed, 22 Jul 2020 14:13:31 -0400 Subject: [PATCH 02/11] updates to KS model to fit market refactoring --- HARK/ConsumptionSaving/ConsAggShockModel.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/HARK/ConsumptionSaving/ConsAggShockModel.py b/HARK/ConsumptionSaving/ConsAggShockModel.py index db8da7aa9..a4285805b 100644 --- a/HARK/ConsumptionSaving/ConsAggShockModel.py +++ b/HARK/ConsumptionSaving/ConsAggShockModel.py @@ -616,7 +616,7 @@ def getEconomyData(self, Economy): ''' self.T_sim = Economy.act_T # Need to be able to track as many periods as economy runs self.kInit = Economy.KSS # Initialize simulation assets to steady state - self.MrkvInit = Economy.MrkvNow_init # Starting Markov state for the macroeconomy + self.MrkvInit = Economy.sow_init['MrkvNow'] # Starting Markov state for the macroeconomy self.Mgrid = Economy.MSS*self.MgridBase # Aggregate market resources grid adjusted around SS capital ratio self.AFunc = Economy.AFunc # Next period's aggregate savings function self.DeprFac = Economy.DeprFac # Rate of capital depreciation @@ -2264,14 +2264,14 @@ def update(self): self.convertKtoY = lambda KtoY: KtoY**(1.0/(1.0 - self.CapShare)) # converts K/Y to K/L self.rFunc = lambda k: self.CapShare*k**(self.CapShare-1.0) self.Wfunc = lambda k: ((1.0-self.CapShare)*k**(self.CapShare)) - self.KtoLnow_init = self.KtoLSS - self.Mnow_init = self.MSS - self.Aprev_init = self.KSS - self.Rnow_init = self.RSS - self.Wnow_init = self.WSS + self.sow_init['KtoLnow'] = self.KtoLSS + self.sow_init['Mnow'] = self.MSS + self.sow_init['Aprev'] = self.KSS + self.sow_init['Rnow'] = self.RSS + self.sow_init['Wnow'] = self.WSS self.PermShkAggNow_init = 1.0 self.TranShkAggNow_init = 1.0 - self.Mrkv_init = 0 + self.sow_init['MrkvNow'] = 0 self.makeMrkvArray() def reset(self): From 15682cd91c1aaa5ffe58afb2bdcc6d5b08f7f495 Mon Sep 17 00:00:00 2001 From: sb Date: Wed, 22 Jul 2020 15:26:33 -0400 Subject: [PATCH 03/11] update SmallOpenEconomy --- HARK/ConsumptionSaving/ConsAggShockModel.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/HARK/ConsumptionSaving/ConsAggShockModel.py b/HARK/ConsumptionSaving/ConsAggShockModel.py index 0fbc63a17..018d35591 100644 --- a/HARK/ConsumptionSaving/ConsAggShockModel.py +++ b/HARK/ConsumptionSaving/ConsAggShockModel.py @@ -1680,12 +1680,12 @@ def update(self): self.KtoLnow_init = self.kSS self.Rfunc = ConstantFunction(self.Rfree) self.wFunc = ConstantFunction(self.wRte) - self.RfreeNow_init = self.Rfunc(self.kSS) - self.wRteNow_init = self.wFunc(self.kSS) - self.MaggNow_init = self.kSS - self.AaggNow_init = self.kSS - self.PermShkAggNow_init = 1.0 - self.TranShkAggNow_init = 1.0 + self.sow_init['RfreeNow'] = self.Rfunc(self.kSS) + self.sow_init['wRteNow'] = self.wFunc(self.kSS) + self.sow_init['MaggNow'] = self.kSS + self.sow_init['AaggNow'] = self.kSS + self.sow_init['PermShkAggNow'] = 1.0 + self.sow_init['TranShkAggNow'] = 1.0 self.makeAggShkDstn() self.AFunc = ConstantFunction(1.0) From 7444dc5957c2bbe9df0d0d0fa4329dad8e1102cd Mon Sep 17 00:00:00 2001 From: sb Date: Wed, 22 Jul 2020 16:36:28 -0400 Subject: [PATCH 04/11] const_vars now in dictionary --- HARK/core.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/HARK/core.py b/HARK/core.py index 53f9a63f9..93ff4ebf5 100644 --- a/HARK/core.py +++ b/HARK/core.py @@ -929,7 +929,9 @@ def __init__(self, agents=None, sow_vars=None, reap_vars=None, const_vars=None, self.agents = agents if agents is not None else list() # NOQA self.reap_vars = reap_vars if reap_vars is not None else list() # NOQA self.sow_vars = sow_vars if sow_vars is not None else list() # NOQA - self.const_vars = const_vars if const_vars is not None else list() # NOQA + + const_vars = const_vars if const_vars is not None else list() # NOQA + self.const_vars = OrderedDict([(var, None) for var in const_vars]) self.track_vars = track_vars if track_vars is not None else list() # NOQA self.dyn_vars = dyn_vars if dyn_vars is not None else list() # NOQA if millRule is not None: # To prevent overwriting of method-based millRules @@ -949,12 +951,8 @@ def __init__(self, agents=None, sow_vars=None, reap_vars=None, const_vars=None, # dictionaries for tracking initial and current values # of the sow variables. - self.sow_init = OrderedDict({sow : None - for sow - in self.sow_vars}) - self.sow_state = OrderedDict({sow: None - for sow - in self.sow_vars}) + self.sow_init = OrderedDict([(var, None) for var in self.sow_vars]) + self.sow_state = OrderedDict([(var, None) for var in self.sow_vars]) def solveAgents(self): ''' @@ -1072,10 +1070,9 @@ def mill(self): reap_vars_string = '' for name in self.reap_vars: reap_vars_string += ' \'' + name + '\' : self.' + name + ',' - const_vars_string = '' - for name in self.const_vars: - const_vars_string += ' \'' + name + '\' : self.' + name + ',' - mill_dict = eval('{' + reap_vars_string + const_vars_string + '}') + + mill_dict = eval('{' + reap_vars_string + '}') + mill_dict.update(self.const_vars) # Run the millRule and store its output in self product = self.millRule(**mill_dict) From e6f1022738d0503848c14f36b4d49a8afd170e23 Mon Sep 17 00:00:00 2001 From: sb Date: Wed, 22 Jul 2020 22:28:05 -0400 Subject: [PATCH 05/11] reap variables to dictionary --- HARK/core.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/HARK/core.py b/HARK/core.py index 93ff4ebf5..75c9d286c 100644 --- a/HARK/core.py +++ b/HARK/core.py @@ -927,7 +927,10 @@ def __init__(self, agents=None, sow_vars=None, reap_vars=None, const_vars=None, None ''' self.agents = agents if agents is not None else list() # NOQA - self.reap_vars = reap_vars if reap_vars is not None else list() # NOQA + + reap_vars = reap_vars if reap_vars is not None else list() # NOQA + self.reap_vars = OrderedDict([(var, []) for var in reap_vars]) + self.sow_vars = sow_vars if sow_vars is not None else list() # NOQA const_vars = const_vars if const_vars is not None else list() # NOQA @@ -1032,7 +1035,7 @@ def reap(self): harvest = [] for this_type in self.agents: harvest.append(getattr(this_type, var_name)) - setattr(self, var_name, harvest) + self.reap_vars[var_name] = harvest def sow(self): ''' @@ -1067,11 +1070,7 @@ def mill(self): none ''' # Make a dictionary of inputs for the millRule - reap_vars_string = '' - for name in self.reap_vars: - reap_vars_string += ' \'' + name + '\' : self.' + name + ',' - - mill_dict = eval('{' + reap_vars_string + '}') + mill_dict = copy(self.reap_vars) mill_dict.update(self.const_vars) # Run the millRule and store its output in self From 0ef77f717ad0c80da72b88158b90abf2ff669648 Mon Sep 17 00:00:00 2001 From: sb Date: Wed, 22 Jul 2020 22:53:16 -0400 Subject: [PATCH 06/11] collect sow var dicts in with sow vars --- HARK/core.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/HARK/core.py b/HARK/core.py index 75c9d286c..c45706cf3 100644 --- a/HARK/core.py +++ b/HARK/core.py @@ -932,11 +932,18 @@ def __init__(self, agents=None, sow_vars=None, reap_vars=None, const_vars=None, self.reap_vars = OrderedDict([(var, []) for var in reap_vars]) self.sow_vars = sow_vars if sow_vars is not None else list() # NOQA + # dictionaries for tracking initial and current values + # of the sow variables. + self.sow_init = OrderedDict([(var, None) for var in self.sow_vars]) + self.sow_state = OrderedDict([(var, None) for var in self.sow_vars]) const_vars = const_vars if const_vars is not None else list() # NOQA self.const_vars = OrderedDict([(var, None) for var in const_vars]) + + ## TODO: track_vars handling is not right self.track_vars = track_vars if track_vars is not None else list() # NOQA self.dyn_vars = dyn_vars if dyn_vars is not None else list() # NOQA + if millRule is not None: # To prevent overwriting of method-based millRules self.millRule = millRule if calcDynamics is not None: # Ditto for calcDynamics @@ -952,10 +959,6 @@ def __init__(self, agents=None, sow_vars=None, reap_vars=None, const_vars=None, # "solveAgents" one time. If set to false, the error will never # print. See "solveAgents" for why this prints once or never. - # dictionaries for tracking initial and current values - # of the sow variables. - self.sow_init = OrderedDict([(var, None) for var in self.sow_vars]) - self.sow_state = OrderedDict([(var, None) for var in self.sow_vars]) def solveAgents(self): ''' From b7b91abc08dd193d4a75d7fe69cabc8dd23d70ba Mon Sep 17 00:00:00 2001 From: sb Date: Thu, 23 Jul 2020 12:59:49 -0400 Subject: [PATCH 07/11] adding ConsAggShockModel tests for Market history tracking --- .../tests/test_ConsAggShockModel.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/HARK/ConsumptionSaving/tests/test_ConsAggShockModel.py b/HARK/ConsumptionSaving/tests/test_ConsAggShockModel.py index 62b65b732..70c615ed1 100644 --- a/HARK/ConsumptionSaving/tests/test_ConsAggShockModel.py +++ b/HARK/ConsumptionSaving/tests/test_ConsAggShockModel.py @@ -48,6 +48,9 @@ def test_macro(self): self.assertAlmostEqual(self.economy.AFunc.slope, 1.116259456228145) + self.assertAlmostEqual(self.economy.history['MaggNow'][10], + 7.456324335623432) + class testAggShockMarkovConsumerType(unittest.TestCase): @@ -81,7 +84,10 @@ def test_economy(self): self.economy.AFunc = self.economy.dynamics.AFunc self.assertAlmostEqual(self.economy.AFunc[0].slope, 1.0904698841958917) - + + self.assertAlmostEqual(self.economy.history['AaggNow'][5], + 9.467758924955897) + class testKrusellSmith(unittest.TestCase): @@ -110,3 +116,13 @@ def test_economy(self): self.economy.AFunc = self.economy.dynamics.AFunc self.assertAlmostEqual(self.economy.AFunc[0].slope, 1.0014463644834282) + + self.assertAlmostEqual(self.economy.history['Aprev'][4], + 11.009107526443584) + + self.assertAlmostEqual(self.economy.history['MrkvNow'][40], + 1 + ) + + self.assertAlmostEqual(self.economy.history['Urate'][12], + 0.040000000000000036) From 7b78cd78a46a0a8f45ddfce821ea81519fba6c67 Mon Sep 17 00:00:00 2001 From: sb Date: Thu, 23 Jul 2020 13:32:57 -0400 Subject: [PATCH 08/11] fixing trak_vars --- HARK/core.py | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/HARK/core.py b/HARK/core.py index c45706cf3..4d8168c84 100644 --- a/HARK/core.py +++ b/HARK/core.py @@ -929,7 +929,7 @@ def __init__(self, agents=None, sow_vars=None, reap_vars=None, const_vars=None, self.agents = agents if agents is not None else list() # NOQA reap_vars = reap_vars if reap_vars is not None else list() # NOQA - self.reap_vars = OrderedDict([(var, []) for var in reap_vars]) + self.reap_state = OrderedDict([(var, []) for var in reap_vars]) self.sow_vars = sow_vars if sow_vars is not None else list() # NOQA # dictionaries for tracking initial and current values @@ -940,7 +940,6 @@ def __init__(self, agents=None, sow_vars=None, reap_vars=None, const_vars=None, const_vars = const_vars if const_vars is not None else list() # NOQA self.const_vars = OrderedDict([(var, None) for var in const_vars]) - ## TODO: track_vars handling is not right self.track_vars = track_vars if track_vars is not None else list() # NOQA self.dyn_vars = dyn_vars if dyn_vars is not None else list() # NOQA @@ -1034,11 +1033,11 @@ def reap(self): ------- none ''' - for var_name in self.reap_vars: - harvest = [] - for this_type in self.agents: - harvest.append(getattr(this_type, var_name)) - self.reap_vars[var_name] = harvest + for var_name in self.reap_state: + harvest = [getattr(this_type, var_name) + for this_type + in self.agents] + self.reap_state[var_name] = harvest def sow(self): ''' @@ -1073,7 +1072,7 @@ def mill(self): none ''' # Make a dictionary of inputs for the millRule - mill_dict = copy(self.reap_vars) + mill_dict = copy(self.reap_state) mill_dict.update(self.const_vars) # Run the millRule and store its output in self @@ -1114,11 +1113,15 @@ def reset(self): ------- none ''' - for var_name in self.track_vars: # Reset the history of tracked variables - self.history[var_name] = [] - for var_name in self.sow_vars: # Set the sow variables to their initial levels + # Reset the history of tracked variables + self.history = {var_name : [] for var_name in self.track_vars} + + # Set the sow variables to their initial levels + for var_name in self.sow_state: self.sow_state[var_name] = self.sow_init[var_name] - for this_type in self.agents: # Reset each AgentType in the market + + # Reset each AgentType in the market + for this_type in self.agents: this_type.reset() def store(self): @@ -1135,10 +1138,15 @@ def store(self): none ''' for var_name in self.track_vars: - try: - value_now = getattr(self, var_name) - except: + if var_name in self.sow_state: value_now = self.sow_state[var_name] + elif var_name in self.reap_state: + value_now = self.reap_state[var_name] + elif var_name in self.const_vars: + value_now = self.const_vars[var_name] + else: + value_now = getattr(self, var_name) + self.history[var_name].append(value_now) def makeHistory(self): From 2220fa5787916491dfc2d203dbb9877a3918b2a8 Mon Sep 17 00:00:00 2001 From: sb Date: Thu, 23 Jul 2020 16:12:37 -0400 Subject: [PATCH 09/11] millRule returning a tuple of values same size/order as sow_vars --- HARK/ConsumptionSaving/ConsAggShockModel.py | 175 +++++++++----------- HARK/core.py | 12 +- 2 files changed, 82 insertions(+), 105 deletions(-) diff --git a/HARK/ConsumptionSaving/ConsAggShockModel.py b/HARK/ConsumptionSaving/ConsAggShockModel.py index 018d35591..169c0710f 100644 --- a/HARK/ConsumptionSaving/ConsAggShockModel.py +++ b/HARK/ConsumptionSaving/ConsAggShockModel.py @@ -24,7 +24,7 @@ __all__ = ['MargValueFunc2D', 'AggShockConsumerType', 'AggShockMarkovConsumerType', 'CobbDouglasEconomy', 'SmallOpenEconomy', 'CobbDouglasMarkovEconomy', - 'SmallOpenMarkovEconomy', 'CobbDouglasAggVars', 'AggregateSavingRule', 'AggShocksDynamicRule','init_agg_shocks','init_agg_mrkv_shocks', 'init_cobb_douglas','init_mrkv_cobb_douglas'] + 'SmallOpenMarkovEconomy', 'AggregateSavingRule', 'AggShocksDynamicRule','init_agg_shocks','init_agg_mrkv_shocks', 'init_cobb_douglas','init_mrkv_cobb_douglas'] utility = CRRAutility utilityP = CRRAutilityP @@ -818,7 +818,7 @@ def getShocks(self): # Get boolean arrays for current employment states employed = self.EmpNow.copy() unemployed = np.logical_not(employed) - + # Transition some agents between unemployment and employment emp_permute = self.emp_permute[self.MrkvPrev][self.MrkvNow] unemp_permute = self.unemp_permute[self.MrkvPrev][self.MrkvNow] @@ -1547,10 +1547,20 @@ def calcRandW(self, aLvlNow, pLvlNow): Returns ------- - AggVarsNow : CobbDouglasAggVars - An object containing the aggregate variables for the upcoming period: - capital-to-labor ratio, interest factor, (normalized) wage rate, - aggregate permanent and transitory shocks. + MaggNow : float + Aggregate market resources for this period normalized by mean permanent income + AaggNow : float + Aggregate savings for this period normalized by mean permanent income + RfreeNow : float + Interest factor on assets in the economy this period. + wRteNow : float + Wage rate for labor in the economy this period. + PermShkAggNow : float + Permanent shock to aggregate labor productivity this period. + TranShkAggNow : float + Transitory shock to aggregate labor productivity this period. + KtoLnow : float + Capital-to-labor ratio in the economy this period. ''' # Calculate aggregate savings AaggPrev = np.mean(np.array(aLvlNow))/np.mean(pLvlNow) # End-of-period savings from last period @@ -1577,9 +1587,8 @@ def calcRandW(self, aLvlNow, pLvlNow): self.KtoLnow = KtoLnow # Need to store this as it is a sow variable # Package the results into an object and return it - AggVarsNow = CobbDouglasAggVars(MaggNow, AaggPrev, KtoLnow, RfreeNow, wRteNow, PermShkAggNow, TranShkAggNow) - return AggVarsNow - + return MaggNow, AaggPrev, RfreeNow, wRteNow, PermShkAggNow, TranShkAggNow, KtoLnow + def calcAFunc(self, MaggNow, AaggNow): ''' Calculate a new aggregate savings rule based on the history @@ -1781,8 +1790,21 @@ def getAggShocks(self): Returns ------- - AggVarsNow : CobbDouglasAggVars - Aggregate state and shock variables for this period. + MaggNow : float + Aggregate market resources for this period normalized by mean permanent income + AaggNow : float + Aggregate savings for this period normalized by mean permanent income + RfreeNow : float + Interest factor on assets in the economy this period. + wRteNow : float + Wage rate for labor in the economy this period. + PermShkAggNow : float + Permanent shock to aggregate labor productivity this period. + TranShkAggNow : float + Transitory shock to aggregate labor productivity this period. + KtoLnow : float + Capital-to-labor ratio in the economy this period. + ''' # Get this period's aggregate shocks PermShkAggNow = self.PermShkAggHist[self.Shk_idx] @@ -1798,9 +1820,7 @@ def getAggShocks(self): MaggNow = 1.0 KtoLnow = 1.0/PermShkAggNow - # Package the results into an object and return it - AggVarsNow = CobbDouglasAggVars(MaggNow, AaggNow, KtoLnow, RfreeNow, wRteNow, PermShkAggNow, TranShkAggNow) - return AggVarsNow + return MaggNow, AaggNow, RfreeNow, wRteNow, PermShkAggNow, TranShkAggNow, KtoLnow # Make a dictionary to specify a Markov Cobb-Douglas economy init_mrkv_cobb_douglas = init_cobb_douglas.copy() @@ -2085,11 +2105,26 @@ def millRule(self, aLvlNow, pLvlNow): and adds the Markov state index. See documentation for calcRandW for more information. + + Returns + ------- + Mnow : float + Aggregate market resources for this period. + Aprev : float + Aggregate savings for the prior period. + KtoLnow : float + Capital-to-labor ratio in the economy this period. + Rnow : float + Interest factor on assets in the economy this period. + Wnow : float + Wage rate for labor in the economy this period. + MrkvNow : int + Binary indicator for bad (0) or good (1) macroeconomic state. ''' MrkvNow = self.MrkvNow_hist[self.Shk_idx] temp = self.calcRandW(aLvlNow, pLvlNow) - temp(MrkvNow=MrkvNow) - return temp + + return temp + (MrkvNow,) def calcAFunc(self, MaggNow, AaggNow): ''' @@ -2356,7 +2391,21 @@ def millRule(self, aNow, EmpNow): wage rate based on each agent's current state. Just calls calcRandW(). See documentation for calcRandW for more information. + + Returns + ------- + Mnow : float + Aggregate market resources for this period. + Aprev : float + Aggregate savings for the prior period. + MrkvNow : int + Binary indicator for bad (0) or good (1) macroeconomic state. + Rnow : float + Interest factor on assets in the economy this period. + Wnow : float + Wage rate for labor in the economy this period. ''' + return self.calcRandW(aNow, EmpNow) def calcDynamics(self, Mnow, Aprev): @@ -2383,10 +2432,16 @@ def calcRandW(self, aNow, EmpNow): Returns ------- - AggVarsNow : CobbDouglasAggVars - An object containing the aggregate variables for the upcoming period: - capital-to-labor ratio, interest factor, (normalized) wage rate, - aggregate permanent and transitory shocks. + Mnow : float + Aggregate market resources for this period. + Aprev : float + Aggregate savings for the prior period. + MrkvNow : int + Binary indicator for bad (0) or good (1) macroeconomic state. + Rnow : float + Interest factor on assets in the economy this period. + Wnow : float + Wage rate for labor in the economy this period. ''' # Calculate aggregate savings Aprev = np.mean(np.array(aNow)) # End-of-period savings from last period @@ -2414,9 +2469,8 @@ def calcRandW(self, aNow, EmpNow): Mnow = Rnow*AggK + Wnow*AggL self.KtoLnow = KtoLnow # Need to store this as it is a sow variable - # Package the results into an object and return it - AggVarsNow = KrusellSmithAggVars(Mnow, Aprev, KtoLnow, Rnow, Wnow, MrkvNow) - return AggVarsNow + # Returns a tuple of these values + return Mnow, Aprev, MrkvNow, Rnow, Wnow def calcAFunc(self, Mnow, Aprev): ''' @@ -2472,81 +2526,6 @@ def calcAFunc(self, Mnow, Aprev): return AggShocksDynamicRule(AFunc_list) -class CobbDouglasAggVars(HARKobject): - ''' - A simple class for holding the relevant aggregate variables that should be - passed from the market to each type. Includes the capital-to-labor ratio, - the interest factor, the wage rate, and the aggregate permanent and tran- - sitory shocks. - ''' - def __init__(self, MaggNow, AaggNow, KtoLnow, RfreeNow, wRteNow, PermShkAggNow, TranShkAggNow): - ''' - Make a new instance of CobbDouglasAggVars. - - Parameters - ---------- - MaggNow : float - Aggregate market resources for this period normalized by mean permanent income - AaggNow : float - Aggregate savings for this period normalized by mean permanent income - KtoLnow : float - Capital-to-labor ratio in the economy this period. - RfreeNow : float - Interest factor on assets in the economy this period. - wRteNow : float - Wage rate for labor in the economy this period. - PermShkAggNow : float - Permanent shock to aggregate labor productivity this period. - TranShkAggNow : float - Transitory shock to aggregate labor productivity this period. - - Returns - ------- - None - ''' - self.MaggNow = MaggNow - self.AaggNow = AaggNow - self.KtoLnow = KtoLnow - self.RfreeNow = RfreeNow - self.wRteNow = wRteNow - self.PermShkAggNow = PermShkAggNow - self.TranShkAggNow = TranShkAggNow - - -class KrusellSmithAggVars(): - ''' - Just a container class for aggregate data in the Krusell-Smith model. - ''' - def __init__(self, Mnow, Aprev, KtoLnow, Rnow, Wnow, MrkvNow): - ''' - Make a new instance of KrusellSmithAggVars. - - Parameters - ---------- - Mnow : float - Aggregate market resources for this period. - Aprev : float - Aggregate savings for the prior period. - KtoLnow : float - Capital-to-labor ratio in the economy this period. - Rnow : float - Interest factor on assets in the economy this period. - Wnow : float - Wage rate for labor in the economy this period. - MrkvNow : int - Binary indicator for bad (0) or good (1) macroeconomic state. - - Returns - ------- - None - ''' - self.Mnow = Mnow - self.Aprev = Aprev - self.KtoLnow = KtoLnow - self.Rnow = Rnow - self.Wnow = Wnow - self.MrkvNow = MrkvNow - class AggregateSavingRule(HARKobject): ''' diff --git a/HARK/core.py b/HARK/core.py index 4d8168c84..5ed7bb1fd 100644 --- a/HARK/core.py +++ b/HARK/core.py @@ -906,8 +906,7 @@ def __init__(self, agents=None, sow_vars=None, reap_vars=None, const_vars=None, dyn_vars : [string] Names of variables that constitute a "dynamic rule". millRule : function - A function that takes inputs named in reap_vars and returns an object - with attributes named in sow_vars. The "aggregate market process" that + A function that takes inputs named in reap_vars and returns a tuple the same size and order as sow_vars. The "aggregate market process" that transforms individual agent actions/states/data into aggregate data to be sent back to agents. calcDynamics : function @@ -1078,9 +1077,8 @@ def mill(self): # Run the millRule and store its output in self product = self.millRule(**mill_dict) - for sow_var in self.sow_state: - this_product = getattr(product, sow_var) - self.sow_state[sow_var] = this_product + for i, sow_var in enumerate(self.sow_state): + self.sow_state[sow_var] = product[i] def cultivate(self): ''' @@ -1117,7 +1115,7 @@ def reset(self): self.history = {var_name : [] for var_name in self.track_vars} # Set the sow variables to their initial levels - for var_name in self.sow_state: + for var_name in self.sow_state: self.sow_state[var_name] = self.sow_init[var_name] # Reset each AgentType in the market @@ -1146,7 +1144,7 @@ def store(self): value_now = self.const_vars[var_name] else: value_now = getattr(self, var_name) - + self.history[var_name].append(value_now) def makeHistory(self): From 3b678d157613d261f24c27ee3a2fc300f6aebf19 Mon Sep 17 00:00:00 2001 From: sb Date: Thu, 23 Jul 2020 16:24:05 -0400 Subject: [PATCH 10/11] missed a sow_var in Small Open --- HARK/ConsumptionSaving/ConsAggShockModel.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/HARK/ConsumptionSaving/ConsAggShockModel.py b/HARK/ConsumptionSaving/ConsAggShockModel.py index 169c0710f..b6159f6be 100644 --- a/HARK/ConsumptionSaving/ConsAggShockModel.py +++ b/HARK/ConsumptionSaving/ConsAggShockModel.py @@ -1673,7 +1673,8 @@ def __init__(self, agents=None, tolerance=0.0001, act_T=1000, **kwds): def update(self): ''' - Use primitive parameters to set basic objects. This is an extremely stripped-down version + Use primitive parameters to set basic objects. + This is an extremely stripped-down version of update for CobbDouglasEconomy. Parameters @@ -1686,7 +1687,7 @@ def update(self): ''' self.kSS = 1.0 self.MSS = 1.0 - self.KtoLnow_init = self.kSS + self.sow_init['KtoLnow_init'] = self.kSS self.Rfunc = ConstantFunction(self.Rfree) self.wFunc = ConstantFunction(self.wRte) self.sow_init['RfreeNow'] = self.Rfunc(self.kSS) From a6e2de92eeb4525a96192b58e38a8971be698106 Mon Sep 17 00:00:00 2001 From: sb Date: Thu, 30 Jul 2020 16:13:06 -0400 Subject: [PATCH 11/11] replace OrderedDict with dict -- 3.7 dicts ordered by default --- HARK/core.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/HARK/core.py b/HARK/core.py index 5ed7bb1fd..e0cc29dfa 100644 --- a/HARK/core.py +++ b/HARK/core.py @@ -12,7 +12,6 @@ from builtins import str from builtins import range from builtins import object -from collections import OrderedDict import sys import os from distutils.dir_util import copy_tree @@ -928,16 +927,16 @@ def __init__(self, agents=None, sow_vars=None, reap_vars=None, const_vars=None, self.agents = agents if agents is not None else list() # NOQA reap_vars = reap_vars if reap_vars is not None else list() # NOQA - self.reap_state = OrderedDict([(var, []) for var in reap_vars]) + self.reap_state = dict([(var, []) for var in reap_vars]) self.sow_vars = sow_vars if sow_vars is not None else list() # NOQA # dictionaries for tracking initial and current values # of the sow variables. - self.sow_init = OrderedDict([(var, None) for var in self.sow_vars]) - self.sow_state = OrderedDict([(var, None) for var in self.sow_vars]) + self.sow_init = dict([(var, None) for var in self.sow_vars]) + self.sow_state = dict([(var, None) for var in self.sow_vars]) const_vars = const_vars if const_vars is not None else list() # NOQA - self.const_vars = OrderedDict([(var, None) for var in const_vars]) + self.const_vars = dict([(var, None) for var in const_vars]) self.track_vars = track_vars if track_vars is not None else list() # NOQA self.dyn_vars = dyn_vars if dyn_vars is not None else list() # NOQA