def Steady_State_SS(guesses, chi_params, params, weights_SS, rho_vec, lambdas, theta, tau_bq, e): ''' Parameters: Steady state distribution of capital guess as array size 2*S*J Returns: Array of 2*S*J Euler equation errors ''' J, S, T, beta, sigma, alpha, Z, delta, ltilde, nu, g_y, tau_payroll, retire, mean_income_data, a_tax_income, b_tax_income, c_tax_income, d_tax_income, h_wealth, p_wealth, m_wealth, b_ellipse, upsilon = params chi_b = np.tile(np.array(chi_params[:J]).reshape(1, J), (S, 1)) chi_n = np.array(chi_params[J:]) b_guess = guesses[0: S * J].reshape((S, J)) K = house.get_K(b_guess, weights_SS) n_guess = guesses[S * J:-1].reshape((S, J)) L = firm.get_L(e, n_guess, weights_SS) Y = firm.get_Y(K, L, params) w = firm.get_w(Y, L, params) r = firm.get_r(Y, K, params) BQ = (1 + r) * (b_guess * weights_SS * rho_vec.reshape(S, 1)).sum(0) b_s = np.array(list(np.zeros(J).reshape(1, J)) + list(b_guess[:-1, :])) b_splus1 = b_guess b_splus2 = np.array(list(b_guess[1:]) + list(np.zeros(J).reshape(1, J))) factor = guesses[-1] T_H = tax.get_lump_sum(r, b_s, w, e, n_guess, BQ, lambdas, factor, weights_SS, 'SS', params, theta, tau_bq) error1 = house.euler_savings_func(w, r, e, n_guess, b_s, b_splus1, b_splus2, BQ.reshape(1, J), factor, T_H, chi_b, params, theta, tau_bq, rho_vec, lambdas) error2 = house.euler_labor_leisure_func(w, r, e, n_guess, b_s, b_splus1, BQ.reshape(1, J), factor, T_H, chi_n, params, theta, tau_bq, lambdas) average_income_model = ((r * b_s + w * e * n_guess) * weights_SS).sum() error3 = [mean_income_data - factor * average_income_model] # Check and punish constraint violations mask1 = n_guess < 0 error2[mask1] += 1e9 mask2 = n_guess > ltilde error2[mask2] += 1e9 if b_guess.sum() <= 0: error1 += 1e9 tax1 = tax.total_taxes(r, b_s, w, e, n_guess, BQ, lambdas, factor, T_H, None, 'SS', False, params, theta, tau_bq) cons = house.get_cons(r, b_s, w, e, n_guess, BQ.reshape(1, J), lambdas, b_splus1, params, tax1) mask3 = cons < 0 error2[mask3] += 1e9 mask4 = b_guess[:-1] <= 0 error1[mask4] += 1e9 # print np.abs(np.array(list(error1.flatten()) + list( # error2.flatten()) + error3)).max() return list(error1.flatten()) + list( error2.flatten()) + error3
dictionary = {} for key in var_names: dictionary[key] = globals()[key] pickle.dump(dictionary, open("OUTPUT/Saved_moments/SS_experiment_solutions.pkl", "w")) bssmat = solutions[0:(S-1) * J].reshape(S-1, J) bq = solutions[(S-1)*J:S*J] bssmat_s = np.array(list(np.zeros(J).reshape(1, J)) + list(bssmat)) bssmat_splus1 = np.array(list(bssmat) + list(bq.reshape(1, J))) nssmat = solutions[S * J:2*S*J].reshape(S, J) wss, rss, factor_ss, T_Hss = solutions[2*S*J:] Kss = house.get_K(bssmat_splus1, omega_SS) Lss = firm.get_L(e, nssmat, omega_SS) Yss = firm.get_Y(Kss, Lss, parameters) theta = tax.replacement_rate_vals(nssmat, wss, factor_ss, e, J, omega_SS) BQss = (1+rss)*(np.array(list(bssmat) + list(bq.reshape(1, J))).reshape( S, J) * omega_SS * rho.reshape(S, 1)).sum(0) b_s = np.array(list(np.zeros(J).reshape((1, J))) + list(bssmat)) taxss = tax.total_taxes(rss, b_s, wss, e, nssmat, BQss, lambdas, factor_ss, T_Hss, None, 'SS', False, parameters, theta, tau_bq) cssmat = house.get_cons(rss, b_s, wss, e, nssmat, BQss.reshape(1, J), lambdas.reshape(1, J), bssmat_splus1, parameters, taxss) house.constraint_checker_SS(bssmat, nssmat, cssmat, parameters) ''' ------------------------------------------------------------------------ Generate variables for graphs ------------------------------------------------------------------------ b_s = SxJ array of bssmat in period t
def new_SS_Solver(b_guess_init, n_guess_init, wguess, rguess, T_Hguess, factorguess, chi_n, chi_b, params, iterative_params, theta, tau_bq, rho, lambdas, weights): J, S, T, beta, sigma, alpha, Z, delta, ltilde, nu, g_y, tau_payroll, retire, mean_income_data, a_tax_income, b_tax_income, c_tax_income, d_tax_income, h_wealth, p_wealth, m_wealth, b_ellipse, upsilon = params maxiter, mindist = iterative_params w = wguess r = rguess T_H = T_Hguess factor = factorguess bssmat = b_guess_init nssmat = n_guess_init dist = 10 iteration = 0 dist_vec = np.zeros(maxiter) while (dist > mindist) and (iteration < maxiter): for j in xrange(J): # Solve the euler equations guesses = np.append(bssmat[:, j], nssmat[:, j]) solutions = opt.fsolve(Euler_equation_solver, guesses * .9, args=(r, w, T_H, factor, j, params, chi_b, chi_n, theta, tau_bq, rho, lambdas, weights)) bssmat[:,j] = solutions[:S] nssmat[:,j] = solutions[S:] # print np.array(Euler_equation_solver(np.append(bssmat[:, j], nssmat[:, j]), r, w, T_H, factor, j, params, chi_b, chi_n, theta, tau_bq, rho, lambdas)).max() K = house.get_K(bssmat, weights) L = firm.get_L(e, nssmat, weights) Y = firm.get_Y(K, L, params) new_r = firm.get_r(Y, K, params) new_w = firm.get_w(Y, L, params) 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) * weights).sum() new_factor = mean_income_data / average_income_model new_BQ = (1+new_r)*(bssmat * weights * rho.reshape(S, 1)).sum(0) new_T_H = tax.get_lump_sum(new_r, b_s, new_w, e, nssmat, new_BQ, lambdas, factor, weights, 'SS', params, theta, tau_bq) r = misc_funcs.convex_combo(new_r, r, params) w = misc_funcs.convex_combo(new_w, w, params) factor = misc_funcs.convex_combo(new_factor, factor, params) T_H = misc_funcs.convex_combo(new_T_H, T_H, params) dist = np.array([abs(r-new_r)] + [abs(w-new_w)] + [abs(T_H-new_T_H)]).max() dist_vec[iteration] = dist 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 eul_errors = np.ones(J) b_mat = np.zeros((S, J)) n_mat = np.zeros((S, J)) for j in xrange(J): solutions1 = opt.fsolve(Euler_equation_solver, np.append(bssmat[:, j], nssmat[:, j])* .9, args=(r, w, T_H, factor, j, params, chi_b, chi_n, theta, tau_bq, rho, lambdas, weights), xtol=1e-13) eul_errors[j] = np.array(Euler_equation_solver(solutions1, r, w, T_H, factor, j, params, chi_b, chi_n, theta, tau_bq, rho, lambdas, weights)).max() b_mat[:, j] = solutions1[:S] n_mat[:, j] = solutions1[S:] print 'SS fsolve euler error:', eul_errors.max() solutions = np.append(b_mat.flatten(), n_mat.flatten()) other_vars = np.array([w, r, factor, T_H]) solutions = np.append(solutions, other_vars) return solutions
parameters = [J, S, T, beta, sigma, alpha, Z, delta, ltilde, nu, g_y, tau_payroll, retire, mean_income_data] + income_tax_params + wealth_tax_params + ellipse_params N_tilde = omega.sum(1).sum(1) omega_stationary = omega / N_tilde.reshape(T+S, 1, 1) if get_baseline: initial_b = bssmat_splus1 initial_n = nssmat else: initial_b = bssmat_init initial_n = nssmat_init K0 = house.get_K(initial_b, omega_stationary[0]) b_sinit = np.array(list(np.zeros(J).reshape(1, J)) + list(initial_b[:-1])) b_splus1init = initial_b L0 = firm.get_L(e, initial_n, omega_stationary[0]) Y0 = firm.get_Y(K0, L0, parameters) w0 = firm.get_w(Y0, L0, parameters) r0 = firm.get_r(Y0, K0, parameters) BQ0 = (1+r0)*(initial_b * omega_stationary[0] * rho.reshape(S, 1)).sum(0) T_H_0 = tax.get_lump_sum(r0, b_sinit, w0, e, initial_n, BQ0, lambdas, factor_ss, omega_stationary[0], 'SS', parameters, theta, tau_bq) tax0 = tax.total_taxes(r0, b_sinit, w0, e, initial_n, BQ0, lambdas, factor_ss, T_H_0, None, 'SS', False, parameters, theta, tau_bq) c0 = house.get_cons(r0, b_sinit, w0, e, initial_n, BQ0.reshape(1, J), lambdas.reshape(1, J), b_splus1init, parameters, tax0) ''' ------------------------------------------------------------------------ Solve for equilibrium transition path by TPI ------------------------------------------------------------------------ ''' def SS_TPI_firstdoughnutring(guesses, winit, rinit, BQinit, T_H_init):
N_tilde = omega.sum(1) omega_stationary = omega / N_tilde.reshape(T+S, 1) if get_baseline: initial_b = bssmat_splus1 initial_n = nssmat else: initial_b = bssmat_init initial_n = nssmat_init # Get an initial distribution of capital with the initial population distribution K0 = house.get_K(initial_b, omega_stationary[0].reshape(S, 1), lambdas, g_n_vector[0]) b_sinit = np.array(list(np.zeros(J).reshape(1, J)) + list(initial_b[:-1])) b_splus1init = initial_b L0 = firm.get_L(e, initial_n, omega_stationary[0].reshape(S, 1), lambdas) Y0 = firm.get_Y(K0, L0, parameters) w0 = firm.get_w(Y0, L0, parameters) r0 = firm.get_r(Y0, K0, parameters) BQ0 = house.get_BQ(r0, initial_b, omega_stationary[0].reshape(S, 1), lambdas, rho.reshape(S, 1), g_n_vector[0]) T_H_0 = tax.get_lump_sum(r0, b_sinit, w0, e, initial_n, BQ0, lambdas, factor_ss, omega_stationary[0].reshape(S, 1), 'SS', parameters, theta, tau_bq) tax0 = tax.total_taxes(r0, b_sinit, w0, e, initial_n, BQ0, lambdas, factor_ss, T_H_0, None, 'SS', False, parameters, theta, tau_bq) c0 = house.get_cons(r0, b_sinit, w0, e, initial_n, BQ0.reshape(1, J), lambdas.reshape(1, J), b_splus1init, parameters, tax0) ''' ------------------------------------------------------------------------ Solve for equilibrium transition path by TPI ------------------------------------------------------------------------ ''' def SS_TPI_firstdoughnutring(guesses, winit, rinit, BQinit, T_H_init, j):
, 1.85430468 , 1.97291208 , 1.97017228 , 2.25518398 , 2.43969757 , 3.21870602 , 4.18334822 , 4.97772026 , 6.37663164 , 8.65075992 , 9.46944758 , 10.51634777 , 12.13353793 , 11.89186997 , 12.07083882 , 13.2992811 , 14.07987878 , 14.19951571 , 14.97943562 , 16.05601334 , 16.42979341 , 16.91576867 , 17.62775142 , 18.4885405 , 19.10609921 , 20.03988031 , 20.86564363 , 21.73645892 , 22.6208256 , 23.37786072 , 24.38166073 , 25.22395387 , 26.21419653 , 27.05246704 , 27.86896121 , 28.90029708 , 29.83586775 , 30.87563699 , 31.91207845 , 33.07449767 , 34.27919965 , 35.57195873 , 36.95045988 , 38.62308152]) if SS_stage == 'first_run_for_guesses': b_guess_init = np.ones((S, J)) * .01 n_guess_init = np.ones((S, J)) * .99 * ltilde Kg = house.get_K(b_guess_init, omega_SS) Lg = firm.get_L(e, n_guess_init, omega_SS) Yg = firm.get_Y(Kg, Lg, parameters) wguess = firm.get_w(Yg, Lg, parameters) rguess = firm.get_r(Yg, Kg, parameters) avIguess = ((rguess * b_guess_init + wguess * e * n_guess_init) * omega_SS).sum() factor_guess = [mean_income_data / avIguess] guesses = list(b_guess_init.flatten()) + list(n_guess_init.flatten()) + factor_guess chi_guesses = np.ones(S+J) chi_guesses[0:J] = np.array([5, 10, 90, 250, 250, 250, 250]) + chi_b_scal print 'Chi_b:', chi_guesses[0:J] chi_guesses[J:] = chi_n_guess chi_guesses = list(chi_guesses) final_chi_params = chi_guesses Steady_State_SS_X2 = lambda x: Steady_State_SS(x, final_chi_params, parameters, omega_SS, rho, lambdas, theta, tau_bq, e) solutions = opt.fsolve(Steady_State_SS_X2, guesses, xtol=1e-13) print np.array(Steady_State_SS_X2(solutions)).max() elif SS_stage == 'loop_calibration':
def SS_solver(b_guess_init, n_guess_init, wguess, rguess, T_Hguess, factorguess, chi_n, chi_b, params, iterative_params, tau_bq, rho, lambdas, weights, e): ''' Solves for the steady state distribution of capital, labor, as well as w, r, T_H and the scaling factor, using an iterative method similar to TPI. Inputs: b_guess_init = guesses for b (SxJ array) n_guess_init = guesses for n (SxJ array) wguess = guess for wage rate (scalar) rguess = guess for rental rate (scalar) T_Hguess = guess for lump sum tax (scalar) factorguess = guess for scaling factor to dollars (scalar) chi_n = chi^n_s (Sx1 array) chi_b = chi^b_j (Jx1 array) params = list of parameters (list) iterative_params = list of parameters that determine the convergence of the while loop (list) tau_bq = bequest tax rate (Jx1 array) rho = mortality rates (Sx1 array) lambdas = ability weights (Jx1 array) weights = population weights (Sx1 array) e = ability levels (SxJ array) Outputs: solutions = steady state values of b, n, w, r, factor, T_H ((2*S*J+4)x1 array) ''' J, S, T, beta, sigma, alpha, Z, delta, ltilde, nu, g_y, g_n_ss, tau_payroll, retire, mean_income_data, a_tax_income, b_tax_income, c_tax_income, d_tax_income, h_wealth, p_wealth, m_wealth, b_ellipse, upsilon = params maxiter, mindist_SS = iterative_params # Rename the inputs w = wguess r = rguess T_H = T_Hguess factor = factorguess bssmat = b_guess_init nssmat = n_guess_init dist = 10 iteration = 0 dist_vec = np.zeros(maxiter) while (dist > mindist_SS) and (iteration < maxiter): # Solve for the steady state levels of b and n, given w, r, T_H and factor for j in xrange(J): # Solve the euler equations guesses = np.append(bssmat[:, j], nssmat[:, j]) solutions = opt.fsolve(Euler_equation_solver, guesses * .9, args=(r, w, T_H, factor, j, params, chi_b, chi_n, tau_bq, rho, lambdas, weights, e), xtol=1e-13) bssmat[:,j] = solutions[:S] nssmat[:,j] = solutions[S:] # print np.array(Euler_equation_solver(np.append(bssmat[:, j], nssmat[:, j]), r, w, T_H, factor, j, params, chi_b, chi_n, theta, tau_bq, rho, lambdas, e)).max() K = house.get_K(bssmat, weights.reshape(S, 1), lambdas.reshape(1, J), g_n_ss) L = firm.get_L(e, nssmat, weights.reshape(S, 1), lambdas.reshape(1, J)) Y = firm.get_Y(K, L, params) new_r = firm.get_r(Y, K, params) new_w = firm.get_w(Y, L, params) 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) * weights.reshape(S, 1) * lambdas.reshape(1, J)).sum() new_factor = mean_income_data / average_income_model new_BQ = house.get_BQ(new_r, bssmat, weights.reshape(S, 1), lambdas.reshape(1, J), rho.reshape(S, 1), g_n_ss) theta = tax.replacement_rate_vals(nssmat, new_w, new_factor, e, J, weights.reshape(S, 1), lambdas) new_T_H = tax.get_lump_sum(new_r, b_s, new_w, e, nssmat, new_BQ, lambdas.reshape(1, J), factor, weights.reshape(S, 1), 'SS', params, theta, tau_bq) r = misc_funcs.convex_combo(new_r, r, params) w = misc_funcs.convex_combo(new_w, w, params) factor = misc_funcs.convex_combo(new_factor, factor, params) T_H = misc_funcs.convex_combo(new_T_H, T_H, params) if T_H != 0: dist = np.array([misc_funcs.perc_dif_func(new_r, r)] + [misc_funcs.perc_dif_func(new_w, w)] + [misc_funcs.perc_dif_func(new_T_H, T_H)] + [misc_funcs.perc_dif_func(new_factor, factor)]).max() else: # If T_H is zero (if there are no taxes), a percent difference will throw NaN's, so we use an absoluate difference dist = np.array([misc_funcs.perc_dif_func(new_r, r)] + [misc_funcs.perc_dif_func(new_w, w)] + [abs(new_T_H - T_H)] + [misc_funcs.perc_dif_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 eul_errors = np.ones(J) b_mat = np.zeros((S, J)) n_mat = np.zeros((S, J)) # Given the final w, r, T_H and factor, solve for the SS b and n (if you don't do a final fsolve, there will be a slight mismatch, with high euler errors) for j in xrange(J): solutions1 = opt.fsolve(Euler_equation_solver, np.append(bssmat[:, j], nssmat[:, j])* .9, args=(r, w, T_H, factor, j, params, chi_b, chi_n, tau_bq, rho, lambdas, weights, e), xtol=1e-13) eul_errors[j] = np.array(Euler_equation_solver(solutions1, r, w, T_H, factor, j, params, chi_b, chi_n, tau_bq, rho, lambdas, weights, e)).max() b_mat[:, j] = solutions1[:S] n_mat[:, j] = solutions1[S:] print 'SS fsolve euler error:', eul_errors.max() solutions = np.append(b_mat.flatten(), n_mat.flatten()) other_vars = np.array([w, r, factor, T_H]) solutions = np.append(solutions, other_vars) return solutions
''' ------------------------------------------------------------------------ Generate the SS values of variables, including euler errors ------------------------------------------------------------------------ ''' bssmat = solutions[0:(S-1) * J].reshape(S-1, J) bq = solutions[(S-1)*J:S*J] bssmat_s = np.array(list(np.zeros(J).reshape(1, J)) + list(bssmat)) bssmat_splus1 = np.array(list(bssmat) + list(bq.reshape(1, J))) nssmat = solutions[S * J:2*S*J].reshape(S, J) wss, rss, factor_ss, T_Hss = solutions[2*S*J:] Kss = house.get_K(bssmat_splus1, omega_SS.reshape(S, 1), lambdas, g_n_ss) Lss = firm.get_L(e, nssmat, omega_SS.reshape(S, 1), lambdas) Yss = firm.get_Y(Kss, Lss, parameters) Iss = firm.get_I(Kss, Kss, delta, g_y, g_n_ss) theta = tax.replacement_rate_vals(nssmat, wss, factor_ss, e, J, omega_SS.reshape(S, 1), lambdas) BQss = house.get_BQ(rss, bssmat_splus1, omega_SS.reshape(S, 1), lambdas, rho.reshape(S, 1), g_n_ss) b_s = np.array(list(np.zeros(J).reshape((1, J))) + list(bssmat)) taxss = tax.total_taxes(rss, b_s, wss, e, nssmat, BQss, lambdas, factor_ss, T_Hss, None, 'SS', False, parameters, theta, tau_bq) cssmat = house.get_cons(rss, b_s, wss, e, nssmat, BQss.reshape(1, J), lambdas.reshape(1, J), bssmat_splus1, parameters, taxss) Css = house.get_C(cssmat, omega_SS.reshape(S, 1), lambdas) resource_constraint = Yss - (Css + Iss) print 'Resource Constraint Difference:', resource_constraint
omega_stationary = omega / N_tilde.reshape(T + S, 1) if get_baseline: initial_b = bssmat_splus1 initial_n = nssmat else: initial_b = bssmat_init initial_n = nssmat_init # Get an initial distribution of capital with the initial population distribution K0 = house.get_K(initial_b, omega_stationary[0].reshape(S, 1), lambdas, g_n_vector[0]) b_sinit = np.array(list(np.zeros(J).reshape(1, J)) + list(initial_b[:-1])) b_splus1init = initial_b L0 = firm.get_L(e, initial_n, omega_stationary[0].reshape(S, 1), lambdas) Y0 = firm.get_Y(K0, L0, parameters) w0 = firm.get_w(Y0, L0, parameters) r0 = firm.get_r(Y0, K0, parameters) BQ0 = house.get_BQ(r0, initial_b, omega_stationary[0].reshape(S, 1), lambdas, rho.reshape(S, 1), g_n_vector[0]) T_H_0 = tax.get_lump_sum(r0, b_sinit, w0, e, initial_n, BQ0, lambdas, factor_ss, omega_stationary[0].reshape(S, 1), 'SS', parameters, theta, tau_bq) tax0 = tax.total_taxes(r0, b_sinit, w0, e, initial_n, BQ0, lambdas, factor_ss, T_H_0, None, 'SS', False, parameters, theta, tau_bq) c0 = house.get_cons(r0, b_sinit, w0, e, initial_n, BQ0.reshape(1, J), lambdas.reshape(1, J), b_splus1init, parameters, tax0) ''' ------------------------------------------------------------------------ Solve for equilibrium transition path by TPI ------------------------------------------------------------------------