def updateIncomeProcessAlt(self): ''' An alternative method for constructing the income process in the infinite horizon model, where the labor supply l_bar creates a small oddity. Parameters ---------- none Returns ------- none ''' tax_rate = (self.IncUnemp * self.UnempPrb) / (self.l_bar * (1.0 - self.UnempPrb)) TranShkDstn = deepcopy( approxMeanOneLognormal(self.TranShkCount, sigma=self.TranShkStd[0], tail_N=0)) TranShkDstn[0] = np.insert(TranShkDstn[0] * (1.0 - self.UnempPrb), 0, self.UnempPrb) TranShkDstn[1] = np.insert( self.l_bar * TranShkDstn[1] * (1.0 - tax_rate), 0, self.IncUnemp) PermShkDstn = approxMeanOneLognormal(self.PermShkCount, sigma=self.PermShkStd[0], tail_N=0) self.IncomeDstn = [combineIndepDstns(PermShkDstn, TranShkDstn)] self.TranShkDstn = TranShkDstn self.PermShkDstn = PermShkDstn self.addToTimeVary('IncomeDstn')
def updateIncomeProcess(self): ''' An alternative method for constructing the income process in the infinite horizon model. Parameters ---------- none Returns ------- none ''' if self.cycles == 0: tax_rate = (self.IncUnemp * self.UnempPrb) / ( (1.0 - self.UnempPrb) * self.IndL) TranShkDstn = deepcopy( approxMeanOneLognormal(self.TranShkCount, sigma=self.TranShkStd[0], tail_N=0)) TranShkDstn[0] = np.insert(TranShkDstn[0] * (1.0 - self.UnempPrb), 0, self.UnempPrb) TranShkDstn[1] = np.insert( TranShkDstn[1] * (1.0 - tax_rate) * self.IndL, 0, self.IncUnemp) PermShkDstn = approxMeanOneLognormal(self.PermShkCount, sigma=self.PermShkStd[0], tail_N=0) self.IncomeDstn = [combineIndepDstns(PermShkDstn, TranShkDstn)] self.TranShkDstn = TranShkDstn self.PermShkDstn = PermShkDstn self.addToTimeVary('IncomeDstn') else: # Do the usual method if this is the lifecycle model EstimationAgentClass.updateIncomeProcess(self)
def updatePrefShockProcess(self): ''' Make a discrete preference shock structure for each period in the cycle for this agent type, storing them as attributes of self for use in the solution (and other methods). Parameters ---------- none Returns ------- none ''' time_orig = self.time_flow self.timeFwd() PrefShkDstn = [] # discrete distributions of preference shocks for t in range(len(self.PrefShkStd)): PrefShkStd = self.PrefShkStd[t] PrefShkDstn.append( approxMeanOneLognormal(N=self.PrefShkCount, sigma=PrefShkStd, tail_N=self.PrefShk_tail_N)) # Store the preference shocks in self (time-varying) and restore time flow self.PrefShkDstn = PrefShkDstn self.addToTimeVary('PrefShkDstn') if not time_orig: self.timeRev()
def getShocks(self): ''' Gets permanent and transitory income shocks for this period as well as preference shocks. Parameters ---------- None Returns ------- None ''' IndShockConsumerType.getShocks(self) # Get permanent and transitory income shocks PrefShkNow = np.zeros(self.AgentCount) # Initialize shock array for t in range(self.T_cycle): these = t == self.t_cycle N = np.sum(these) if N > 0: PrefShkNow[these] = self.RNG.permutation(approxMeanOneLognormal(N,sigma=self.PrefShkStd[t])[1]) self.PrefShkNow = PrefShkNow
def constructLognormalIncomeAndPreferenceProcess(parameters): ''' Generates a list of discrete approximations to the income and preference shock process . Permanent shocks are mean one lognormally distributed with standard deviation PermShkStd. Transitory shocks are mean one lognormally distributed Parameters (passed as attributes of the input parameters) ---------- PermShkStd : [float] List of standard deviations in log permanent income uncertainty during the agent's life. PermShkCount : int The number of approximation points to be used in the discrete approxima- tion to the permanent income shock distribution. TranShkStd : [float] List of standard deviations in log transitory income uncertainty during the agent's life. TranShkCount : int The number of approximation points to be used in the discrete approxima- tion to the permanent income shock distribution. PrefShkStd : [float] List of standard deviations in log preference uncertainty during the agent's life. PrefShkCount : int The number of approximation points to be used in the discrete approxima- tion to the preference shock distribution. Returns ------- IncomeAndPrefDstn : [[np.array]] A list with T_cycle elements, each of which is a list of four arrays representing a discrete approximation to the income and preference process in a period. Order: probabilities, permanent shocks, transitory shocks, preference shocks. PermShkDstn : [[np.array]] A list with T_cycle elements, each of which is a list of two arrays representing a discrete approximation to the permanent income shocks. TranShkDstn : [[np.array]] A list with T_cycle elements, each of which is a list of two arrays representing a discrete approximation to the transitory income shocks. PrefShkDstn : [[np.array]] A list with T_cycle elements, each of which is a list of two arrays representing a discrete approximation to the preference shocks. ''' # Unpack the parameters from the input PermShkStd = parameters.PermShkStd PermShkCount = parameters.PermShkCount TranShkStd = parameters.TranShkStd TranShkCount = parameters.TranShkCount PrefShkStd = parameters.PrefShkStd PrefShkCount = parameters.PrefShkCount UnempPrb = parameters.UnempPrb IncUnemp = parameters.IncUnemp IncomeDstn = [] # Discrete approximations to income process in each period PermShkDstn = [] # Discrete approximations to permanent income shocks TranShkDstn = [] # Discrete approximations to transitory income shocks PrefShkDstn = [] # Discrete approximations to preference shocks t = 0 TranShkDstn_t = approxMeanOneLognormal(N=TranShkCount, sigma=TranShkStd[t], tail_N=0) if UnempPrb > 0: TranShkDstn_t = addDiscreteOutcomeConstantMean(TranShkDstn_t, p=UnempPrb, x=IncUnemp) #add in a shock at zero to impose natural borrowing constraint TranShkDstn_t = addDiscreteOutcomeConstantMean(TranShkDstn_t, p=0.000000001, x=0.0) PermShkDstn_t = approxMeanOneLognormal(N=PermShkCount, sigma=PermShkStd[t], tail_N=0) PrefShkDstn_t = approxMeanOneLognormal(N=PrefShkCount, sigma=PrefShkStd[t], tail_N=0) IncomeDstn.append( combineIndepDstns(PermShkDstn_t, TranShkDstn_t, PrefShkDstn_t)) # mix the independent distributions PermShkDstn.append(PermShkDstn_t) TranShkDstn.append(TranShkDstn_t) PrefShkDstn.append(PrefShkDstn_t) return IncomeDstn, PermShkDstn, TranShkDstn, PrefShkDstn
# is actually the true shock structure. That is, that the aggregate state only changes with prob UpdatePrb, # but that the state changes are as if ~1/UpdatePrb periods have elapsed. t_exp_between_updates = int(np.round(1. / UpdatePrb)) PolyMrkvArrayAlt = PolyMrkvArray for t in range(t_exp_between_updates - 1): # Premultiply T-1 times PolyMrkvArrayAlt = np.dot(PolyMrkvArray, PolyMrkvArrayAlt) PolyMrkvArrayAlt *= UpdatePrb # Scale down all transitions so they only happen with UpdatePrb probability PolyMrkvArrayAlt += (1. - UpdatePrb) * np.eye( StateCount) # Move that probability weight to no change # In the alternate specification, agents also think that permanent aggregate shocks only # happen with UpdatePrb probability, but are 1/UpdatePrb times larger when they do happen. # Transitory aggregate shocks are interpreted to be much larger when not updating. PermShkAggVarAlt = PermShkAggVar / UpdatePrb PermShkAggStdAlt = np.sqrt(PermShkAggVarAlt) PermShkAggDstnAlt_update = approxMeanOneLognormal(5, PermShkAggStdAlt) TranShkAggDstnAlt_update = approxMeanOneLognormal(5, np.sqrt(TranShkAggVar)) AggShkDstnAlt_update = combineIndepDstns(PermShkAggDstnAlt_update, TranShkAggDstnAlt_update) AggShkDstnAlt_update[0] *= UpdatePrb PermShkAggDstnAlt_dont = [np.array([1.0]), np.array([1.0])] # Degenerate distribution TranShkAggDstnAlt_dont = approxMeanOneLognormal( 5, np.sqrt(TranShkAggVar + PermShkAggVar / UpdatePrb)) AggShkDstnAlt_dont = combineIndepDstns(PermShkAggDstnAlt_dont, TranShkAggDstnAlt_dont) AggShkDstnAlt_dont[0] *= 1. - UpdatePrb AggShkDstnAlt = StateCount * [[ np.concatenate([AggShkDstnAlt_update[n], AggShkDstnAlt_dont[n]]) for n in range(3) ]]