def evalSocialOptimum(self): ''' Execute a simulation run that calculates "socially optimal" objects. ''' self.update() self.solve() self.CalcSocialOptimum = True self.initializeSim() self.simulate() self.iLvlSocOpt_histX = deepcopy(self.iLvlSocOpt_hist) self.CopaySocOpt_histX = deepcopy(self.CopaySocOpt_hist) self.LifePriceSocOpt_histX = deepcopy(self.LifePriceSocOpt_hist) self.CumLivPrb_histX = deepcopy(self.CumLivPrb_hist) self.CalcSocialOptimum = False try: Health = self.hLvlNow_hist.flatten() Weights = self.CumLivPrb_hist.flatten() Copays = self.CopaySocOpt_hist.flatten() Age = np.tile( np.reshape(np.arange(self.T_cycle), (self.T_cycle, 1)), (1, self.AgentCount)).flatten() AgeSq = Age**2. HealthSq = Health**2 Ones = np.ones_like(Health) AgeHealth = Age * Health AgeHealthSq = Age * HealthSq AgeSqHealth = AgeSq * Health AgeSqHealthSq = AgeSq * HealthSq these = np.logical_not(np.isnan(Copays)) regressors = np.transpose( np.vstack((Ones, Health, HealthSq, Age, AgeHealth, AgeHealthSq, AgeSq, AgeSqHealth, AgeSqHealthSq))) copay_model = WLS(Copays[these], regressors[these, :], weights=Weights[these]) coeffs = (copay_model.fit()).params UpperCopayFunc = ConstantFunction(1.0) LowerCopayFunc = ConstantFunction(0.01) OptimalCopayInvstFunc = [] for t in range(self.T_cycle): c0 = coeffs[0] + t * coeffs[3] + t**2 * coeffs[6] c1 = coeffs[1] + t * coeffs[4] + t**2 * coeffs[7] c2 = coeffs[2] + t * coeffs[5] + t**2 * coeffs[8] TempFunc = QuadraticFunction(c0, c1, c2) OptimalCopayInvstFunc_t = UpperEnvelope( LowerEnvelope(TempFunc, UpperCopayFunc), LowerCopayFunc) OptimalCopayInvstFunc.append(OptimalCopayInvstFunc_t) except: for t in range(self.T_cycle): OptimalCopayInvstFunc.append(ConstantFunction(1.0)) self.OptimalCopayInvstFunc = OptimalCopayInvstFunc self.delSolution()
def usePointsForInterpolation(self, cNrm, mNrm, interpolator): ''' Make a basic solution object with a consumption function and marginal value function (unconditional on the preference shock). Parameters ---------- cNrm : np.array Consumption points for interpolation. mNrm : np.array Corresponding market resource points for interpolation. interpolator : function A function that constructs and returns a consumption function. Returns ------- solution_now : ConsumerSolution The solution to this period's consumption-saving problem, with a consumption function, marginal value function, and minimum m. ''' # Make the preference-shock specific consumption functions PrefShkCount = self.PrefShkVals.size cFunc_list = [] for j in range(PrefShkCount): MPCmin_j = self.MPCminNow * self.PrefShkVals[j]**(1.0 / self.CRRA) cFunc_this_shock = LowerEnvelope( LinearInterp(mNrm[j, :], cNrm[j, :], intercept_limit=self.hNrmNow * MPCmin_j, slope_limit=MPCmin_j), self.cFuncNowCnst) cFunc_list.append(cFunc_this_shock) # Combine the list of consumption functions into a single interpolation cFuncNow = LinearInterpOnInterp1D(cFunc_list, self.PrefShkVals) # Make the ex ante marginal value function (before the preference shock) m_grid = self.aXtraGrid + self.mNrmMinNow vP_vec = np.zeros_like(m_grid) for j in range( PrefShkCount): # numeric integration over the preference shock vP_vec += self.uP(cFunc_list[j]( m_grid)) * self.PrefShkPrbs[j] * self.PrefShkVals[j] vPnvrs_vec = self.uPinv(vP_vec) vPfuncNow = MargValueFunc(LinearInterp(m_grid, vPnvrs_vec), self.CRRA) # Store the results in a solution object and return it solution_now = ConsumerSolution(cFunc=cFuncNow, vPfunc=vPfuncNow, mNrmMin=self.mNrmMinNow) return solution_now
def makeBasicSolution(self, EndOfPrdvP, aNrm, wageShkVals, prefShkVals): ''' Given end of period assets and end of period marginal value, construct the basic solution for this period. Parameters ---------- EndOfPrdvP : np.array Array of end-of-period marginal values. aNrm : np.array Array of end-of-period asset values that yield the marginal values in EndOfPrdvP. wageShkVals : np.array Array of this period transitory wage shock values. prefShkVals : np.array Array of this period preference shock values. Returns ------- solution_now : ConsumerSolution The solution to this period's consumption-saving problem, with a consumption function, marginal value function. ''' num_pref_shocks = len(prefShkVals) num_wage_shocks = len(wageShkVals) cFuncBaseByPref_list = [] vPFuncBaseByPref_list = [] lFuncBaseByPref_list = [] for i in range(num_wage_shocks): cFuncBaseByPref_list.append([]) vPFuncBaseByPref_list.append([]) lFuncBaseByPref_list.append([]) for j in range(num_pref_shocks): c_temp = self.uPinv(EndOfPrdvP / prefShkVals[j]) l_temp = self.LabSupply(wageShkVals[i] * EndOfPrdvP) b_temp = c_temp + aNrm - l_temp * wageShkVals[i] if wageShkVals[i] == 0.0: c_temp = np.insert(c_temp, 0, 0., axis=-1) l_temp = np.insert(l_temp, 0, 0.0, axis=-1) b_temp = np.insert(b_temp, 0, 0.0, axis=-1) lFuncBaseByPref_list[i].append( LinearInterp(b_temp, l_temp, lower_extrap=True)) cFunc1 = LinearInterp(b_temp, c_temp, lower_extrap=True) cFunc2 = LinearInterp(b_temp, l_temp * wageShkVals[i] + b_temp, lower_extrap=True) cFuncBaseByPref_list[i].append(LowerEnvelope(cFunc1, cFunc2)) pseudo_inverse_vPfunc1 = LinearInterp( b_temp, prefShkVals[j]**(-1.0 / self.CRRA) * c_temp, lower_extrap=True) pseudo_inverse_vPfunc2 = LinearInterp( b_temp, prefShkVals[j]**(-1.0 / self.CRRA) * (l_temp * wageShkVals[i] + b_temp), lower_extrap=True) pseudo_inverse_vPfunc = LowerEnvelope(pseudo_inverse_vPfunc1, pseudo_inverse_vPfunc2) vPFuncBaseByPref_list[i].append( MargValueFunc(pseudo_inverse_vPfunc, self.CRRA)) cFuncNow = BilinearInterpOnInterp1D(cFuncBaseByPref_list, wageShkVals, prefShkVals) vPfuncNow = BilinearInterpOnInterp1D(vPFuncBaseByPref_list, wageShkVals, prefShkVals) lFuncNow = BilinearInterpOnInterp1D(lFuncBaseByPref_list, wageShkVals, prefShkVals) # Pack up and return the solution solution_now = ConsumerSolution(cFunc=cFuncNow, vPfunc=vPfuncNow) solution_now.lFunc = lFuncNow return solution_now