def setup_grids(self): """ construct grids for states and shocks """ if self.solmethod in ['negm', 'negm_cpp']: self.par.do_marg_u = True # a. states self.par.grid_p = misc.nonlinspace(self.par.p_min, self.par.p_max, self.par.Np, 1.1) self.par.grid_n = misc.nonlinspace(0, self.par.n_max, self.par.Nn, 1.1) self.par.grid_m = misc.nonlinspace(0, self.par.m_max, self.par.Nm, 1.1) self.par.grid_x = misc.nonlinspace(0, self.par.x_max, self.par.Nx, 1.1) # b. post-decision states self.par.grid_a = misc.nonlinspace(0, self.par.a_max, self.par.Na, 1.1) # c. shocks shocks = misc.create_shocks(self.par.sigma_psi, self.par.Npsi, self.par.sigma_xi, self.par.Nxi, self.par.pi, self.par.mu) self.par.psi, self.par.psi_w, self.par.xi, self.par.xi_w, self.par.Nshocks = shocks # d. set seed np.random.seed(self.par.sim_seed) # e. timing self.par.time_w = np.zeros(self.par.T) self.par.time_keep = np.zeros(self.par.T) self.par.time_adj = np.zeros(self.par.T)
def create_grids(self): """ construct grids for states and shocks """ par = self.par if self.solmethod in ['negm', 'negm_cpp', 'negm_2d_cpp']: par.do_marg_u = True # a. states par.grid_p = nonlinspace(par.p_min, par.p_max, par.Np, 1.1) par.grid_n = nonlinspace(0, par.n_max, par.Nn, 1.1) par.grid_m = nonlinspace(0, par.m_max, par.Nm, 1.1) par.grid_x = nonlinspace(0, par.x_max, par.Nx, 1.1) # b. post-decision states par.grid_a = nonlinspace(0, par.a_max, par.Na, 1.1) # c. shocks shocks = create_shocks(par.sigma_psi, par.Npsi, par.sigma_xi, par.Nxi, par.pi, par.mu) par.psi, par.psi_w, par.xi, par.xi_w, par.Nshocks = shocks # d. set seed np.random.seed(par.sim_seed) # e. timing par.time_w = np.zeros(par.T) par.time_keep = np.zeros(par.T) par.time_adj = np.zeros(par.T) par.time_adj_full = np.zeros(par.T) par.time_adj_d1 = np.zeros(par.T) par.time_adj_d2 = np.zeros(par.T)
def setup_grids(self): """ construct grids for states and shocks """ # a. states (unequally spaced vectors of length Nm) self.par.grid_m = misc.nonlinspace(1e-6, 20, self.par.Nm, 1.1) self.par.grid_p = misc.nonlinspace(1e-4, 10, self.par.Np, 1.1) # b. post-decision states (unequally spaced vector of length Na) self.par.grid_a = misc.nonlinspace(1e-6, 20, self.par.Na, 1.1) # c. shocks (qudrature nodes and weights using GaussHermite) shocks = misc.create_shocks(self.par.sigma_psi, self.par.Npsi, self.par.sigma_xi, self.par.Nxi, self.par.pi, self.par.mu) self.par.psi, self.par.psi_w, self.par.xi, self.par.xi_w, self.par.Nshocks = shocks # d. set seed np.random.seed(self.par.sim_seed)
def grids(par): """ construct grids for states and shocks """ # a. a-grid (unequally spaced vector of length Na) par.grid_a = misc.nonlinspace(par.tol, par.a_max, par.Na, par.a_phi) # b. shocks (quadrature nodes and weights for GaussHermite) par.xi = np.nan * np.zeros((len(par.MA), par.Nxi)) par.xi_w = np.nan * np.zeros((len(par.MA), par.Nxi)) for ma in range(len(par.MA)): par.xi[ma], par.xi_w[ma] = funs.GaussHermite_lognorm( par.var[ma], par.Nxi) # # c. correlated shocks for joint labor income (only for couples) if par.couple: par.xi_corr, par.w_corr = funs.GH_lognorm_corr(par.var, par.cov, par.Nxi_men, par.Nxi_women)
def ss_calib(calib, settings): # Load income tax functions with open('Tax_Function_Fit/cs_avg.pickle', 'rb') as f: cs_avg = pickle.load(f) with open('Tax_Function_Fit/cs_marg.pickle', 'rb') as f: cs_marg = pickle.load(f) # Grids nA = 250 nBeta = 5 ne = 11 nN = 2 amax = 50 e_grid, pi_ern, Pi_ern = utils.markov_rouwenhorst(rho= 0.94, sigma= 0.7, N=ne) # Values from IMPC: rho = 0.91, variance = 0.92. Floden and linde (2001) for Sweden persistence values. nPoints = [nBeta, ne, nA] beta_mid_guess = 0.96513206 beta_var_guess = 0.02 beta_disp_guess = 0.06 vphi_guess = 2.125509040803471 nonlintax_guess = 0.049834087883106254 kappa_g = 0.04 dist_type = "LeftSkewed" beta, pi_beta, Pi_beta = beta_dist(nBeta, beta_mid_guess, beta_var_guess, beta_disp_guess, dist_type ) N = 0.95 b_ratio = 0.51 mix = 0 destr = 0.1 eis = 0.5 frisch = 0.5 alpha = 0.35 G = 0.24 VAT = 0 U = 0.05 Y = 1 N = 1 - U S, q, pMatch, V, Tight, ma, destrO, destrNO, nPos = SAM_calib(U, destr, settings) Eq = q pi_N = [N,1-N] Pi_N = np.empty([2,2]) Pi_N[0,0] = 1 - destr * (1-q) Pi_N[0,1] = destr * (1-q) Pi_N[1,1] = 1 - q * (1-destrO) Pi_N[1,0] = q * (1-destrO) Pi = np.kron(np.kron(Pi_beta, Pi_ern), Pi_N) pi_e = np.kron(np.kron(pi_beta, pi_ern), pi_N) Pi_seed = pi_e r = 0.02 / 4 # 2% yearly rstar = r P = 1 pi = 0 i = r + pi Benefit_type = 0 # proportional to e_grid vacK_rate = 0.05 w_g = 0.58 vacK_g = vacK_rate * w_g * N K = 8 mup = 1.1 mc = 1 / mup destr_L = destr destrO_L = destrO A_tot = 2.3 B = A_tot * 0.5 p = A_tot - B T_firms_g = 0 F_cost_g = 0.05 Agg_C_guess = 0.4 if settings['Fvac_share']: Fvac_factor = settings['Fvac_factor'] else: Fvac_factor = 5 def Asset_calib(x): T_firms_g, Agg_C_g, vacK_g, F_cost_g, w_g = x U_inc_g, U_inc_agg_g = Unemp_benefit(Benefit_type, w_g * b_ratio, e_grid, pi_ern, ne, w_g) ssAvgInc = N * w_g + (1-N) * U_inc_agg_g tax_N = N * np.vdot(avgTaxf(w_g * e_grid, ssAvgInc, cs_avg) * w_g * e_grid , pi_ern) tax_S = (1-N) * np.vdot(avgTaxf(U_inc_g, ssAvgInc, cs_avg) * U_inc_g, pi_ern) mc = 1/mup rk = alpha * mc * Y / K delta = rk - r I = K * delta b = optimize.fsolve(b_calib, [w_g * 0.5], args = (Benefit_type, e_grid, pi_ern, ne, w_g, b_ratio, N, cs_avg, avgTaxf) ) U_inc, U_inc_agg = Unemp_benefit(Benefit_type, b, e_grid, pi_ern, ne, w_g) MPL = (1-alpha) * mc * Y / N if settings['SAM_model'] == 'Standard': JV = 0 JM = (MPL - w_g) / (1 - (1-destr) /(1+r)) LS_res = JV - (- vacK_g + pMatch * JM) Vac_costs = vacK_g elif settings['SAM_model'] == 'Costly_vac_creation': if Fvac_factor == np.inf: Fvac = vacK_g / nPos vacK_g = 0 else: if settings['Fvac_share']: Tot_cost = vacK_g #+ Fvac * nPos Fvac = Fvac_factor * Tot_cost / nPos vacK_g = Tot_cost - Fvac * nPos else: Fvac = Fvac_factor / (nPos / vacK_g) JV = Fvac * nPos if settings['SAM_model_variant'] == 'simple': JM = (MPL - w_g) / (1 - (1-destr) /(1+r)) LS_res = JV - (- vacK_g + pMatch * JM + (1-pMatch) * JV / (1+r)) else: JM = (JV - (1-pMatch) *(1-destrO) * JV /(1+r) + vacK_g) / pMatch LS_res = JM - ((MPL-w_g) + (1-destrO) * (1-destrNO)/(1+r) * JM + destrNO * (1-destrO) * JV /(1+r)) Vac_costs = vacK_g + Fvac * nPos**2 div = 1 - w_g * N - I - Vac_costs - F_cost_g - T_firms_g p_res = div / r - p A_tot_ = p + B G_rev = tax_N + tax_S + VAT * Agg_C_g + B + T_firms_g G_exp = G + U_inc_agg * (1-N) + B * (1 + r) lumpsum_T_res = G_rev - G_exp Agg_C = (ssAvgInc - tax_N - tax_S + A_tot_ * r ) / (1+VAT) A2I = (p + B) / (ssAvgInc - tax_N - tax_S + A_tot_ * r - A_tot_ * kappa_g * 0.15 ) w_res = ( MPL / w_g-1) - settings['vac2w_costs'] return np.array([lumpsum_T_res, Agg_C - Agg_C_g, LS_res, p_res, w_res]) sol = optimize.root(Asset_calib, np.array([T_firms_g, Agg_C_guess, vacK_g, F_cost_g, w_g]), method='hybr') (T_firms, Agg_C, vacK, F_cost, w) = sol.x if not sol.success: raise Exception("Solver did not succeed") lumpsum_T = 0 rk = alpha * mc / K delta = rk - r I = K * delta Fvac = Fvac_factor / (nPos / vacK) assert w > 0 assert vacK >= 0 wss = w sBorrow = 0.5 a_lb = -w * sBorrow a_grid = nonlinspace(a_lb , amax, nA, 1.5) b = optimize.fsolve(b_calib, [w * 0.5], args = (Benefit_type, e_grid, pi_ern, ne, w, b_ratio, N, cs_avg, avgTaxf)) U_inc, U_inc_agg = Unemp_benefit(Benefit_type, b, e_grid, pi_ern, ne, w) ssAvgInc = N * w + (1-N) * U_inc_agg # average taxable labor income in steady state tax_N = N * np.vdot(avgTaxf(w * e_grid, ssAvgInc, cs_avg) * w * e_grid , pi_ern) tax_S = (1-N) * np.vdot(avgTaxf(U_inc, ssAvgInc, cs_avg) * U_inc, pi_ern) Z = Y / (K ** alpha * N**(1-alpha)) Zss = Z MPL = (1-alpha) * mc * Y / N Tight = V / S if settings['SAM_model'] == 'Standard': Vac_costs = vacK JV = 0 JM = (MPL - w) / (1 - (1-destr) /(1+r)) elif settings['SAM_model'] == 'Costly_vac_creation': if settings['Fvac_share']: Tot_cost = vacK #+ Fvac * nPos Fvac = Fvac_factor * Tot_cost / nPos vacK = Tot_cost - Fvac * nPos else: if Fvac_factor == np.inf: Fvac = vacK / nPos vacK = 0 else: Fvac = Fvac_factor / (nPos / vacK) JV = Fvac * nPos Vac_costs = vacK + Fvac * nPos**2 if settings['SAM_model_variant'] == 'simple': JM = (MPL - w) / (1 - (1-destr) /(1+r)) else: JM = (JV - (1-pMatch) *(1-destrO) * JV /(1+r) + vacK) / pMatch div = 1 - w * N - I - Vac_costs - F_cost - T_firms p = div / r MF_Div = 0 mix = 0 ra_test = (div + p) / A_tot + (1+r ) * B / A_tot - (1 + r) ra = r assert abs(ra_test) < 1e-07 Agg_C = (ssAvgInc - tax_N - tax_S + lumpsum_T + A_tot * r ) / (1+VAT) walras1 = 1 - Agg_C - I - G - Vac_costs - F_cost print('Walras 1', walras1) #assert abs(walras1) < 1e-8 #print((100*Vac_costs/0.7)/(w)) beta_max = 1/(1+ra) assert max(beta) < beta_max Tss = lumpsum_T + nonlintax_guess T_dist = 0.1 T = transfers(pi_ern, Tss, e_grid, T_dist) bnds = [-8, 8] args = (U_inc, w, pi_ern, e_grid, N, div , Tss, ssAvgInc, cs_avg, transfers, avgTaxf) res = optimize.minimize_scalar(Income_gini, np.array([T_dist]), method='Bounded', bounds = bnds, args=args) T_dist = res.x Income_gini_disp(x = T_dist, args = args) #Tss = lumpsum_T Ttd = 0 ttd_inf = {'p75' : 0, 'ss_dist' : np.zeros((ne*nBeta, nA)) } # initialize guess for policy function iteration s_match = True use_saved = settings['use_saved'] save = settings['save'] if use_saved == True: try: npzfile = np.load('init_values.npz') EVa = npzfile['x'] if (EVa.shape == (nBeta*ne*nN, nA)) is False: # check that loaded values match in shape s_match = False except OSError as e: s_match = False if s_match == False or use_saved == False: coh_n = np.reshape( (1-avgTaxf(w * e_grid , ssAvgInc, cs_avg)) * w * e_grid + T, ((1, ne, 1))) coh_s = np.reshape( (1-avgTaxf(b * e_grid, ssAvgInc, cs_avg)) * b * e_grid + T , ((1, ne, 1))) coh_n = np.reshape(np.broadcast_to(coh_n, (nBeta,ne, nA)), (ne*nBeta, nA)) coh_s = np.reshape(np.broadcast_to(coh_s, (nBeta,ne, nA)), (ne*nBeta, nA)) EnVa = (1 + r) * (0.8 * coh_n) ** (-1 / eis) EuVa = (1 + r) * (0.8 * (coh_s )) ** (-1 / eis) EVa = np.reshape(np.stack((np.reshape(EnVa, (nBeta, ne, nA)), np.reshape(EuVa, (nBeta, ne, nA))), axis=-2), (nBeta* ne*nN, nA)) ssc = np.ones([EVa.size]) #beta_mid_guess, beta_var_guess, beta_disp_guess, obj = init_search() lumpsum_T_init = lumpsum_T Tss = lumpsum_T args = {} args = { 'EVa' : EVa, 'Pi' : Pi, 'dist_type' : dist_type, 'nBeta' : nBeta, 'Pi_ern' : Pi_ern, 'a_grid' : a_grid, 'pi_e' : pi_e, 'ssN' : N, 'e_grid' : e_grid, 'pi_ern' : pi_ern, 'w' : w, 'ra' : ra, 'eis' : eis, 'Eq' : q, 'N' : N, 'destr_L' : destr, 'U_inc' : U_inc, 'T_dist' : T_dist, 'div' : div, 'lumpsum_T_init' : lumpsum_T_init, 'ssAvgInc' : ssAvgInc, 'VAT' : VAT, 'pi' : pi, 'rstar' : rstar, 'MF_Div' : MF_Div, 'mix' : mix, 'wss' : w, 'nPoints' : nPoints, 'cs_avg' : cs_avg, 'dist_type' : dist_type, 'B' : B, 'rss' : r, 'p' : p , 'sBorrow' : sBorrow, 'hss' : 1, 'T_firms' : T_firms, 'beta_max' : beta_max, 'ttd_inf' : ttd_inf, 'K' : K, 'Tss' : Tss, 'frisch' : frisch, 'G' : G, 'P' : P, 'P_lag' : P, 'N_' : N, 'tax_N' : tax_N, 'a_lb' : a_lb, 'b' : b, 'Benefit_type' : Benefit_type, 'Pi_seed' : Pi_seed, 'Ttd' : Ttd, 'Tuni' :0, 'pi_N' : pi_N, 'Pi_N' : Pi_N, 'Agg_C' : Agg_C, 'tax_S' : tax_S, 'destrO_L' : destrO, 'ssflag' : True} if (calib == 'Full_calib') or (calib == 'Partial_calib'): if calib == 'Full_calib': res1 = optimize.minimize(res_calib_2, np.array([beta_mid_guess, beta_var_guess, beta_disp_guess, vphi_guess, kappa_g]), method='Nelder-Mead', args=args, tol = 1e-5) beta_mid_guess, beta_var, beta_disp, vphi_guess, nonlintax_guess, kappa = res1.x beta_var_guess = beta_var beta_disp_guess = beta_disp kappa_g = kappa # partial calib kappa = kappa_g beta_var = beta_var_guess beta_disp = beta_disp_guess args.update({'beta_var' : beta_var, 'beta_disp' : beta_disp, 'kappa' : kappa}) print('Beta distribution:', beta_mid_guess, beta_var_guess, beta_disp_guess ) print('Labor supply', vphi_guess, nonlintax_guess) res = optimize.root(res_calib_3_root, [beta_mid_guess], args=args, method='hybr') beta_mid = res.x beta, pi_beta, Pi_beta = beta_dist(nBeta, beta_mid, beta_var, beta_disp, dist_type ) Pi = np.kron(np.kron(Pi_beta, Pi_ern), Pi_N) pi_e = np.kron(np.kron(pi_beta, pi_ern), pi_N) Pi_seed = pi_e elif calib == 'Solve' : beta_mid = beta_mid_guess beta_var = beta_var_guess beta_disp = beta_disp_guess vphi = vphi_guess kappa = kappa_g else : raise ValueError('No calibration chosen!') args.update({'beta' : beta, 'kappa' : kappa, 'Pi_seed' : Pi_seed, 'pi_e' : pi_e, 'Pi' : Pi, 'pi_beta' : pi_beta }) print(beta_mid, beta_var, beta_disp) ss = EGMhousehold.ss(**args) if save == True: np.savez('init_values', x = ss['EVa']) # Short run parameters not identified/needed in SS phi = 1.3 kappak = 6 eps_p = mup / (mup-1) kappap = (eps_p-1) / 0.03 Agg_C = (ssAvgInc - tax_N - tax_S + Tss + (p + B) * r) / (1+VAT) sc_neg = np.nonzero(ss['a'] < 0) walras = 1 - ss['C'] - I - G - Vac_costs - F_cost + kappa * ss['A_DEBT'] G_rev = ss['TINC'] + VAT * ss['C'] + B + T_firms G_exp = G + ss['UINCAGG'] + Tss + B * (1 + r) print('Walras 2', walras) print('Asset market err', ss['A']-(B+p), 'G_budget', G_rev - G_exp) ss.update({'goods_mkt' : walras}) a_pop = ss['a'] sc = np.nonzero(ss['a'] < a_lb + 1e-7) print( 100 * sum(ss['D'][sc])) print( 100 * sum(ss['D'][sc_neg])) print(IneqStat(ss, nPoints, a_lb)) ss.update({'V': V, 'vacK' : vacK, 'pMatch' : pMatch, 'q': q, 'N' : N, 'B': B, 'kappap': kappap, 'Y': Y, 'rstar': r, 'Z': Z, 'mup': mup, 'pi': pi, 'Pi' : Pi, 'eps_p' : eps_p, 'Pi_seed' : pi_e, 'MPL' : MPL, 'eps_r' : 0, 'mu' : 0, 'destr_L' : destr, 'destrO_L' : destrO, 'K': K, 'alpha': alpha, 'delta': delta, 'I': I, 'S': S, 'G' : G, 'div' : div, 'phi' : phi, 'T_dist' : T_dist, 'Tuni' : 0, 'ttd_inf' : ttd_inf, 'L' : N, 'U_inc' : U_inc, 'Agg_C' : Agg_C, 'p' : p, 'T_rate' : 1, 'ssN' : N, 'pshare' : p/ss['A'], 'destrO' : destrO, 'destrNO' : destrNO, 'kappap': kappap, 'eis': eis, 'beta': beta, 'destr': destr, 'Q': 1, 'mc': mc, 'lumpsum_T' : lumpsum_T, 'Zss' : Zss, 'ra' : r, 'rk' : rk, 'r' : r, 'i' : i, 'Tightss' : Tight, 'ma' : ma, 'piw' : 0, 'a_lb' : a_lb, 'mix' : mix,'Pi_N' : Pi_N, 'pi_N' : pi_N, 'Nss' : N, 'wss' : w, 'MF_Div' : MF_Div, 'G_rev' : G_rev, 'G_exp': G_exp, 'P' : 1, 'Tss' : lumpsum_T, 'Ttd' : Ttd, 'Z_I' : 1, 'Isip' :0, 'rss' : r, 'F_cost' : F_cost, 're' : r, 'b_ratio' : b_ratio, 'rg' : r, 'dist_type' : dist_type, 'Fvac' : Fvac, 'VAT': VAT, 'pi_ern' : pi_ern, 'ssAvgInc' : ssAvgInc, 'b' : b, 'Tight' : Tight, 'psip' : 0, 'isip' : 0, 'K_cost' : 0, 'kappak' : kappak, 'cs_avg' : cs_avg, 'Bss' : B, 'epsI' :4, 'Benefit_type' : Benefit_type, 'div_' : div, 'UINCAGG_count' : ss['UINCAGG'], 'T_firms' : T_firms, 'beta_mid' : beta_mid, 'beta_var' : beta_var, 'beta_disp' : beta_disp, 'uT' : 0, 'div_MF' : 0, 'nPos' : nPos, 'JV' : JV, 'JM' : JM, 'ssflag': False}) print('Average Beta' , np.vdot(beta, pi_beta)) # Check bargaining set upper_lvl = (1-alpha) * mc / N lower_lvl = b assert w < upper_lvl assert w > lower_lvl ss.update({'A_agg' : ss['A'], 'C_agg' : ss['C'], 'taxes' : ss['TINC']}) # steady state values for endo. destr. rate ss.update({'destrNOss' : destrNO, 'JMss' : JM, 'eps_m' : 0.5}) ss.update({'destrOss' : destrO, 'JVss' : JV, 'eps_V' : 0.5, 'muV' : 0 }) # Check that income is strictly positive assert min(ss['Inc'].flatten()) > 0 return ss
def create_grids(self): """ create grids and other preperations for solving the model""" par = self.par # a. perfect foresight or buffer-stock model if par.sigma_xi == 0 and par.sigma_psi == 0 and par.low_p == 0: # no risk self.model = 'pf' # perfect foresight else: self.model = 'bs' # buffer-stock # b. shocks # i. basic GuassHermite psi, psi_w = normal_gauss_hermite(sigma=par.sigma_psi, n=par.Npsi) xi, xi_w = normal_gauss_hermite(sigma=par.sigma_xi, n=par.Nxi) # ii. add low income shock to xi if par.low_p > 0: # a. weights xi_w *= (1.0 - par.low_p) xi_w = np.insert(xi_w, 0, par.low_p) # b. values xi = (xi - par.low_val * par.low_p) / (1.0 - par.low_p) xi = np.insert(xi, 0, par.low_val) # iii. vectorize tensor product of shocks and total weight psi_vec, xi_vec = np.meshgrid(psi, xi, indexing='ij') psi_w_vec, xi_w_vec = np.meshgrid(psi_w, xi_w, indexing='ij') par.psi_vec = psi_vec.ravel() par.xi_vec = xi_vec.ravel() par.w = xi_w_vec.ravel() * psi_w_vec.ravel() assert 1 - np.sum(par.w) < 1e-8 # == summing to 1 # iv. count number of shock nodes par.Nshocks = par.w.size # c. minimum a if par.borrowingfac == 0: par.a_min = np.zeros(par.T) # never any borriwng else: # using formula from slides psi_min = np.min(par.psi_vec) xi_min = np.min(par.xi_vec) par.a_min = np.nan * np.ones(par.T) for t in reversed(range(par.T - 1)): if t >= par.TR - 1: # in retirement Omega = 0 elif t == par.TR - 2: # next period is retirement Omega = par.R**(-1) * par.G * par.L[t + 1] * psi_min * xi_min else: # before retirement Omega = par.R**(-1) * (np.fmin(Omega, par.borrowingfac) + xi_min) * par.G * par.L[t + 1] * psi_min par.a_min[t] = -np.fmin( Omega, par.borrowingfac) * par.G * par.L[t + 1] * psi_min # d. end-of-period assets and cash-on-hand par.grid_a = np.nan * np.ones((par.T, par.Na)) par.grid_m = np.nan * np.ones((par.T, par.Nm)) for t in range(par.T): par.grid_a[t, :] = nonlinspace(par.a_min[t] + 1e-6, par.a_max, par.Na, par.a_phi) par.grid_m[t, :] = nonlinspace(par.a_min[t] + 1e-6, par.m_max, par.Nm, par.m_phi) # e. conditions par.FHW = par.G / par.R par.AI = (par.R * par.beta)**(1 / par.rho) par.GI = par.AI * np.sum(par.w * par.psi_vec**(-1)) / par.G par.RI = par.AI / par.R par.WRI = par.low_p**(1 / par.rho) * par.AI / par.R par.FVA = par.beta * np.sum(par.w * (par.G * par.psi_vec)**(1 - par.rho)) # f. fast solution with EGM # grid_a tiled with the number of shocks par.grid_a_tile = np.ones((par.TR, par.Na * par.Nshocks)) for t in range(par.TR): par.grid_a_tile[t, :] = np.tile(par.grid_a[t, :], par.Nshocks) # xi, psi and w repeated with the number of grid points for a par.xi_vec_rep = np.repeat(par.xi_vec, par.Na) par.psi_vec_rep = np.repeat(par.psi_vec, par.Na) par.w_rep = np.repeat(par.w, par.Na) # g. check for existance of solution self.print_and_check_parameters(do_print=False)
def create_grids(self): """ construct grids for states and shocks """ par = self.par # b. shocks # i. basic GuassHermite psi, psi_w = normal_gauss_hermite(sigma=par.sigma_psi, n=par.Npsi) xi, xi_w = normal_gauss_hermite(sigma=par.sigma_xi, n=par.Nxi) # ii. add low income shock to xi if par.pi > 0: # a. weights xi_w *= (1.0 - par.pi) xi_w = np.insert(xi_w, 0, par.pi) # b. values xi = (xi - par.mu * par.pi) / (1.0 - par.pi) xi = np.insert(xi, 0, par.mu) # iii. vectorize tensor product of shocks and total weight psi_vec, xi_vec = np.meshgrid(psi, xi, indexing='ij') psi_w_vec, xi_w_vec = np.meshgrid(psi_w, xi_w, indexing='ij') par.psi_vec = psi_vec.ravel() par.xi_vec = xi_vec.ravel() par.w = xi_w_vec.ravel() * psi_w_vec.ravel() assert 1 - np.sum(par.w) < 1e-8 # == summing to 1 # iv. count number of shock nodes par.Nshocks = par.w.size # c. minimum a if par.borrowingfac == 0: par.a_min = np.zeros(par.T) # never any borriwng else: # using formula from slides psi_min = np.min(par.psi_vec) xi_min = np.min(par.xi_vec) par.a_min = np.ones(par.T) for t in reversed(range(par.T - 1)): if t >= par.TR - 1: # in retirement Omega = 0 elif t == par.TR - 2: # next period is retirement Omega = par.R**(-1) * par.G * par.L[t + 1] * psi_min * xi_min else: # before retirement Omega = par.R**(-1) * (np.fmin(Omega, par.borrowingfac) + xi_min) * par.G * par.L[t + 1] * psi_min par.a_min[t] = -np.fmin( Omega, par.borrowingfac) * par.G * par.L[t + 1] * psi_min # d. end-of-period assets and cash-on-hand par.grid_a = np.ones((par.T, par.Na)) par.grid_m = np.ones((par.T, par.Nm)) for t in range(par.T): par.grid_a[t, :] = nonlinspace(par.a_min[t] + 1e-6, par.a_max, par.Na, par.a_phi) par.grid_m[t, :] = nonlinspace(par.a_min[t] + 1e-6, par.m_max, par.Nm, par.m_phi) # e. conditions par.FHW = np.float(par.G / par.R) par.AI = np.float((par.R * par.beta)**(1 / par.rho)) par.GI = np.float(par.AI * np.sum(par.w * par.psi_vec**(-1)) / par.G) par.RI = np.float(par.AI / par.R) par.WRI = np.float(par.pi**(1 / par.rho) * par.AI / par.R) par.FVA = np.float( par.beta * np.sum(par.w * (par.G * par.psi_vec)**(1 - par.rho))) # g. check for existance of solution self.check(do_print=False)