def SS_solver(b_guess_init, n_guess_init, rss, wss, T_Hss, factor_ss, Yss, params, baseline, fsolve_flag=False, baseline_spending=False): ''' -------------------------------------------------------------------- Solves for the steady state distribution of capital, labor, as well as w, r, T_H and the scaling factor, using a bisection method similar to TPI. -------------------------------------------------------------------- INPUTS: b_guess_init = [S,J] array, initial guesses for savings n_guess_init = [S,J] array, initial guesses for labor supply wguess = scalar, initial guess for SS real wage rate rguess = scalar, initial guess for SS real interest rate T_Hguess = scalar, initial guess for lump sum transfer factorguess = scalar, initial guess for scaling factor to dollars chi_b = [J,] vector, chi^b_j, the utility weight on bequests chi_n = [S,] vector, chi^n_s utility weight on labor supply params = length X tuple, list of parameters iterative_params = length X tuple, list of parameters that determine the convergence of the while loop tau_bq = [J,] vector, bequest tax rate rho = [S,] vector, mortality rates by age lambdas = [J,] vector, fraction of population with each ability type omega = [S,] vector, stationary population weights e = [S,J] array, effective labor units by age and ability type OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION: euler_equation_solver() household.get_K() firm.get_L() firm.get_Y() firm.get_r() firm.get_w() household.get_BQ() tax.replacement_rate_vals() tax.revenue() utils.convex_combo() utils.pct_diff_func() OBJECTS CREATED WITHIN FUNCTION: b_guess = [S,] vector, initial guess at household savings n_guess = [S,] vector, initial guess at household labor supply b_s = [S,] vector, wealth enter period with b_splus1 = [S,] vector, household savings b_splus2 = [S,] vector, household savings one period ahead BQ = scalar, aggregate bequests to lifetime income group theta = scalar, replacement rate for social security benenfits error1 = [S,] vector, errors from FOC for savings error2 = [S,] vector, errors from FOC for labor supply tax1 = [S,] vector, total income taxes paid cons = [S,] vector, household consumption OBJECTS CREATED WITHIN FUNCTION - SMALL OPEN ONLY Bss = scalar, aggregate household wealth in the steady state BIss = scalar, aggregate household net investment in the steady state RETURNS: solutions = steady state values of b, n, w, r, factor, T_H ((2*S*J+4)x1 array) OUTPUT: None -------------------------------------------------------------------- ''' bssmat, nssmat, chi_params, ss_params, income_tax_params, iterative_params, small_open_params = params J, S, T, BW, beta, sigma, alpha, gamma, epsilon, Z, delta, ltilde, nu, g_y,\ g_n_ss, tau_payroll, tau_bq, rho, omega_SS, budget_balance, \ alpha_T, debt_ratio_ss, tau_b, delta_tau,\ lambdas, imm_rates, e, retire, mean_income_data,\ h_wealth, p_wealth, m_wealth, b_ellipse, upsilon = ss_params analytical_mtrs, etr_params, mtrx_params, mtry_params = income_tax_params chi_b, chi_n = chi_params maxiter, mindist_SS = iterative_params small_open, ss_firm_r, ss_hh_r = small_open_params # Rename the inputs r = rss w = wss T_H = T_Hss factor = factor_ss if budget_balance == False: if baseline_spending == True: Y = Yss else: Y = T_H / alpha_T if small_open == True: r = ss_hh_r dist = 10 iteration = 0 dist_vec = np.zeros(maxiter) if fsolve_flag == True: maxiter = 1 while (dist > mindist_SS) and (iteration < maxiter): # Solve for the steady state levels of b and n, given w, r, Y and # factor if budget_balance: outer_loop_vars = (bssmat, nssmat, r, w, T_H, factor) else: outer_loop_vars = (bssmat, nssmat, r, w, Y, T_H, factor) inner_loop_params = (ss_params, income_tax_params, chi_params, small_open_params) euler_errors, bssmat, nssmat, new_r, new_w, \ new_T_H, new_Y, new_factor, new_BQ, average_income_model = inner_loop(outer_loop_vars, inner_loop_params, baseline, baseline_spending) r = utils.convex_combo(new_r, r, nu) w = utils.convex_combo(new_w, w, nu) factor = utils.convex_combo(new_factor, factor, nu) if budget_balance: T_H = utils.convex_combo(new_T_H, T_H, nu) dist = np.array([utils.pct_diff_func(new_r, r)] + [utils.pct_diff_func(new_w, w)] + [utils.pct_diff_func(new_T_H, T_H)] + [utils.pct_diff_func(new_factor, factor)]).max() else: Y = utils.convex_combo(new_Y, Y, nu) if Y != 0: dist = np.array([utils.pct_diff_func(new_r, r)] + [utils.pct_diff_func(new_w, w)] + [utils.pct_diff_func(new_Y, Y)] + [utils.pct_diff_func(new_factor, factor)]).max() else: # If Y is zero (if there is no output), a percent difference # will throw NaN's, so we use an absoluate difference dist = np.array([utils.pct_diff_func(new_r, r)] + [utils.pct_diff_func(new_w, w)] + [abs(new_Y - Y)] + [utils.pct_diff_func(new_factor, factor)]).max() dist_vec[iteration] = dist # Similar to TPI: if the distance between iterations increases, then # decrease the value of nu to prevent cycling if iteration > 10: if dist_vec[iteration] - dist_vec[iteration - 1] > 0: nu /= 2.0 print 'New value of nu:', nu iteration += 1 print "Iteration: %02d" % iteration, " Distance: ", dist ''' ------------------------------------------------------------------------ Generate the SS values of variables, including euler errors ------------------------------------------------------------------------ ''' bssmat_s = np.append(np.zeros((1,J)),bssmat[:-1,:],axis=0) bssmat_splus1 = bssmat rss = r wss = w factor_ss = factor T_Hss = T_H Lss_params = (e, omega_SS.reshape(S, 1), lambdas, 'SS') Lss = firm.get_L(nssmat, Lss_params) if small_open == False: Kss_params = (omega_SS.reshape(S, 1), lambdas, imm_rates, g_n_ss, 'SS') Bss = household.get_K(bssmat_splus1, Kss_params) if budget_balance: debt_ss = 0.0 else: debt_ss = debt_ratio_ss*Y Kss = Bss - debt_ss Iss_params = (delta, g_y, omega_SS, lambdas, imm_rates, g_n_ss, 'SS') Iss = firm.get_I(bssmat_splus1, Kss, Kss, Iss_params) else: # Compute capital (K) and wealth (B) separately Kss_params = (Z, gamma, epsilon, delta, tau_b, delta_tau) Kss = firm.get_K(Lss, ss_firm_r, Kss_params) Iss_params = (delta, g_y, omega_SS, lambdas, imm_rates, g_n_ss, 'SS') InvestmentPlaceholder = np.zeros(bssmat_splus1.shape) Iss = firm.get_I(InvestmentPlaceholder, Kss, Kss, Iss_params) Bss_params = (omega_SS.reshape(S, 1), lambdas, imm_rates, g_n_ss, 'SS') Bss = household.get_K(bssmat_splus1, Bss_params) BIss_params = (0.0, g_y, omega_SS, lambdas, imm_rates, g_n_ss, 'SS') BIss = firm.get_I(bssmat_splus1, Bss, Bss, BIss_params) if budget_balance: debt_ss = 0.0 else: debt_ss = debt_ratio_ss*Y # Yss_params = (alpha, Z) Yss_params = (Z, gamma, epsilon) Yss = firm.get_Y(Kss, Lss, Yss_params) # Verify that T_Hss = alpha_T*Yss # transfer_error = T_Hss - alpha_T*Yss # if np.absolute(transfer_error) > mindist_SS: # print 'Transfers exceed alpha_T percent of GDP by:', transfer_error # err = "Transfers do not match correct share of GDP in SS_solver" # raise RuntimeError(err) BQss = new_BQ theta_params = (e, S, retire) theta = tax.replacement_rate_vals(nssmat, wss, factor_ss, theta_params) # Next 5 lines pulled out of inner_loop where they are used to calculate tax revenue. Now calculating G to balance gov't budget. b_s = np.array(list(np.zeros(J).reshape(1, J)) + list(bssmat[:-1, :])) lump_sum_params = (e, lambdas.reshape(1, J), omega_SS.reshape(S, 1), 'SS', etr_params, theta, tau_bq, tau_payroll, h_wealth, p_wealth, m_wealth, retire, T, S, J, tau_b, delta_tau) revenue_ss = tax.revenue(new_r, new_w, b_s, nssmat, new_BQ, Yss, Lss, Kss, factor, lump_sum_params) r_gov_ss = rss debt_service_ss = r_gov_ss*debt_ratio_ss*Yss new_borrowing = debt_ratio_ss*Yss*((1+g_n_ss)*np.exp(g_y)-1) # government spends such that it expands its debt at the same rate as GDP if budget_balance: Gss = 0.0 else: Gss = revenue_ss + new_borrowing - (T_Hss + debt_service_ss) # solve resource constraint etr_params_3D = np.tile(np.reshape(etr_params,(S,1,etr_params.shape[1])),(1,J,1)) mtrx_params_3D = np.tile(np.reshape(mtrx_params,(S,1,mtrx_params.shape[1])),(1,J,1)) ''' ------------------------------------------------------------------------ The code below is to calulate and save model MTRs - only exists to help debug ------------------------------------------------------------------------ ''' # etr_params_extended = np.append(etr_params,np.reshape(etr_params[-1,:],(1,etr_params.shape[1])),axis=0)[1:,:] # etr_params_extended_3D = np.tile(np.reshape(etr_params_extended,(S,1,etr_params_extended.shape[1])),(1,J,1)) # mtry_params_extended = np.append(mtry_params,np.reshape(mtry_params[-1,:],(1,mtry_params.shape[1])),axis=0)[1:,:] # mtry_params_extended_3D = np.tile(np.reshape(mtry_params_extended,(S,1,mtry_params_extended.shape[1])),(1,J,1)) # e_extended = np.array(list(e) + list(np.zeros(J).reshape(1, J))) # nss_extended = np.array(list(nssmat) + list(np.zeros(J).reshape(1, J))) # mtry_ss_params = (e_extended[1:,:], etr_params_extended_3D, mtry_params_extended_3D, analytical_mtrs) # mtry_ss = tax.MTR_capital(rss, wss, bssmat_splus1, nss_extended[1:,:], factor_ss, mtry_ss_params) # mtrx_ss_params = (e, etr_params_3D, mtrx_params_3D, analytical_mtrs) # mtrx_ss = tax.MTR_labor(rss, wss, bssmat_s, nssmat, factor_ss, mtrx_ss_params) # np.savetxt("mtr_ss_capital.csv", mtry_ss, delimiter=",") # np.savetxt("mtr_ss_labor.csv", mtrx_ss, delimiter=",") # solve resource constraint taxss_params = (e, lambdas, 'SS', retire, etr_params_3D, h_wealth, p_wealth, m_wealth, tau_payroll, theta, tau_bq, J, S) taxss = tax.total_taxes(rss, wss, bssmat_s, nssmat, BQss, factor_ss, T_Hss, None, False, taxss_params) css_params = (e, lambdas.reshape(1, J), g_y) cssmat = household.get_cons(rss, wss, bssmat_s, bssmat_splus1, nssmat, BQss.reshape( 1, J), taxss, css_params) biz_params = (tau_b, delta_tau) business_revenue = tax.get_biz_tax(wss, Yss, Lss, Kss, biz_params) Css_params = (omega_SS.reshape(S, 1), lambdas, 'SS') Css = household.get_C(cssmat, Css_params) if small_open == False: resource_constraint = Yss - (Css + Iss + Gss) print 'Yss= ', Yss, '\n', 'Gss= ', Gss, '\n', 'Css= ', Css, '\n', 'Kss = ', Kss, '\n', 'Iss = ', Iss, '\n', 'Lss = ', Lss, '\n', 'Debt service = ', debt_service_ss print 'D/Y:', debt_ss/Yss, 'T/Y:', T_Hss/Yss, 'G/Y:', Gss/Yss, 'Rev/Y:', revenue_ss/Yss, 'business rev/Y: ', business_revenue/Yss, 'Int payments to GDP:', (rss*debt_ss)/Yss print 'Check SS budget: ', Gss - (np.exp(g_y)*(1+g_n_ss)-1-rss)*debt_ss - revenue_ss + T_Hss print 'resource constraint: ', resource_constraint else: # include term for current account resource_constraint = Yss + new_borrowing - (Css + BIss + Gss) + (ss_hh_r * Bss - (delta + ss_firm_r) * Kss - debt_service_ss) print 'Yss= ', Yss, '\n', 'Css= ', Css, '\n', 'Bss = ', Bss, '\n', 'BIss = ', BIss, '\n', 'Kss = ', Kss, '\n', 'Iss = ', Iss, '\n', 'Lss = ', Lss, '\n', 'T_H = ', T_H,'\n', 'Gss= ', Gss print 'D/Y:', debt_ss/Yss, 'T/Y:', T_Hss/Yss, 'G/Y:', Gss/Yss, 'Rev/Y:', revenue_ss/Yss, 'Int payments to GDP:', (rss*debt_ss)/Yss print 'resource constraint: ', resource_constraint if Gss < 0: print 'Steady state government spending is negative to satisfy budget' if ENFORCE_SOLUTION_CHECKS and np.absolute(resource_constraint) > mindist_SS: print 'Resource Constraint Difference:', resource_constraint err = "Steady state aggregate resource constraint not satisfied" raise RuntimeError(err) # check constraints household.constraint_checker_SS(bssmat, nssmat, cssmat, ltilde) euler_savings = euler_errors[:S,:] euler_labor_leisure = euler_errors[S:,:] ''' ------------------------------------------------------------------------ Return dictionary of SS results ------------------------------------------------------------------------ ''' output = {'Kss': Kss, 'bssmat': bssmat, 'Bss': Bss, 'Lss': Lss, 'Css':Css, 'Iss':Iss, 'nssmat': nssmat, 'Yss': Yss, 'wss': wss, 'rss': rss, 'theta': theta, 'BQss': BQss, 'factor_ss': factor_ss, 'bssmat_s': bssmat_s, 'cssmat': cssmat, 'bssmat_splus1': bssmat_splus1, 'T_Hss': T_Hss, 'Gss': Gss, 'revenue_ss': revenue_ss, 'euler_savings': euler_savings, 'euler_labor_leisure': euler_labor_leisure, 'chi_n': chi_n, 'chi_b': chi_b} return output
def inner_loop(outer_loop_vars, params, baseline, baseline_spending=False): ''' This function solves for the inner loop of the SS. That is, given the guesses of the outer loop variables (r, w, Y, factor) this function solves the households' problems in the SS. Inputs: r = [T,] vector, interest rate w = [T,] vector, wage rate b = [T,S,J] array, wealth holdings n = [T,S,J] array, labor supply BQ = [T,J] vector, bequest amounts factor = scalar, model income scaling factor Y = [T,] vector, lump sum transfer amount(s) Functions called: euler_equation_solver() household.get_K() firm.get_L() firm.get_Y() firm.get_r() firm.get_w() household.get_BQ() tax.replacement_rate_vals() tax.revenue() Objects in function: Returns: euler_errors, bssmat, nssmat, new_r, new_w new_T_H, new_factor, new_BQ ''' # unpack variables and parameters pass to function ss_params, income_tax_params, chi_params, small_open_params = params J, S, T, BW, beta, sigma, alpha, gamma, epsilon, Z, delta, ltilde, nu, g_y,\ g_n_ss, tau_payroll, tau_bq, rho, omega_SS, budget_balance, \ alpha_T, debt_ratio_ss, tau_b, delta_tau,\ lambdas, imm_rates, e, retire, mean_income_data,\ h_wealth, p_wealth, m_wealth, b_ellipse, upsilon = ss_params analytical_mtrs, etr_params, mtrx_params, mtry_params = income_tax_params chi_b, chi_n = chi_params small_open, ss_firm_r, ss_hh_r = small_open_params if budget_balance: bssmat, nssmat, r, w, T_H, factor = outer_loop_vars else: bssmat, nssmat, r, w, Y, T_H, factor = outer_loop_vars euler_errors = np.zeros((2*S,J)) for j in xrange(J): # Solve the euler equations if j == 0: guesses = np.append(bssmat[:, j], nssmat[:, j]) else: guesses = np.append(bssmat[:, j-1], nssmat[:, j-1]) euler_params = [r, w, T_H, factor, j, J, S, beta, sigma, ltilde, g_y,\ g_n_ss, tau_payroll, retire, mean_income_data,\ h_wealth, p_wealth, m_wealth, b_ellipse, upsilon,\ j, chi_b, chi_n, tau_bq, rho, lambdas, omega_SS, e,\ analytical_mtrs, etr_params, mtrx_params,\ mtry_params] [solutions, infodict, ier, message] = opt.fsolve(euler_equation_solver, guesses * .9, args=euler_params, xtol=MINIMIZER_TOL, full_output=True) euler_errors[:,j] = infodict['fvec'] # print 'Max Euler errors: ', np.absolute(euler_errors[:,j]).max() bssmat[:, j] = solutions[:S] nssmat[:, j] = solutions[S:] L_params = (e, omega_SS.reshape(S, 1), lambdas.reshape(1, J), 'SS') L = firm.get_L(nssmat, L_params) if small_open == False: K_params = (omega_SS.reshape(S, 1), lambdas.reshape(1, J), imm_rates, g_n_ss, 'SS') B = household.get_K(bssmat, K_params) if budget_balance: K = B else: K = B - debt_ratio_ss*Y else: K_params = (Z, gamma, epsilon, delta, tau_b, delta_tau) K = firm.get_K(L, ss_firm_r, K_params) # Y_params = (alpha, Z) Y_params = (Z, gamma, epsilon) new_Y = firm.get_Y(K, L, Y_params) #print 'inner K, L, Y: ', K, L, new_Y if budget_balance: Y = new_Y if small_open == False: r_params = (Z, gamma, epsilon, delta, tau_b, delta_tau) new_r = firm.get_r(Y, K, r_params) else: new_r = ss_hh_r w_params = (Z, gamma, epsilon) new_w = firm.get_w(Y, L, w_params) print 'inner factor prices: ', new_r, new_w b_s = np.array(list(np.zeros(J).reshape(1, J)) + list(bssmat[:-1, :])) average_income_model = ((new_r * b_s + new_w * e * nssmat) * omega_SS.reshape(S, 1) * lambdas.reshape(1, J)).sum() if baseline: new_factor = mean_income_data / average_income_model else: new_factor = factor BQ_params = (omega_SS.reshape(S, 1), lambdas.reshape(1, J), rho.reshape(S, 1), g_n_ss, 'SS') new_BQ = household.get_BQ(new_r, bssmat, BQ_params) theta_params = (e, S, retire) theta = tax.replacement_rate_vals(nssmat, new_w, new_factor, theta_params) if budget_balance: T_H_params = (e, lambdas.reshape(1, J), omega_SS.reshape(S, 1), 'SS', etr_params, theta, tau_bq, tau_payroll, h_wealth, p_wealth, m_wealth, retire, T, S, J, tau_b, delta_tau) new_T_H = tax.revenue(new_r, new_w, b_s, nssmat, new_BQ, new_Y, L, K, factor, T_H_params) elif baseline_spending: new_T_H = T_H else: new_T_H = alpha_T*new_Y return euler_errors, bssmat, nssmat, new_r, new_w, \ new_T_H, new_Y, new_factor, new_BQ, average_income_model
def SS_solver(b_guess_init, n_guess_init, rss, wss, T_Hss, factor_ss, Yss, params, baseline, fsolve_flag=False, baseline_spending=False): ''' -------------------------------------------------------------------- Solves for the steady state distribution of capital, labor, as well as w, r, T_H and the scaling factor, using a bisection method similar to TPI. -------------------------------------------------------------------- INPUTS: b_guess_init = [S,J] array, initial guesses for savings n_guess_init = [S,J] array, initial guesses for labor supply wguess = scalar, initial guess for SS real wage rate rguess = scalar, initial guess for SS real interest rate T_Hguess = scalar, initial guess for lump sum transfer factorguess = scalar, initial guess for scaling factor to dollars chi_b = [J,] vector, chi^b_j, the utility weight on bequests chi_n = [S,] vector, chi^n_s utility weight on labor supply params = length X tuple, list of parameters iterative_params = length X tuple, list of parameters that determine the convergence of the while loop tau_bq = [J,] vector, bequest tax rate rho = [S,] vector, mortality rates by age lambdas = [J,] vector, fraction of population with each ability type omega = [S,] vector, stationary population weights e = [S,J] array, effective labor units by age and ability type OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION: euler_equation_solver() aggr.get_K() aggr.get_L() firm.get_Y() firm.get_r() firm.get_w() aggr.get_BQ() tax.replacement_rate_vals() aggr.revenue() utils.convex_combo() utils.pct_diff_func() OBJECTS CREATED WITHIN FUNCTION: b_guess = [S,] vector, initial guess at household savings n_guess = [S,] vector, initial guess at household labor supply b_s = [S,] vector, wealth enter period with b_splus1 = [S,] vector, household savings b_splus2 = [S,] vector, household savings one period ahead BQ = scalar, aggregate bequests to lifetime income group theta = scalar, replacement rate for social security benenfits error1 = [S,] vector, errors from FOC for savings error2 = [S,] vector, errors from FOC for labor supply tax1 = [S,] vector, total income taxes paid cons = [S,] vector, household consumption OBJECTS CREATED WITHIN FUNCTION - SMALL OPEN ONLY Bss = scalar, aggregate household wealth in the steady state BIss = scalar, aggregate household net investment in the steady state RETURNS: solutions = steady state values of b, n, w, r, factor, T_H ((2*S*J+4)x1 array) OUTPUT: None -------------------------------------------------------------------- ''' bssmat, nssmat, chi_params, ss_params, income_tax_params, iterative_params, small_open_params = params J, S, T, BW, beta, sigma, alpha, gamma, epsilon, Z, delta, ltilde, nu, g_y,\ g_n_ss, tau_payroll, tau_bq, rho, omega_SS, budget_balance, \ alpha_T, debt_ratio_ss, tau_b, delta_tau,\ lambdas, imm_rates, e, retire, mean_income_data,\ h_wealth, p_wealth, m_wealth, b_ellipse, upsilon = ss_params analytical_mtrs, etr_params, mtrx_params, mtry_params = income_tax_params chi_b, chi_n = chi_params maxiter, mindist_SS = iterative_params small_open, ss_firm_r, ss_hh_r = small_open_params # Rename the inputs r = rss w = wss T_H = T_Hss factor = factor_ss if budget_balance == False: if baseline_spending == True: Y = Yss else: Y = T_H / alpha_T if small_open == True: r = ss_hh_r dist = 10 iteration = 0 dist_vec = np.zeros(maxiter) if fsolve_flag == True: maxiter = 1 while (dist > mindist_SS) and (iteration < maxiter): # Solve for the steady state levels of b and n, given w, r, Y and # factor if budget_balance: outer_loop_vars = (bssmat, nssmat, r, w, T_H, factor) else: outer_loop_vars = (bssmat, nssmat, r, w, Y, T_H, factor) inner_loop_params = (ss_params, income_tax_params, chi_params, small_open_params) euler_errors, bssmat, nssmat, new_r, new_w, \ new_T_H, new_Y, new_factor, new_BQ, average_income_model = inner_loop(outer_loop_vars, inner_loop_params, baseline, baseline_spending) r = utils.convex_combo(new_r, r, nu) w = utils.convex_combo(new_w, w, nu) factor = utils.convex_combo(new_factor, factor, nu) if budget_balance: T_H = utils.convex_combo(new_T_H, T_H, nu) dist = np.array([utils.pct_diff_func(new_r, r)] + [utils.pct_diff_func(new_w, w)] + [utils.pct_diff_func(new_T_H, T_H)] + [utils.pct_diff_func(new_factor, factor)]).max() else: Y = utils.convex_combo(new_Y, Y, nu) if Y != 0: dist = np.array( [utils.pct_diff_func(new_r, r)] + [utils.pct_diff_func(new_w, w)] + [utils.pct_diff_func(new_Y, Y)] + [utils.pct_diff_func(new_factor, factor)]).max() else: # If Y is zero (if there is no output), a percent difference # will throw NaN's, so we use an absoluate difference dist = np.array( [utils.pct_diff_func(new_r, r)] + [utils.pct_diff_func(new_w, w)] + [abs(new_Y - Y)] + [utils.pct_diff_func(new_factor, factor)]).max() dist_vec[iteration] = dist # Similar to TPI: if the distance between iterations increases, then # decrease the value of nu to prevent cycling if iteration > 10: if dist_vec[iteration] - dist_vec[iteration - 1] > 0: nu /= 2.0 print 'New value of nu:', nu iteration += 1 print "Iteration: %02d" % iteration, " Distance: ", dist ''' ------------------------------------------------------------------------ Generate the SS values of variables, including euler errors ------------------------------------------------------------------------ ''' bssmat_s = np.append(np.zeros((1, J)), bssmat[:-1, :], axis=0) bssmat_splus1 = bssmat rss = r wss = w factor_ss = factor T_Hss = T_H Lss_params = (e, omega_SS.reshape(S, 1), lambdas, 'SS') Lss = aggr.get_L(nssmat, Lss_params) if small_open == False: Kss_params = (omega_SS.reshape(S, 1), lambdas, imm_rates, g_n_ss, 'SS') Bss = aggr.get_K(bssmat_splus1, Kss_params) if budget_balance: debt_ss = 0.0 else: debt_ss = debt_ratio_ss * Y Kss = Bss - debt_ss Iss_params = (delta, g_y, omega_SS, lambdas, imm_rates, g_n_ss, 'SS') Iss = aggr.get_I(bssmat_splus1, Kss, Kss, Iss_params) else: # Compute capital (K) and wealth (B) separately Kss_params = (Z, gamma, epsilon, delta, tau_b, delta_tau) Kss = firm.get_K(Lss, ss_firm_r, Kss_params) Iss_params = (delta, g_y, omega_SS, lambdas, imm_rates, g_n_ss, 'SS') InvestmentPlaceholder = np.zeros(bssmat_splus1.shape) Iss = aggr.get_I(InvestmentPlaceholder, Kss, Kss, Iss_params) Bss_params = (omega_SS.reshape(S, 1), lambdas, imm_rates, g_n_ss, 'SS') Bss = aggr.get_K(bssmat_splus1, Bss_params) BIss_params = (0.0, g_y, omega_SS, lambdas, imm_rates, g_n_ss, 'SS') BIss = aggr.get_I(bssmat_splus1, Bss, Bss, BIss_params) if budget_balance: debt_ss = 0.0 else: debt_ss = debt_ratio_ss * Y # Yss_params = (alpha, Z) Yss_params = (Z, gamma, epsilon) Yss = firm.get_Y(Kss, Lss, Yss_params) # Verify that T_Hss = alpha_T*Yss # transfer_error = T_Hss - alpha_T*Yss # if np.absolute(transfer_error) > mindist_SS: # print 'Transfers exceed alpha_T percent of GDP by:', transfer_error # err = "Transfers do not match correct share of GDP in SS_solver" # raise RuntimeError(err) BQss = new_BQ theta_params = (e, S, retire) theta = tax.replacement_rate_vals(nssmat, wss, factor_ss, theta_params) # Next 5 lines pulled out of inner_loop where they are used to calculate tax revenue. Now calculating G to balance gov't budget. b_s = np.array(list(np.zeros(J).reshape(1, J)) + list(bssmat[:-1, :])) lump_sum_params = (e, lambdas.reshape(1, J), omega_SS.reshape(S, 1), 'SS', etr_params, theta, tau_bq, tau_payroll, h_wealth, p_wealth, m_wealth, retire, T, S, J, tau_b, delta_tau) revenue_ss = aggr.revenue(new_r, new_w, b_s, nssmat, new_BQ, Yss, Lss, Kss, factor, lump_sum_params) r_gov_ss = rss debt_service_ss = r_gov_ss * debt_ratio_ss * Yss new_borrowing = debt_ratio_ss * Yss * ((1 + g_n_ss) * np.exp(g_y) - 1) # government spends such that it expands its debt at the same rate as GDP if budget_balance: Gss = 0.0 else: Gss = revenue_ss + new_borrowing - (T_Hss + debt_service_ss) # solve resource constraint etr_params_3D = np.tile( np.reshape(etr_params, (S, 1, etr_params.shape[1])), (1, J, 1)) mtrx_params_3D = np.tile( np.reshape(mtrx_params, (S, 1, mtrx_params.shape[1])), (1, J, 1)) ''' ------------------------------------------------------------------------ The code below is to calulate and save model MTRs - only exists to help debug ------------------------------------------------------------------------ ''' # etr_params_extended = np.append(etr_params,np.reshape(etr_params[-1,:],(1,etr_params.shape[1])),axis=0)[1:,:] # etr_params_extended_3D = np.tile(np.reshape(etr_params_extended,(S,1,etr_params_extended.shape[1])),(1,J,1)) # mtry_params_extended = np.append(mtry_params,np.reshape(mtry_params[-1,:],(1,mtry_params.shape[1])),axis=0)[1:,:] # mtry_params_extended_3D = np.tile(np.reshape(mtry_params_extended,(S,1,mtry_params_extended.shape[1])),(1,J,1)) # e_extended = np.array(list(e) + list(np.zeros(J).reshape(1, J))) # nss_extended = np.array(list(nssmat) + list(np.zeros(J).reshape(1, J))) # mtry_ss_params = (e_extended[1:,:], etr_params_extended_3D, mtry_params_extended_3D, analytical_mtrs) # mtry_ss = tax.MTR_capital(rss, wss, bssmat_splus1, nss_extended[1:,:], factor_ss, mtry_ss_params) # mtrx_ss_params = (e, etr_params_3D, mtrx_params_3D, analytical_mtrs) # mtrx_ss = tax.MTR_labor(rss, wss, bssmat_s, nssmat, factor_ss, mtrx_ss_params) # np.savetxt("mtr_ss_capital.csv", mtry_ss, delimiter=",") # np.savetxt("mtr_ss_labor.csv", mtrx_ss, delimiter=",") # solve resource constraint taxss_params = (e, lambdas, 'SS', retire, etr_params_3D, h_wealth, p_wealth, m_wealth, tau_payroll, theta, tau_bq, J, S) taxss = tax.total_taxes(rss, wss, bssmat_s, nssmat, BQss, factor_ss, T_Hss, None, False, taxss_params) css_params = (e, lambdas.reshape(1, J), g_y) cssmat = household.get_cons(rss, wss, bssmat_s, bssmat_splus1, nssmat, BQss.reshape(1, J), taxss, css_params) biz_params = (tau_b, delta_tau) business_revenue = tax.get_biz_tax(wss, Yss, Lss, Kss, biz_params) Css_params = (omega_SS.reshape(S, 1), lambdas, 'SS') Css = aggr.get_C(cssmat, Css_params) if small_open == False: resource_constraint = Yss - (Css + Iss + Gss) print 'Yss= ', Yss, '\n', 'Gss= ', Gss, '\n', 'Css= ', Css, '\n', 'Kss = ', Kss, '\n', 'Iss = ', Iss, '\n', 'Lss = ', Lss, '\n', 'Debt service = ', debt_service_ss print 'D/Y:', debt_ss / Yss, 'T/Y:', T_Hss / Yss, 'G/Y:', Gss / Yss, 'Rev/Y:', revenue_ss / Yss, 'business rev/Y: ', business_revenue / Yss, 'Int payments to GDP:', ( rss * debt_ss) / Yss print 'Check SS budget: ', Gss - (np.exp(g_y) * (1 + g_n_ss) - 1 - rss) * debt_ss - revenue_ss + T_Hss print 'resource constraint: ', resource_constraint else: # include term for current account resource_constraint = Yss + new_borrowing - (Css + BIss + Gss) + ( ss_hh_r * Bss - (delta + ss_firm_r) * Kss - debt_service_ss) print 'Yss= ', Yss, '\n', 'Css= ', Css, '\n', 'Bss = ', Bss, '\n', 'BIss = ', BIss, '\n', 'Kss = ', Kss, '\n', 'Iss = ', Iss, '\n', 'Lss = ', Lss, '\n', 'T_H = ', T_H, '\n', 'Gss= ', Gss print 'D/Y:', debt_ss / Yss, 'T/Y:', T_Hss / Yss, 'G/Y:', Gss / Yss, 'Rev/Y:', revenue_ss / Yss, 'Int payments to GDP:', ( rss * debt_ss) / Yss print 'resource constraint: ', resource_constraint if Gss < 0: print 'Steady state government spending is negative to satisfy budget' if ENFORCE_SOLUTION_CHECKS and np.absolute( resource_constraint) > mindist_SS: print 'Resource Constraint Difference:', resource_constraint err = "Steady state aggregate resource constraint not satisfied" raise RuntimeError(err) # check constraints household.constraint_checker_SS(bssmat, nssmat, cssmat, ltilde) euler_savings = euler_errors[:S, :] euler_labor_leisure = euler_errors[S:, :] ''' ------------------------------------------------------------------------ Return dictionary of SS results ------------------------------------------------------------------------ ''' output = { 'Kss': Kss, 'bssmat': bssmat, 'Bss': Bss, 'Lss': Lss, 'Css': Css, 'Iss': Iss, 'nssmat': nssmat, 'Yss': Yss, 'wss': wss, 'rss': rss, 'theta': theta, 'BQss': BQss, 'factor_ss': factor_ss, 'bssmat_s': bssmat_s, 'cssmat': cssmat, 'bssmat_splus1': bssmat_splus1, 'T_Hss': T_Hss, 'Gss': Gss, 'revenue_ss': revenue_ss, 'euler_savings': euler_savings, 'euler_labor_leisure': euler_labor_leisure, 'chi_n': chi_n, 'chi_b': chi_b } return output
def run_TPI(income_tax_params, tpi_params, iterative_params, small_open_params, initial_values, SS_values, fiscal_params, biz_tax_params, output_dir="./OUTPUT", baseline_spending=False): # unpack tuples of parameters analytical_mtrs, etr_params, mtrx_params, mtry_params = income_tax_params maxiter, mindist_SS, mindist_TPI = iterative_params J, S, T, BW, beta, sigma, alpha, gamma, epsilon, Z, delta, ltilde, nu, g_y,\ g_n_vector, tau_payroll, tau_bq, rho, omega, N_tilde, lambdas, imm_rates, e, retire, mean_income_data,\ factor, h_wealth, p_wealth, m_wealth, b_ellipse, upsilon, chi_b, chi_n, theta = tpi_params # K0, b_sinit, b_splus1init, L0, Y0,\ # w0, r0, BQ0, T_H_0, factor, tax0, c0, initial_b, initial_n, omega_S_preTP = initial_values small_open, tpi_firm_r, tpi_hh_r = small_open_params B0, b_sinit, b_splus1init, factor, initial_b, initial_n, omega_S_preTP, initial_debt = initial_values Kss, Bss, Lss, rss, wss, BQss, T_Hss, revenue_ss, bssmat_splus1, nssmat, Yss, Gss = SS_values tau_b, delta_tau = biz_tax_params if baseline_spending==False: budget_balance, ALPHA_T, ALPHA_G, tG1, tG2, rho_G, debt_ratio_ss = fiscal_params else: budget_balance, ALPHA_T, ALPHA_G, tG1, tG2, rho_G, debt_ratio_ss, T_Hbaseline, Gbaseline = fiscal_params print 'Government spending breakpoints are tG1: ', tG1, '; and tG2:', tG2 TPI_FIG_DIR = output_dir # Initialize guesses at time paths # Make array of initial guesses for labor supply and savings domain = np.linspace(0, T, T) domain2 = np.tile(domain.reshape(T, 1, 1), (1, S, J)) ending_b = bssmat_splus1 guesses_b = (-1 / (domain2 + 1)) * (ending_b - initial_b) + ending_b ending_b_tail = np.tile(ending_b.reshape(1, S, J), (S, 1, 1)) guesses_b = np.append(guesses_b, ending_b_tail, axis=0) domain3 = np.tile(np.linspace(0, 1, T).reshape(T, 1, 1), (1, S, J)) guesses_n = domain3 * (nssmat - initial_n) + initial_n ending_n_tail = np.tile(nssmat.reshape(1, S, J), (S, 1, 1)) guesses_n = np.append(guesses_n, ending_n_tail, axis=0) b_mat = guesses_b#np.zeros((T + S, S, J)) n_mat = guesses_n#np.zeros((T + S, S, J)) ind = np.arange(S) L_init = np.ones((T+S,))*Lss B_init = np.ones((T+S,))*Bss L_params = (e.reshape(1, S, J), omega[:T, :].reshape(T, S, 1), lambdas.reshape(1, 1, J), 'TPI') L_init[:T] = firm.get_L(n_mat[:T], L_params) B_params = (omega[:T-1].reshape(T-1, S, 1), lambdas.reshape(1, 1, J), imm_rates[:T-1].reshape(T-1,S,1), g_n_vector[1:T], 'TPI') B_init[1:T] = household.get_K(b_mat[:T-1], B_params) B_init[0] = B0 if small_open == False: if budget_balance: K_init = B_init else: K_init = B_init * Kss/Bss else: K_params = (Z, gamma, epsilon, delta, tau_b, delta_tau) K_init = firm.get_K(L_init, tpi_firm_r, K_params) K = K_init # if np.any(K < 0): # print 'K_init has negative elements. Setting them positive to prevent NAN.' # K[:T] = np.fmax(K[:T], 0.05*B[:T]) L = L_init B = B_init Y_params = (Z, gamma, epsilon) Y = firm.get_Y(K, L, Y_params) w_params = (Z, gamma, epsilon) w = firm.get_w(Y, L, w_params) if small_open == False: r_params = (Z, gamma, epsilon, delta, tau_b, delta_tau) r = firm.get_r(Y, K, r_params) else: r = tpi_hh_r BQ = np.zeros((T + S, J)) BQ0_params = (omega_S_preTP.reshape(S, 1), lambdas, rho.reshape(S, 1), g_n_vector[0], 'SS') BQ0 = household.get_BQ(r[0], initial_b, BQ0_params) for j in xrange(J): BQ[:, j] = list(np.linspace(BQ0[j], BQss[j], T)) + [BQss[j]] * S BQ = np.array(BQ) if budget_balance: if np.abs(T_Hss) < 1e-13 : T_Hss2 = 0.0 # sometimes SS is very small but not zero, even if taxes are zero, this get's rid of the approximation error, which affects the perc changes below else: T_Hss2 = T_Hss T_H = np.ones(T + S) * T_Hss2 REVENUE = T_H G = np.zeros(T + S) elif baseline_spending==False: T_H = ALPHA_T * Y elif baseline_spending==True: T_H = T_Hbaseline T_H_new = T_H # Need to set T_H_new for later reference G = Gbaseline G_0 = Gbaseline[0] # Initialize some inputs # D = np.zeros(T + S) D = debt_ratio_ss*Y omega_shift = np.append(omega_S_preTP.reshape(1,S),omega[:T-1,:],axis=0) BQ_params = (omega_shift.reshape(T, S, 1), lambdas.reshape(1, 1, J), rho.reshape(1, S, 1), g_n_vector[:T].reshape(T, 1), 'TPI') tax_params = np.zeros((T,S,J,etr_params.shape[2])) for i in range(etr_params.shape[2]): tax_params[:,:,:,i] = np.tile(np.reshape(np.transpose(etr_params[:,:T,i]),(T,S,1)),(1,1,J)) REVENUE_params = (np.tile(e.reshape(1, S, J),(T,1,1)), lambdas.reshape(1, 1, J), omega[:T].reshape(T, S, 1), 'TPI', tax_params, theta, tau_bq, tau_payroll, h_wealth, p_wealth, m_wealth, retire, T, S, J, tau_b, delta_tau) # print 'D/Y:', D[:T]/Y[:T] # print 'T/Y:', T_H[:T]/Y[:T] # print 'G/Y:', G[:T]/Y[:T] # print 'Int payments to GDP:', (r[:T]*D[:T])/Y[:T] # quit() TPIiter = 0 TPIdist = 10 PLOT_TPI = False report_tG1 = False euler_errors = np.zeros((T, 2 * S, J)) TPIdist_vec = np.zeros(maxiter) print 'analytical mtrs in tpi = ', analytical_mtrs while (TPIiter < maxiter) and (TPIdist >= mindist_TPI): # Plot TPI for K for each iteration, so we can see if there is a # problem if PLOT_TPI is True: #K_plot = list(K) + list(np.ones(10) * Kss) D_plot = list(D) + list(np.ones(10) * Yss * debt_ratio_ss) plt.figure() plt.axhline( y=Kss, color='black', linewidth=2, label=r"Steady State $\hat{K}$", ls='--') plt.plot(np.arange( T + 10), D_plot[:T + 10], 'b', linewidth=2, label=r"TPI time path $\hat{K}_t$") plt.savefig(os.path.join(TPI_FIG_DIR, "TPI_D")) if report_tG1 is True: print '\tAt time tG1-1:' print '\t\tG = ', G[tG1-1] print '\t\tK = ', K[tG1-1] print '\t\tr = ', r[tG1-1] print '\t\tD = ', D[tG1-1] guesses = (guesses_b, guesses_n) outer_loop_vars = (r, w, K, BQ, T_H) inner_loop_params = (income_tax_params, tpi_params, initial_values, ind) # Solve HH problem in inner loop euler_errors, b_mat, n_mat = inner_loop(guesses, outer_loop_vars, inner_loop_params) bmat_s = np.zeros((T, S, J)) bmat_s[0, 1:, :] = initial_b[:-1, :] bmat_s[1:, 1:, :] = b_mat[:T-1, :-1, :] bmat_splus1 = np.zeros((T, S, J)) bmat_splus1[:, :, :] = b_mat[:T, :, :] #L_params = (e.reshape(1, S, J), omega[:T, :].reshape(T, S, 1), lambdas.reshape(1, 1, J), 'TPI') # defined above L[:T] = firm.get_L(n_mat[:T], L_params) #B_params = (omega[:T-1].reshape(T-1, S, 1), lambdas.reshape(1, 1, J), imm_rates[:T-1].reshape(T-1,S,1), g_n_vector[1:T], 'TPI') # defined above B[1:T] = household.get_K(bmat_splus1[:T-1], B_params) if np.any(B) < 0: print 'B has negative elements. B[0:9]:', B[0:9] print 'B[T-2:T]:', B[T-2,T] if small_open == False: if budget_balance: K[:T] = B[:T] else: if baseline_spending == False: Y = T_H/ALPHA_T #SBF 3/3: This seems totally unnecessary as both these variables are defined above. # tax_params = np.zeros((T,S,J,etr_params.shape[2])) # for i in range(etr_params.shape[2]): # tax_params[:,:,:,i] = np.tile(np.reshape(np.transpose(etr_params[:,:T,i]),(T,S,1)),(1,1,J)) # REVENUE_params = (np.tile(e.reshape(1, S, J),(T,1,1)), lambdas.reshape(1, 1, J), omega[:T].reshape(T, S, 1), 'TPI', # tax_params, theta, tau_bq, tau_payroll, h_wealth, p_wealth, m_wealth, retire, T, S, J, tau_b, delta_tau) # define above REVENUE = np.array(list(tax.revenue(np.tile(r[:T].reshape(T, 1, 1),(1,S,J)), np.tile(w[:T].reshape(T, 1, 1),(1,S,J)), bmat_s, n_mat[:T,:,:], BQ[:T].reshape(T, 1, J), Y[:T], L[:T], K[:T], factor, REVENUE_params)) + [revenue_ss] * S) D_0 = initial_debt * Y[0] other_dg_params = (T, r, g_n_vector, g_y) if baseline_spending==False: G_0 = ALPHA_G[0] * Y[0] dg_fixed_values = (Y, REVENUE, T_H, D_0,G_0) Dnew, G = fiscal.D_G_path(dg_fixed_values, fiscal_params, other_dg_params, baseline_spending=baseline_spending) K[:T] = B[:T] - Dnew[:T] if np.any(K < 0): print 'K has negative elements. Setting them positive to prevent NAN.' K[:T] = np.fmax(K[:T], 0.05*B[:T]) else: # K_params previously set to = (Z, gamma, epsilon, delta, tau_b, delta_tau) K[:T] = firm.get_K(L[:T], tpi_firm_r[:T], K_params) Y_params = (Z, gamma, epsilon) Ynew = firm.get_Y(K[:T], L[:T], Y_params) Y = Ynew w_params = (Z, gamma, epsilon) wnew = firm.get_w(Ynew[:T], L[:T], w_params) if small_open == False: r_params = (Z, gamma, epsilon, delta, tau_b, delta_tau) rnew = firm.get_r(Ynew[:T], K[:T], r_params) else: rnew = r.copy() print 'Y and T_H: ', Y[3], T_H[3] # omega_shift = np.append(omega_S_preTP.reshape(1,S),omega[:T-1,:],axis=0) # defined above # BQ_params = (omega_shift.reshape(T, S, 1), lambdas.reshape(1, 1, J), rho.reshape(1, S, 1), # g_n_vector[:T].reshape(T, 1), 'TPI') # defined above b_mat_shift = np.append(np.reshape(initial_b,(1,S,J)),b_mat[:T-1,:,:],axis=0) BQnew = household.get_BQ(rnew[:T].reshape(T, 1), b_mat_shift, BQ_params) # tax_params = np.zeros((T,S,J,etr_params.shape[2])) # for i in range(etr_params.shape[2]): # tax_params[:,:,:,i] = np.tile(np.reshape(np.transpose(etr_params[:,:T,i]),(T,S,1)),(1,1,J)) # REVENUE_params = (np.tile(e.reshape(1, S, J),(T,1,1)), lambdas.reshape(1, 1, J), omega[:T].reshape(T, S, 1), 'TPI', # tax_params, theta, tau_bq, tau_payroll, h_wealth, p_wealth, m_wealth, retire, T, S, J, tau_b, delta_tau) # defined above REVENUE = np.array(list(tax.revenue(np.tile(rnew[:T].reshape(T, 1, 1),(1,S,J)), np.tile(wnew[:T].reshape(T, 1, 1),(1,S,J)), bmat_s, n_mat[:T,:,:], BQnew[:T].reshape(T, 1, J), Y[:T], L[:T], K[:T], factor, REVENUE_params)) + [revenue_ss] * S) if budget_balance: T_H_new = REVENUE elif baseline_spending==False: T_H_new = ALPHA_T[:T] * Y[:T] # If baseline_spending==True, no need to update T_H, which remains fixed. if small_open==True and budget_balance==False: # Loop through years to calculate debt and gov't spending. This is done earlier when small_open=False. D_0 = initial_debt * Y[0] other_dg_params = (T, r, g_n_vector, g_y) if baseline_spending==False: G_0 = ALPHA_G[0] * Y[0] dg_fixed_values = (Y, REVENUE, T_H, D_0,G_0) Dnew, G = fiscal.D_G_path(dg_fixed_values, fiscal_params, other_dg_params, baseline_spending=baseline_spending) w[:T] = utils.convex_combo(wnew[:T], w[:T], nu) r[:T] = utils.convex_combo(rnew[:T], r[:T], nu) BQ[:T] = utils.convex_combo(BQnew[:T], BQ[:T], nu) # D[:T] = utils.convex_combo(Dnew[:T], D[:T], nu) D = Dnew Y[:T] = utils.convex_combo(Ynew[:T], Y[:T], nu) if baseline_spending==False: T_H[:T] = utils.convex_combo(T_H_new[:T], T_H[:T], nu) guesses_b = utils.convex_combo(b_mat, guesses_b, nu) guesses_n = utils.convex_combo(n_mat, guesses_n, nu) print 'r diff: ', (rnew[:T]-r[:T]).max(), (rnew[:T]-r[:T]).min() print 'w diff: ', (wnew[:T]-w[:T]).max(), (wnew[:T]-w[:T]).min() print 'BQ diff: ', (BQnew[:T]-BQ[:T]).max(), (BQnew[:T]-BQ[:T]).min() print 'T_H diff: ', (T_H_new[:T]-T_H[:T]).max(), (T_H_new[:T]-T_H[:T]).min() if baseline_spending==False: if T_H.all() != 0: TPIdist = np.array(list(utils.pct_diff_func(rnew[:T], r[:T])) + list(utils.pct_diff_func(BQnew[:T], BQ[:T]).flatten()) + list( utils.pct_diff_func(wnew[:T], w[:T])) + list(utils.pct_diff_func(T_H_new[:T], T_H[:T]))).max() else: TPIdist = np.array(list(utils.pct_diff_func(rnew[:T], r[:T])) + list(utils.pct_diff_func(BQnew[:T], BQ[:T]).flatten()) + list( utils.pct_diff_func(wnew[:T], w[:T])) + list(np.abs(T_H[:T]))).max() else: # TPIdist = np.array(list(utils.pct_diff_func(rnew[:T], r[:T])) + list(utils.pct_diff_func(BQnew[:T], BQ[:T]).flatten()) + list( # utils.pct_diff_func(wnew[:T], w[:T])) + list(utils.pct_diff_func(Dnew[:T], D[:T]))).max() TPIdist = np.array(list(utils.pct_diff_func(rnew[:T], r[:T])) + list(utils.pct_diff_func(BQnew[:T], BQ[:T]).flatten()) + list( utils.pct_diff_func(wnew[:T], w[:T])) + list(utils.pct_diff_func(Ynew[:T], Y[:T]))).max() TPIdist_vec[TPIiter] = TPIdist # After T=10, if cycling occurs, drop the value of nu # wait til after T=10 or so, because sometimes there is a jump up # in the first couple iterations # if TPIiter > 10: # if TPIdist_vec[TPIiter] - TPIdist_vec[TPIiter - 1] > 0: # nu /= 2 # print 'New Value of nu:', nu TPIiter += 1 print 'Iteration:', TPIiter print '\tDistance:', TPIdist # print 'D/Y:', (D[:T]/Ynew[:T]).max(), (D[:T]/Ynew[:T]).min(), np.median(D[:T]/Ynew[:T]) # print 'T/Y:', (T_H_new[:T]/Ynew[:T]).max(), (T_H_new[:T]/Ynew[:T]).min(), np.median(T_H_new[:T]/Ynew[:T]) # print 'G/Y:', (G[:T]/Ynew[:T]).max(), (G[:T]/Ynew[:T]).min(), np.median(G[:T]/Ynew[:T]) # print 'Int payments to GDP:', ((r[:T]*D[:T])/Ynew[:T]).max(), ((r[:T]*D[:T])/Ynew[:T]).min(), np.median((r[:T]*D[:T])/Ynew[:T]) # # print 'D/Y:', (D[:T]/Ynew[:T]) # print 'T/Y:', (T_H_new[:T]/Ynew[:T]) # print 'G/Y:', (G[:T]/Ynew[:T]) # # print 'deficit: ', REVENUE[:T] - T_H_new[:T] - G[:T] # Loop through years to calculate debt and gov't spending. The re-assignment of G0 & D0 is necessary because Y0 may change in the TPI loop. if budget_balance == False: D_0 = initial_debt * Y[0] other_dg_params = (T, r, g_n_vector, g_y) if baseline_spending==False: G_0 = ALPHA_G[0] * Y[0] dg_fixed_values = (Y, REVENUE, T_H, D_0,G_0) D, G = fiscal.D_G_path(dg_fixed_values, fiscal_params, other_dg_params, baseline_spending=baseline_spending) # Solve HH problem in inner loop guesses = (guesses_b, guesses_n) outer_loop_vars = (r, w, K, BQ, T_H) inner_loop_params = (income_tax_params, tpi_params, initial_values, ind) euler_errors, b_mat, n_mat = inner_loop(guesses, outer_loop_vars, inner_loop_params) bmat_s = np.zeros((T, S, J)) bmat_s[0, 1:, :] = initial_b[:-1, :] bmat_s[1:, 1:, :] = b_mat[:T-1, :-1, :] bmat_splus1 = np.zeros((T, S, J)) bmat_splus1[:, :, :] = b_mat[:T, :, :] #L_params = (e.reshape(1, S, J), omega[:T, :].reshape(T, S, 1), lambdas.reshape(1, 1, J), 'TPI') # defined above L[:T] = firm.get_L(n_mat[:T], L_params) #B_params = (omega[:T-1].reshape(T-1, S, 1), lambdas.reshape(1, 1, J), imm_rates[:T-1].reshape(T-1,S,1), g_n_vector[1:T], 'TPI') # defined above B[1:T] = household.get_K(bmat_splus1[:T-1], B_params) if small_open == False: K[:T] = B[:T] - D[:T] else: # K_params previously set to = (Z, gamma, epsilon, delta, tau_b, delta_tau) K[:T] = firm.get_K(L[:T], tpi_firm_r[:T], K_params) # Y_params previously set to = (Z, gamma, epsilon) Ynew = firm.get_Y(K[:T], L[:T], Y_params) # testing for change in Y ydiff = Ynew[:T] - Y[:T] ydiff_max = np.amax(np.abs(ydiff)) print 'ydiff_max = ', ydiff_max w_params = (Z, gamma, epsilon) wnew = firm.get_w(Ynew[:T], L[:T], w_params) if small_open == False: # r_params previously set to = (Z, gamma, epsilon, delta, tau_b, delta_tau) rnew = firm.get_r(Ynew[:T], K[:T], r_params) else: rnew = r # Note: previously, Y was not reassigned to equal Ynew at this point. Y = Ynew[:] # omega_shift = np.append(omega_S_preTP.reshape(1,S),omega[:T-1,:],axis=0) # BQ_params = (omega_shift.reshape(T, S, 1), lambdas.reshape(1, 1, J), rho.reshape(1, S, 1), # g_n_vector[:T].reshape(T, 1), 'TPI') b_mat_shift = np.append(np.reshape(initial_b,(1,S,J)),b_mat[:T-1,:,:],axis=0) BQnew = household.get_BQ(rnew[:T].reshape(T, 1), b_mat_shift, BQ_params) # tax_params = np.zeros((T,S,J,etr_params.shape[2])) # for i in range(etr_params.shape[2]): # tax_params[:,:,:,i] = np.tile(np.reshape(np.transpose(etr_params[:,:T,i]),(T,S,1)),(1,1,J)) # REVENUE_params = (np.tile(e.reshape(1, S, J),(T,1,1)), lambdas.reshape(1, 1, J), omega[:T].reshape(T, S, 1), 'TPI', # tax_params, theta, tau_bq, tau_payroll, h_wealth, p_wealth, m_wealth, retire, T, S, J, tau_b, delta_tau) REVENUE = np.array(list(tax.revenue(np.tile(rnew[:T].reshape(T, 1, 1),(1,S,J)), np.tile(wnew[:T].reshape(T, 1, 1),(1,S,J)), bmat_s, n_mat[:T,:,:], BQnew[:T].reshape(T, 1, J), Ynew[:T], L[:T], K[:T], factor, REVENUE_params)) + [revenue_ss] * S) etr_params_path = np.zeros((T,S,J,etr_params.shape[2])) for i in range(etr_params.shape[2]): etr_params_path[:,:,:,i] = np.tile(np.reshape(np.transpose(etr_params[:,:T,i]),(T,S,1)),(1,1,J)) tax_path_params = (np.tile(e.reshape(1, S, J),(T,1,1)), lambdas, 'TPI', retire, etr_params_path, h_wealth, p_wealth, m_wealth, tau_payroll, theta, tau_bq, J, S) tax_path = tax.total_taxes(np.tile(r[:T].reshape(T, 1, 1),(1,S,J)), np.tile(w[:T].reshape(T, 1, 1),(1,S,J)), bmat_s, n_mat[:T,:,:], BQ[:T, :].reshape(T, 1, J), factor, T_H[:T].reshape(T, 1, 1), None, False, tax_path_params) cons_params = (e.reshape(1, S, J), lambdas.reshape(1, 1, J), g_y) c_path = household.get_cons(r[:T].reshape(T, 1, 1), w[:T].reshape(T, 1, 1), bmat_s, bmat_splus1, n_mat[:T,:,:], BQ[:T].reshape(T, 1, J), tax_path, cons_params) C_params = (omega[:T].reshape(T, S, 1), lambdas, 'TPI') C = household.get_C(c_path, C_params) if budget_balance==False: D_0 = initial_debt * Y[0] other_dg_params = (T, r, g_n_vector, g_y) if baseline_spending==False: G_0 = ALPHA_G[0] * Y[0] dg_fixed_values = (Y, REVENUE, T_H, D_0,G_0) D, G = fiscal.D_G_path(dg_fixed_values, fiscal_params, other_dg_params, baseline_spending=baseline_spending) if small_open == False: I_params = (delta, g_y, omega[:T].reshape(T, S, 1), lambdas, imm_rates[:T].reshape(T, S, 1), g_n_vector[1:T+1], 'TPI') I = firm.get_I(bmat_splus1[:T], K[1:T+1], K[:T], I_params) rc_error = Y[:T] - C[:T] - I[:T] - G[:T] else: #InvestmentPlaceholder = np.zeros(bmat_splus1[:T].shape) #I_params = (delta, g_y, omega[:T].reshape(T, S, 1), lambdas, imm_rates[:T].reshape(T, S, 1), g_n_vector[1:T+1], 'TPI') I = (1+g_n_vector[:T])*np.exp(g_y)*K[1:T+1] - (1.0 - delta) * K[:T] #firm.get_I(InvestmentPlaceholder, K[1:T+1], K[:T], I_params) BI_params = (0.0, g_y, omega[:T].reshape(T, S, 1), lambdas, imm_rates[:T].reshape(T, S, 1), g_n_vector[1:T+1], 'TPI') BI = firm.get_I(bmat_splus1[:T], B[1:T+1], B[:T], BI_params) new_borrowing = D[1:T]*(1+g_n_vector[1:T])*np.exp(g_y) - D[:T-1] rc_error = Y[:T-1] + new_borrowing - (C[:T-1] + BI[:T-1] + G[:T-1] ) + (tpi_hh_r[:T-1] * B[:T-1] - (delta + tpi_firm_r[:T-1])*K[:T-1] - tpi_hh_r[:T-1]*D[:T-1]) #print 'Y(T-1):', Y[T-1], '\n','C(T-1):', C[T-1], '\n','K(T-1):', K[T-1], '\n','B(T-1):', B[T-1], '\n','BI(T-1):', BI[T-1], '\n','I(T-1):', I[T-1] rce_max = np.amax(np.abs(rc_error)) print 'Max absolute value resource constraint error:', rce_max print'Checking time path for violations of constraints.' for t in xrange(T): household.constraint_checker_TPI( b_mat[t], n_mat[t], c_path[t], t, ltilde) eul_savings = euler_errors[:, :S, :].max(1).max(1) eul_laborleisure = euler_errors[:, S:, :].max(1).max(1) # print 'Max Euler error, savings: ', eul_savings # print 'Max Euler error labor supply: ', eul_laborleisure ''' ------------------------------------------------------------------------ Save variables/values so they can be used in other modules ------------------------------------------------------------------------ ''' output = {'Y': Y, 'K': K, 'L': L, 'C': C, 'I': I, 'BQ': BQ, 'REVENUE': REVENUE, 'T_H': T_H, 'G': G, 'D': D, 'r': r, 'w': w, 'b_mat': b_mat, 'n_mat': n_mat, 'c_path': c_path, 'tax_path': tax_path, 'eul_savings': eul_savings, 'eul_laborleisure': eul_laborleisure} tpi_dir = os.path.join(output_dir, "TPI") utils.mkdirs(tpi_dir) tpi_vars = os.path.join(tpi_dir, "TPI_vars.pkl") pickle.dump(output, open(tpi_vars, "wb")) macro_output = {'Y': Y, 'K': K, 'L': L, 'C': C, 'I': I, 'BQ': BQ, 'T_H': T_H, 'r': r, 'w': w, 'tax_path': tax_path} growth = (1+g_n_vector)*np.exp(g_y) with open('TPI_output.csv', 'wb') as csvfile: tpiwriter = csv.writer(csvfile) tpiwriter.writerow(Y) tpiwriter.writerow(D) tpiwriter.writerow(REVENUE) tpiwriter.writerow(G) tpiwriter.writerow(T_H) tpiwriter.writerow(C) tpiwriter.writerow(K) tpiwriter.writerow(I) tpiwriter.writerow(r) if small_open == True: tpiwriter.writerow(B) tpiwriter.writerow(BI) tpiwriter.writerow(new_borrowing) tpiwriter.writerow(growth) tpiwriter.writerow(rc_error) tpiwriter.writerow(ydiff) if np.any(G) < 0: print 'Government spending is negative along transition path to satisfy budget' if ((TPIiter >= maxiter) or (np.absolute(TPIdist) > mindist_TPI)) and ENFORCE_SOLUTION_CHECKS : raise RuntimeError("Transition path equlibrium not found (TPIdist)") if ((np.any(np.absolute(rc_error) >= mindist_TPI)) and ENFORCE_SOLUTION_CHECKS): raise RuntimeError("Transition path equlibrium not found (rc_error)") if ((np.any(np.absolute(eul_savings) >= mindist_TPI) or (np.any(np.absolute(eul_laborleisure) > mindist_TPI))) and ENFORCE_SOLUTION_CHECKS): raise RuntimeError("Transition path equlibrium not found (eulers)") # Non-stationary output # macro_ns_output = {'K_ns_path': K_ns_path, 'C_ns_path': C_ns_path, 'I_ns_path': I_ns_path, # 'L_ns_path': L_ns_path, 'BQ_ns_path': BQ_ns_path, # 'rinit': rinit, 'Y_ns_path': Y_ns_path, 'T_H_ns_path': T_H_ns_path, # 'w_ns_path': w_ns_path} return output, macro_output
def inner_loop(outer_loop_vars, params, baseline, baseline_spending=False): ''' This function solves for the inner loop of the SS. That is, given the guesses of the outer loop variables (r, w, Y, factor) this function solves the households' problems in the SS. Inputs: r = [T,] vector, interest rate w = [T,] vector, wage rate b = [T,S,J] array, wealth holdings n = [T,S,J] array, labor supply BQ = [T,J] vector, bequest amounts factor = scalar, model income scaling factor Y = [T,] vector, lump sum transfer amount(s) Functions called: euler_equation_solver() aggr.get_K() aggr.get_L() firm.get_Y() firm.get_r() firm.get_w() aggr.get_BQ() tax.replacement_rate_vals() aggr.revenue() Objects in function: Returns: euler_errors, bssmat, nssmat, new_r, new_w new_T_H, new_factor, new_BQ ''' # unpack variables and parameters pass to function ss_params, income_tax_params, chi_params, small_open_params = params J, S, T, BW, beta, sigma, alpha, gamma, epsilon, Z, delta, ltilde, nu, g_y,\ g_n_ss, tau_payroll, tau_bq, rho, omega_SS, budget_balance, \ alpha_T, debt_ratio_ss, tau_b, delta_tau,\ lambdas, imm_rates, e, retire, mean_income_data,\ h_wealth, p_wealth, m_wealth, b_ellipse, upsilon = ss_params analytical_mtrs, etr_params, mtrx_params, mtry_params = income_tax_params chi_b, chi_n = chi_params small_open, ss_firm_r, ss_hh_r = small_open_params if budget_balance: bssmat, nssmat, r, w, T_H, factor = outer_loop_vars else: bssmat, nssmat, r, w, Y, T_H, factor = outer_loop_vars euler_errors = np.zeros((2 * S, J)) for j in xrange(J): # Solve the euler equations if j == 0: guesses = np.append(bssmat[:, j], nssmat[:, j]) else: guesses = np.append(bssmat[:, j - 1], nssmat[:, j - 1]) euler_params = [r, w, T_H, factor, j, J, S, beta, sigma, ltilde, g_y,\ g_n_ss, tau_payroll, retire, mean_income_data,\ h_wealth, p_wealth, m_wealth, b_ellipse, upsilon,\ j, chi_b, chi_n, tau_bq, rho, lambdas, omega_SS, e,\ analytical_mtrs, etr_params, mtrx_params,\ mtry_params] [solutions, infodict, ier, message] = opt.fsolve(euler_equation_solver, guesses * .9, args=euler_params, xtol=MINIMIZER_TOL, full_output=True) euler_errors[:, j] = infodict['fvec'] # print 'Max Euler errors: ', np.absolute(euler_errors[:,j]).max() bssmat[:, j] = solutions[:S] nssmat[:, j] = solutions[S:] L_params = (e, omega_SS.reshape(S, 1), lambdas.reshape(1, J), 'SS') L = aggr.get_L(nssmat, L_params) if small_open == False: K_params = (omega_SS.reshape(S, 1), lambdas.reshape(1, J), imm_rates, g_n_ss, 'SS') B = aggr.get_K(bssmat, K_params) if budget_balance: K = B else: K = B - debt_ratio_ss * Y else: K_params = (Z, gamma, epsilon, delta, tau_b, delta_tau) K = firm.get_K(L, ss_firm_r, K_params) # Y_params = (alpha, Z) Y_params = (Z, gamma, epsilon) new_Y = firm.get_Y(K, L, Y_params) #print 'inner K, L, Y: ', K, L, new_Y if budget_balance: Y = new_Y if small_open == False: r_params = (Z, gamma, epsilon, delta, tau_b, delta_tau) new_r = firm.get_r(Y, K, r_params) else: new_r = ss_hh_r w_params = (Z, gamma, epsilon) new_w = firm.get_w(Y, L, w_params) print 'inner factor prices: ', new_r, new_w b_s = np.array(list(np.zeros(J).reshape(1, J)) + list(bssmat[:-1, :])) average_income_model = ((new_r * b_s + new_w * e * nssmat) * omega_SS.reshape(S, 1) * lambdas.reshape(1, J)).sum() if baseline: new_factor = mean_income_data / average_income_model else: new_factor = factor BQ_params = (omega_SS.reshape(S, 1), lambdas.reshape(1, J), rho.reshape(S, 1), g_n_ss, 'SS') new_BQ = aggr.get_BQ(new_r, bssmat, BQ_params) theta_params = (e, S, retire) theta = tax.replacement_rate_vals(nssmat, new_w, new_factor, theta_params) if budget_balance: T_H_params = (e, lambdas.reshape(1, J), omega_SS.reshape(S, 1), 'SS', etr_params, theta, tau_bq, tau_payroll, h_wealth, p_wealth, m_wealth, retire, T, S, J, tau_b, delta_tau) new_T_H = aggr.revenue(new_r, new_w, b_s, nssmat, new_BQ, new_Y, L, K, factor, T_H_params) elif baseline_spending: new_T_H = T_H else: new_T_H = alpha_T * new_Y return euler_errors, bssmat, nssmat, new_r, new_w, \ new_T_H, new_Y, new_factor, new_BQ, average_income_model