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 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 initializeAges(self): ''' Assign initial values of t_cycle to simulated agents, using the attribute LRageDstn as the distribution of discrete ages. ''' age = drawDiscrete(self.AgentCount, X=self.LRageDstn[1], P=self.LRageDstn[0], exact_match=False, seed=self.RNG.randint(0,2**31-1)) age = age.astype(int) self.t_cycle = age self.t_age = age
def getShocks(self): ''' Gets new Markov states and permanent and transitory income shocks for this period. Samples from IncomeDstn for each period-state in the cycle. Parameters ---------- None Returns ------- None ''' # Get new Markov states for each agent if self.global_markov: base_draws = np.ones(self.AgentCount)*drawUniform(1,seed=self.RNG.randint(0,2**31-1)) else: base_draws = self.RNG.permutation(np.arange(self.AgentCount,dtype=float)/self.AgentCount + 1.0/(2*self.AgentCount)) newborn = self.t_age == 0 # Don't change Markov state for those who were just born (unless global_markov) MrkvPrev = self.MrkvNow MrkvNow = np.zeros(self.AgentCount,dtype=int) for t in range(self.T_cycle): Cutoffs = np.cumsum(self.MrkvArray[t],axis=1) for j in range(self.MrkvArray[t].shape[0]): these = np.logical_and(self.t_cycle == t,MrkvPrev == j) MrkvNow[these] = np.searchsorted(Cutoffs[j,:],base_draws[these]).astype(int) if not self.global_markov: MrkvNow[newborn] = MrkvPrev[newborn] self.MrkvNow = MrkvNow.astype(int) # Now get income shocks for each consumer, by cycle-time and discrete state PermShkNow = np.zeros(self.AgentCount) # Initialize shock arrays TranShkNow = np.zeros(self.AgentCount) for t in range(self.T_cycle): for j in range(self.MrkvArray[t].shape[0]): these = np.logical_and(t == self.t_cycle, j == MrkvNow) N = np.sum(these) if N > 0: IncomeDstnNow = self.IncomeDstn[t-1][j] # set current income distribution PermGroFacNow = self.PermGroFac[t-1][j] # 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] newborn = self.t_age == 0 PermShkNow[newborn] = 1.0 TranShkNow[newborn] = 1.0 self.PermShkNow = PermShkNow self.TranShkNow = TranShkNow
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
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.
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
def test_drawDiscrete(self): self.assertEqual(simulation.drawDiscrete(1)[0], 0)
# 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)