def getShocks(self): ''' Draws a new Markov state and income shocks for the representative agent. Parameters ---------- None Returns ------- None ''' cutoffs = np.cumsum(self.MrkvArray[self.MrkvNow, :]) MrkvDraw = drawUniform(N=1, seed=self.RNG.randint(0, 2**31 - 1)) self.MrkvNow = np.searchsorted(cutoffs, MrkvDraw) t = self.t_cycle[0] i = self.MrkvNow[0] IncomeDstnNow = self.IncomeDstn[t - 1][ i] # set current income distribution PermGroFacNow = self.PermGroFac[t - 1][i] # and permanent growth factor Indices = np.arange(IncomeDstnNow[0].size) # just a list of integers # Get random draws of income shocks from the discrete distribution EventDraw = drawDiscrete(N=1, X=Indices, P=IncomeDstnNow[0], exact_match=False, seed=self.RNG.randint(0, 2**31 - 1)) PermShkNow = IncomeDstnNow[1][ EventDraw] * PermGroFacNow # permanent "shock" includes expected growth TranShkNow = IncomeDstnNow[2][EventDraw] self.PermShkNow = np.array(PermShkNow) self.TranShkNow = np.array(TranShkNow)
def makeAggShkHist(self): ''' Make simulated histories of aggregate transitory and permanent shocks. Histories are of length self.act_T, for use in the general equilibrium simulation. This replicates the same method for CobbDouglasEconomy; future version should create parent class. Parameters ---------- None Returns ------- None ''' sim_periods = self.act_T Events = np.arange(self.AggShkDstn[0].size) # just a list of integers EventDraws = drawDiscrete(N=sim_periods, P=self.AggShkDstn[0], X=Events, seed=0) PermShkAggHist = self.AggShkDstn[1][EventDraws] TranShkAggHist = self.AggShkDstn[2][EventDraws] # Store the histories self.PermShkAggHist = PermShkAggHist self.TranShkAggHist = TranShkAggHist
def makeAggShkHist(self): ''' Make simulated histories of aggregate transitory and permanent shocks. Histories are of length self.act_T, for use in the general equilibrium simulation. Parameters ---------- none Returns ------- none ''' sim_periods = self.act_T Events = np.arange(self.AggShkDstn[0].size) # just a list of integers EventDraws = drawDiscrete(N=sim_periods, P=self.AggShkDstn[0], X=Events, seed=0) PermShkAggHist = self.AggShkDstn[1][EventDraws] TranShkAggHist = self.AggShkDstn[2][EventDraws] # Store the histories self.PermShkAggHist = PermShkAggHist self.TranShkAggHist = TranShkAggHist
def reset(self): self.initializeSim() self.t_age = drawDiscrete(self.AgentCount,P=self.AgeDstn,X=np.arange(self.AgeDstn.size),exact_match=False,seed=self.RNG.randint(0,2**31-1)).astype(int) self.t_cycle = copy(self.t_age) if hasattr(self,'kGrid'): self.aLvlNow = self.kInit*np.ones(self.AgentCount) # Start simulation near SS self.aNrmNow = self.aLvlNow/self.pLvlNow
def reset(self): self.initializeSim() self.t_age = drawDiscrete(self.AgentCount, P=self.AgeDstn, X=np.arange(self.AgeDstn.size), exact_match=False, seed=self.RNG.randint(0, 2**31 - 1)).astype(int) self.t_cycle = copy(self.t_age)
def reset(self): self.initializeSim() self.t_age = drawDiscrete(self.AgentCount, P=self.AgeDstn, X=np.arange(self.AgeDstn.size), exact_match=False, seed=self.RNG.randint(0, 2**31 - 1)).astype(int) self.t_cycle = copy(self.t_age) if hasattr(self, 'kGrid'): self.aLvlNow = self.kInit * np.ones( self.AgentCount) # Start simulation near SS self.aNrmNow = self.aLvlNow / self.pLvlNow
def makeIncShkHist(self): ''' Makes histories of simulated income shocks for this consumer type by drawing from the discrete income distributions, respecting the Markov state for each agent in each period. Should be run after makeMrkvHist(). Parameters ---------- none Returns ------- none ''' orig_time = self.time_flow self.timeFwd() self.resetRNG() # Initialize the shock histories N = self.MrkvArray.shape[0] PermShkHist = np.zeros((self.sim_periods,self.Nagents)) + np.nan TranShkHist = np.zeros((self.sim_periods,self.Nagents)) + np.nan PermShkHist[0,:] = 1.0 TranShkHist[0,:] = 1.0 t_idx = 0 # Draw income shocks for each simulated period, respecting the Markov state for t in range(1,self.sim_periods): MrkvNow = self.MrkvHist[t,:] IncomeDstn_list = self.IncomeDstn[t_idx] PermGroFac_list = self.PermGroFac[t_idx] for n in range(N): these = MrkvNow == n IncomeDstnNow = IncomeDstn_list[n] PermGroFacNow = PermGroFac_list[n] Indices = np.arange(IncomeDstnNow[0].size) # just a list of integers # Get random draws of income shocks from the discrete distribution EventDraws = drawDiscrete(N=np.sum(these),X=Indices,P=IncomeDstnNow[0],exact_match=False,seed=self.RNG.randint(0,2**31-1)) PermShkHist[t,these] = IncomeDstnNow[1][EventDraws]*PermGroFacNow TranShkHist[t,these] = IncomeDstnNow[2][EventDraws] # Advance the time index, looping if we've run out of income distributions t_idx += 1 if t_idx >= len(self.IncomeDstn): t_idx = 0 # Store the results as attributes of self and restore time to its original flow self.PermShkHist = PermShkHist self.TranShkHist = TranShkHist if not orig_time: self.timeRev()
def simBirth(self, which_agents): ''' Agents do not die in this model, so birth only happens at time 0. Agents get given levels of labor income and assets according to the steady state distribution Parameters ---------- which_agents : np.array(Bool) Boolean array of size self.AgentCount indicating which agents should be "born". Note in this model birth only happens once at time zero, for all agents Returns ------- None ''' # Get and store states for newly born agents N = np.sum(which_agents) # Number of new consumers to make # Agents are given productivity and asset levels from the steady state #distribution joint_distr = self.SR['joint_distr'] mgrid = self.mgrid col_indicies = np.repeat([range(joint_distr.shape[1])], joint_distr.shape[0], 0).flatten() row_indicies = np.transpose( np.repeat([range(joint_distr.shape[0])], joint_distr.shape[1], 0)).flatten() draws = drawDiscrete(N, np.array(joint_distr).flatten(), range(joint_distr.size), seed=self.RNG.randint(0, 2**31 - 1)) draws_rows = row_indicies[draws] draws_cols = col_indicies[draws] #steady state consumption function is in terms of end of period savings and income state self.bNow[which_agents] = mgrid[draws_rows] self.incStateNow[which_agents] = draws_cols 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
def makeAggShkHist(self): ''' Make simulated histories of aggregate transitory and permanent shocks. Histories are of length self.act_T, for use in the general equilibrium simulation. Parameters ---------- none Returns ------- none ''' sim_periods = self.act_T Events = np.arange(self.AggShkDstn[0].size) # just a list of integers EventDraws = drawDiscrete(N=sim_periods,P=self.AggShkDstn[0],X=Events,seed=0) PermShkAggHist = self.AggShkDstn[1][EventDraws] # TranShkAggHist = self.AggShkDstn[2][EventDraws] # Store the histories self.PermShkAggHist = PermShkAggHist
def makeAggShkHist(self): ''' Make simulated histories of aggregate transitory and permanent shocks. Histories are of length self.act_T, for use in the general equilibrium simulation. This replicates the same method for CobbDouglasEconomy; future version should create parent class. Parameters ---------- None Returns ------- None ''' sim_periods = self.act_T Events = np.arange(self.AggShkDstn[0].size) # just a list of integers EventDraws = drawDiscrete(N=sim_periods,P=self.AggShkDstn[0],X=Events,seed=0) PermShkAggHist = self.AggShkDstn[1][EventDraws] TranShkAggHist = self.AggShkDstn[2][EventDraws] # Store the histories self.PermShkAggHist = PermShkAggHist self.TranShkAggHist = TranShkAggHist
# Set target Lorenz points and K/Y ratio (MOVE THIS TO SetupParams) if Params.do_liquid: lorenz_target = np.array([0.0, 0.004, 0.025, 0.117]) KY_target = 6.60 else: # This is hacky until I can find the liquid wealth data and import it lorenz_target = getLorenzShares( Params.SCF_wealth, weights=Params.SCF_weights, percentiles=Params.percentiles_to_match) #lorenz_target = np.array([-0.002, 0.01, 0.053,0.171]) KY_target = 10.26 # Make a vector of initial wealth-to-permanent income ratios a_init = drawDiscrete(N=Params.sim_pop_size, P=Params.a0_probs, X=Params.a0_values, seed=Params.a0_seed) # Make the list of types for this run, whether infinite or lifecycle if Params.do_lifecycle: # Make cohort scaling array cohort_scale = Params.TFP_growth**(-np.arange(Params.total_T + 1)) cohort_scale_array = np.tile( np.reshape(cohort_scale, (Params.total_T + 1, 1)), (1, Params.sim_pop_size)) # Make base consumer types for each education level DropoutType = cstwMPCagent(**Params.init_dropout) DropoutType.a_init = a_init DropoutType.cohort_scale = cohort_scale_array HighschoolType = deepcopy(DropoutType)
def getShocks(self): ''' Gets permanent and transitory income shocks for this period. Samples from IncomeDstn for each period in the cycle. Parameters ---------- None Returns ------- None ''' PermShkNow = np.zeros(self.AgentCount) # Initialize shock arrays TranShkNow = np.zeros(self.AgentCount) PrefShkNow = np.zeros(self.AgentCount) newborn = self.t_age == 0 for t in range(self.T_cycle): these = t == self.t_cycle N = np.sum(these) if N > 0: IncomeDstnNow = self.IncomeAndPrefDstn[ t - 1] # set current income distribution PermGroFacNow = self.PermGroFac[ t - 1] # and permanent growth factor Indices = np.arange( IncomeDstnNow[0].size) # just a list of integers # Get random draws of income shocks from the discrete distribution EventDraws = drawDiscrete(N, X=Indices, P=IncomeDstnNow[0], exact_match=False, seed=self.RNG.randint(0, 2**31 - 1)) PermShkNow[these] = IncomeDstnNow[1][ EventDraws] * PermGroFacNow # permanent "shock" includes expected growth TranShkNow[these] = IncomeDstnNow[2][EventDraws] PrefShkNow[these] = IncomeDstnNow[3][EventDraws] # That procedure used the *last* period in the sequence for newborns, but that's not right # Redraw shocks for newborns, using the *first* period in the sequence. Approximation. N = np.sum(newborn) if N > 0: these = newborn IncomeDstnNow = self.IncomeAndPrefDstn[ 0] # set current income distribution PermGroFacNow = self.PermGroFac[0] # and permanent growth factor Indices = np.arange( IncomeDstnNow[0].size) # just a list of integers # Get random draws of income shocks from the discrete distribution EventDraws = drawDiscrete(N, X=Indices, P=IncomeDstnNow[0], exact_match=False, seed=self.RNG.randint(0, 2**31 - 1)) PermShkNow[these] = IncomeDstnNow[1][ EventDraws] * PermGroFacNow # permanent "shock" includes expected growth TranShkNow[these] = IncomeDstnNow[2][EventDraws] PrefShkNow[these] = IncomeDstnNow[3][EventDraws] # PermShkNow[newborn] = 1.0 TranShkNow[newborn] = 1.0 # Store the shocks in self self.EmpNow = np.ones(self.AgentCount, dtype=bool) self.EmpNow[TranShkNow == self.IncUnemp] = False self.PermShkNow = PermShkNow self.TranShkNow = TranShkNow self.PrefShkNow = PrefShkNow
# Set booleans to determine which tasks should be done estimate_model = True compute_standard_errors = False make_contour_plot = True #===================================================== # Define objects and functions used for the estimation #===================================================== # Make a lifecycle consumer to be used for estimation, including simulated shocks (plus an initial distribution of wealth) EstimationAgent = Model.ConsumerType(**Params.init_consumer_objects) EstimationAgent(sim_periods=EstimationAgent.T_total + 1) EstimationAgent.makeIncShkHist() EstimationAgent.a_init = drawDiscrete( P=Params.initial_wealth_income_ratio_probs, X=Params.initial_wealth_income_ratio_vals, N=Params.num_agents, seed=Params.seed) # Define the objective function for the estimation def smmObjectiveFxn(DiscFacAdj, CRRA, agent=EstimationAgent, DiscFacAdj_bound=Params.DiscFacAdj_bound, CRRA_bound=Params.CRRA_bound, empirical_data=Data.w_to_y_data, empirical_weights=Data.empirical_weights, empirical_groups=Data.empirical_groups, map_simulated_to_empirical_cohorts=Data. simulation_map_cohorts_to_age_indices):
which_agents] = 0 # How many periods since each agent was born self.t_cycle[ which_agents] = 0 # Which period of the cycle each agents is currently in return None # Make a lifecycle consumer to be used for estimation, including simulated shocks (plus an initial distribution of wealth) EstimationAgent = TempConsumerType( **Params.init_consumer_objects) # Make a TempConsumerType for estimation EstimationAgent(T_sim=EstimationAgent.T_cycle + 1) # Set the number of periods to simulate EstimationAgent.track_vars = ['bNrmNow' ] # Choose to track bank balances as wealth EstimationAgent.aNrmInit = drawDiscrete( N=Params.num_agents, P=Params.initial_wealth_income_ratio_probs, X=Params.initial_wealth_income_ratio_vals, seed=Params.seed) # Draw initial assets for each consumer EstimationAgent.makeShockHistory() # Define the objective function for the simulated method of moments estimation def smmObjectiveFxn(DiscFacAdj, CRRA, agent=EstimationAgent, DiscFacAdj_bound=Params.DiscFacAdj_bound, CRRA_bound=Params.CRRA_bound, empirical_data=Data.w_to_y_data, empirical_weights=Data.empirical_weights, empirical_groups=Data.empirical_groups, map_simulated_to_empirical_cohorts=Data.
# Set booleans to determine which tasks should be done estimate_model = True # Whether to estimate the model compute_standard_errors = False # Whether to get standard errors via bootstrap make_contour_plot = False # Whether to make a contour map of the objective function #===================================================== # Define objects and functions used for the estimation #===================================================== # Make a lifecycle consumer to be used for estimation, including simulated shocks (plus an initial distribution of wealth) EstimationAgent = Model.IndShockConsumerType(**Params.init_consumer_objects) # Make a ConsumerType for estimation <<<<<<< HEAD EstimationAgent(sim_periods = EstimationAgent.T_total+1) # Set the number of periods to simulate EstimationAgent.makeIncShkHist() # Make a simulated history of income shocks for many consumers EstimationAgent.a_init = drawDiscrete(P=Params.initial_wealth_income_ratio_probs, X=Params.initial_wealth_income_ratio_vals, N=Params.num_agents, ======= EstimationAgent.time_inv.remove('DiscFac') # This estimation uses age-varying discount factors as EstimationAgent.time_vary.append('DiscFac') # estimated by Cagetti (2003), so switch from time_inv to time_vary EstimationAgent(sim_periods = EstimationAgent.T_total+1) # Set the number of periods to simulate EstimationAgent.makeIncShkHist() # Make a simulated history of income shocks for many consumers EstimationAgent.a_init = drawDiscrete(N=Params.num_agents, P=Params.initial_wealth_income_ratio_probs, X=Params.initial_wealth_income_ratio_vals, >>>>>>> eeb37f24755d0c683c9d9efbe5e7447425c98b86 seed=Params.seed) # Draw initial assets for each consumer # Define the objective function for the simulated method of moments estimation def smmObjectiveFxn(DiscFacAdj, CRRA, agent = EstimationAgent,
if __name__ == "__main__": # ================================================================= # ====== Make the list of consumer types for estimation =========== #================================================================== # Set target Lorenz points and K/Y ratio (MOVE THIS TO SetupParams) if Params.do_liquid: lorenz_target = np.array([0.0, 0.004, 0.025,0.117]) KY_target = 6.60 else: # This is hacky until I can find the liquid wealth data and import it lorenz_target = getLorenzShares(Params.SCF_wealth,weights=Params.SCF_weights,percentiles=Params.percentiles_to_match) #lorenz_target = np.array([-0.002, 0.01, 0.053,0.171]) KY_target = 10.26 # Make a vector of initial wealth-to-permanent income ratios a_init = drawDiscrete(N=Params.sim_pop_size,P=Params.a0_probs,X=Params.a0_values,seed=Params.a0_seed) # Make the list of types for this run, whether infinite or lifecycle if Params.do_lifecycle: # Make cohort scaling array cohort_scale = Params.TFP_growth**(-np.arange(Params.total_T+1)) cohort_scale_array = np.tile(np.reshape(cohort_scale,(Params.total_T+1,1)),(1,Params.sim_pop_size)) # Make base consumer types for each education level DropoutType = cstwMPCagent(**Params.init_dropout) DropoutType.a_init = a_init DropoutType.cohort_scale = cohort_scale_array HighschoolType = deepcopy(DropoutType) HighschoolType(**Params.adj_highschool) CollegeType = deepcopy(DropoutType) CollegeType(**Params.adj_college)
None ''' # Get and store states for newly born agents self.aNrmNow[which_agents] = self.aNrmInit[which_agents] # Take directly from pre-specified distribution self.pLvlNow[which_agents] = 1.0 # No variation in permanent income needed 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 agents is currently in return None # Make a lifecycle consumer to be used for estimation, including simulated shocks (plus an initial distribution of wealth) EstimationAgent = TempConsumerType(**Params.init_consumer_objects) # Make a TempConsumerType for estimation EstimationAgent(T_sim = EstimationAgent.T_cycle+1) # Set the number of periods to simulate EstimationAgent.track_vars = ['bNrmNow'] # Choose to track bank balances as wealth EstimationAgent.aNrmInit = drawDiscrete(N=Params.num_agents, P=Params.initial_wealth_income_ratio_probs, X=Params.initial_wealth_income_ratio_vals, seed=Params.seed) # Draw initial assets for each consumer EstimationAgent.makeShockHistory() # Define the objective function for the simulated method of moments estimation def smmObjectiveFxn(DiscFacAdj, CRRA, agent = EstimationAgent, DiscFacAdj_bound = Params.DiscFacAdj_bound, CRRA_bound = Params.CRRA_bound, empirical_data = Data.w_to_y_data, empirical_weights = Data.empirical_weights, empirical_groups = Data.empirical_groups, map_simulated_to_empirical_cohorts = Data.simulation_map_cohorts_to_age_indices): ''' The objective function for the SMM estimation. Given values of discount factor adjuster DiscFacAdj, coeffecient of relative risk aversion CRRA, a base consumer