def rBQ_errors(rBQ_vals, *args): ''' -------------------------------------------------------------------- Generate interest rate and wage errors from labor market clearing and capital market clearing conditions -------------------------------------------------------------------- INPUTS: rBQ_vals = (2,) vector, steady-state r value and BQ value args = length 2 tuple, (nb_guess, p) OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION: firms.get_wt() hh.get_cnb_vecs() aggr.get_Lt() aggr.get_Kt() firms.get_rt() aggr.get_BQt() OBJECTS CREATED WITHIN FUNCTION: nb_buess = (2S,) vector, initial guesses for n_s and b_sp1 p = parameters class object r_init = scalar, initial guess for steady-state interest rate BQ_init = scalar, initial guess for steady-state total bequests w = scalar, steady-state wage implied by r_init b_init = scalar = 0, initial wealth of initial age individuals r_path = (S,) vector, constant interest rate time path over lifetime of individual w_path = (S,) vector, constant wage time path over lifetime of individual BQ_path = (S,) vector, constant total bequests time path over lifetime of individual c_s = (S,) vector, steady-state consumption by age n_s = (S,) vector, steady-state labor supply by age b_s = (S+1,) vector, steady-state wealth or savings by age n_errors = (S,) vector, errors associated with optimal labor supply solution b_errors = (S,) vector, errors associated with optimal savings solution L = scalar, aggregate labor implied by household and firm optimization K = scalar, aggregate capital implied by household and firm optimization r_new = scalar, new value of r implied by household and firm optimization BQ_new = scalar, new value of BQ implied by household and firm optimization r_error = scalar, difference between r_new and r_init BQ_error = scalar, difference between BQ_new and BQ_init rBQ_errors = (2,) vector, r_error and BQ_error FILES CREATED BY THIS FUNCTION: None RETURNS: rBQ_errors -------------------------------------------------------------------- ''' (nb_guess, p) = args r_init, BQ_init = rBQ_vals # Solve for steady-state wage w implied by r w = firms.get_wt(r_init, p) # Solve for household steady-state decisions c_s, n_s, b_{s+1} given # r, w, and BQ b_init = 0.0 r_path = r_init * np.ones(p.S) w_path = w * np.ones(p.S) BQ_path = BQ_init * np.ones(p.S) c_s, n_s, b_s, n_errors, b_errors = \ hh.get_cnb_vecs(nb_guess, b_init, r_path, w_path, BQ_path, p.rho_ss, p.SS_EulDif, p, p.SS_EulTol) # Solve for aggregate labor and aggregate capital L = aggr.get_Lt(n_s, p) K = aggr.get_Kt(b_s[1:], p) # Solve for updated values of the interest rate r and total bequests # BQ r_new = firms.get_rt(K, L, p) BQ_new = aggr.get_BQt(b_s[1:], r_init, p) # solve for errors in interest rate and total bequests guesses r_error = r_new - r_init BQ_error = BQ_new - BQ_init rBQ_errors = np.array([r_error, BQ_error]) return rBQ_errors
def get_TP(p, ss_output, graphs): ''' -------------------------------------------------------------------- Solves for transition path equilibrium using time path iteration (TPI) -------------------------------------------------------------------- INPUTS: p = parameters class object ss_output = length 18 dictionary, steady-state output graphs = boolean, =True if generate transition path equilibrium graphs OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION: get_path() firms.get_wt() hh.get_cnb_paths() aggr.get_Lt() aggr.get_Kt() firms.get_rt() aggr.get_BQt() utils.print_time() firms.get_Yt() aggr.get_Ct() aggr.get_It() aggr.get_NXt() creat_graphs() OBJECTS CREATED WITHIN FUNCTION: start_time = scalar, current processor time in seconds (float) r_ss = scalar > -delta, steady-state interest rate BQ_ss = scalar > 0, steady-state total bequests r_path_init = (T2+S,) vector, initial guess of interest rate time path BQ_path_init = (T2+S,) vector, initial guess of total bequests time path r_0 = scalar > -delta, initial period interest rate guess BQ_0 = scalar > 0, initial period total bequests guess rBQpath_init = (2, T2+S) matrix, initial guess for time paths of interest rate and total bequests iter_TPI = integer >= 0, iteration number index for TPI dist = scalar > 0, distance measure of (rBQpath_new - rBQpath_init) cnb_args = length 2 tuple, (ss_output, p) arguments passed to hh.get_cnb_paths() w_path = (T2+S,) vector, time path of wages cs_path = (S, T2+S) matrix, time path of household consumption by age ns_path = (S, T2+S) matrix, time path of household labor supply by age bs_path = (S+1, T2+S+1) matrix, time path of household savings and wealth by age ns_err_path = (S, T2+S) matrix, time path of Euler errors by age from household optimal labor supply decisions bs_err_path = (S+1, T2+S+1) matrix, time path of Euler errors by age from household optimal savings decisions L_path = (T2+1,) vector, time path of aggregate labor K_path = (T2+1,) vector, time path of aggregate capital stock r_path_new = (T2+S,) vector, time path of interest rates implied by household and firm optimization BQ_Path_new = (T2+S,) vector, time path of total bequests implied by household and firm optimization rBQpath_new = (2, T2+S) matrix, time path of interest rates and total bequests implied by household and firm optimization tpi_time = scalar, elapsed time for TPI computation r_path = (T2+S,) vector, equilibrium interest rate time path BQ_path = (T2+S,) vector, equilibrium total bequests time path Y_path = (T2+1,) vector, equilibrium aggregate output time path C_path = (T2+1,) vector, equilibrium aggregate consumption time path I_path = (T2+1,) vector, equilibrium aggregate investment time path NX_path = (T2+1,) vector, equilibrium net exports time path tpi_output = length 17 dictionary, tpi output objects {cs_path, ns_path, bs_path, ns_err_path, bs_err_path, r_path, w_path, BQ_path, K_path, L_path, Y_path, C_path, I_path, NX_path, dist, iter_TPI, tpi_time} FILES CREATED BY THIS FUNCTION: None RETURNS: tpi_output -------------------------------------------------------------------- ''' start_time = time.clock() # Unpack steady-state objects to be used in this algorithm r_ss = ss_output['r_ss'] BQ_ss = ss_output['BQ_ss'] # Create initial time paths for r, w r_path_init = np.zeros(p.T2 + p.S) BQ_path_init = np.zeros(p.T2 + p.S) # pct_r = 1 + p.xi_TP * ((Km_ss.sum() - p.b_s0_vec.sum()) / # p.b_s0_vec.sum()) r_0 = r_ss # pct_r * r_ss BQ_0 = BQ_ss # (2 - pct_r) * w_ss r_path_init[:p.T2 + 1] = get_path(r_0, r_ss, p.T2 + 1, 'quadratic') r_path_init[p.T2 + 1:] = r_ss BQ_path_init[:p.T2 + 1] = get_path(BQ_0, BQ_ss, p.T2 + 1, 'quadratic') BQ_path_init[p.T2 + 1:] = BQ_ss # print('rpath_init=', rpath_init) # print('BQpath_init=', BQpath_init) rBQpath_init = np.zeros((2, p.T2 + p.S)) rBQpath_init[0, :] = r_path_init rBQpath_init[1, :] = BQ_path_init # raise ValueError('Pause program') iter_TPI = int(0) dist = 10.0 cnb_args = (ss_output, p) while (iter_TPI < p.maxiter_TP) and (dist > p.TP_OutTol): iter_TPI += 1 r_path_init = rBQpath_init[0, :] BQ_path_init = rBQpath_init[1, :] # Solve for time path of w_t given r_t w_path = firms.get_wt(r_path_init, p) # Solve for time path of household optimal decisions n_{s,t} # and b_{s+1,t+1} given prices r_t and w_t and total bequests # BQ_t (cs_path, ns_path, bs_path, ns_err_path, bs_err_path) = \ hh.get_cnb_paths(r_path_init, w_path, BQ_path_init, cnb_args) # Solve for time paths of aggregate capital K_t and aggregate # labor L_t L_path = aggr.get_Lt(ns_path[:, :p.T2 + 1], p) K_path = aggr.get_Kt(bs_path[1:, :p.T2 + 1], p) # Solve for new time paths of r_t^{i+1} and total bequests # BQ_t^{i+1} r_path_new = np.zeros(p.T2 + p.S) r_path_new[:p.T2 + 1] = firms.get_rt(K_path, L_path, p) r_path_new[p.T2 + 1:] = r_path_init[p.T2 + 1:] BQ_path_new = np.zeros(p.T2 + p.S) BQ_path_new[:p.T2 + 1] = aggr.get_BQt(bs_path[1:, :p.T2 + 1], r_path_init[:p.T2 + 1], p) BQ_path_new[p.T2 + 1:] = BQ_path_init[p.T2 + 1:] # Calculate distance measure between (r^{i+1},BQ^{i+1}) and # (r^i,BQ^i) rBQpath_new = np.vstack((r_path_new.reshape((1, p.T2 + p.S)), BQ_path_new.reshape((1, p.T2 + p.S)))) dist = np.absolute(rBQpath_new - rBQpath_init).max() print( 'TPI iter: ', iter_TPI, ', dist: ', "%10.4e" % (dist), ', max abs all errs: ', "%10.4e" % (np.absolute(np.hstack((bs_err_path.max(axis=0), ns_err_path.max(axis=0)))).max())) if dist > p.TP_OutTol: rBQpath_init = (p.xi_TP * rBQpath_new + (1 - p.xi_TP) * rBQpath_init) tpi_time = time.clock() - start_time # Print TPI computation time utils.print_time(tpi_time, 'TPI') if (iter_TPI == p.maxiter_TP) and (dist > p.TP_OutTol): print('TPI reached maxiter and did not converge.') elif (iter_TPI == p.maxiter_TP) and (dist <= p.TP_OutTol): print('TPI converged in the last iteration. ' + 'Should probably increase maxiter_TP.') elif (iter_TPI < p.maxiter_TP) and (dist <= p.TP_OutTol): print('TPI SUCCESS: Converged on iteration', iter_TPI, '.') r_path = r_path_init BQ_path = BQ_path_init # Solve for equilibrium time paths of aggregate output, consumption, # investment, and net exports Y_path = firms.get_Yt(K_path, L_path, p) C_path = aggr.get_Ct(cs_path[:, :p.T2 + 1], p) I_path = aggr.get_It(K_path, p) NX_path = aggr.get_NXt(bs_path[1:, :p.T2 + 1], p) # Create TPI output dictionary tpi_output = { 'cs_path': cs_path, 'ns_path': ns_path, 'bs_path': bs_path, 'ns_err_path': ns_err_path, 'bs_err_path': bs_err_path, 'r_path': r_path, 'w_path': w_path, 'BQ_path': BQ_path, 'K_path': K_path, 'L_path': L_path, 'Y_path': Y_path, 'C_path': C_path, 'I_path': I_path, 'NX_path': NX_path, 'dist': dist, 'iter_TPI': iter_TPI, 'tpi_time': tpi_time} if graphs: create_graphs(tpi_output, p) return tpi_output
def get_SS(rBQ_init, p, graphs=False): ''' -------------------------------------------------------------------- Solve for the steady-state solution of the S-period-lived agent OG model with endogenous labor supply and multiple industries using the root finder method in r and w for the outer loop -------------------------------------------------------------------- INPUTS: rBQ_init = (2,) vector, initial guesses for (rss_init, BQss_init) p = parameters class object graphs = boolean, =True if output steady-state graphs OTHER FUNCTIONS AND FILES CALLED BY THIS FUNCTION: rBQ_errors() firms.get_wt() hh.get_cnb_vecs() aggr.get_Lt() aggr.get_Kt() firms.get_Yt() C_ss = aggr.get_Ct() I_ss = aggr.get_It() NX_ss = aggr.get_NXt() utils.print_time() ss_graphs() OBJECTS CREATED WITHIN FUNCTION: start_time = scalar > 0, clock time at beginning of program nvec_guess = (S,) vector, initial guess for optimal household labor supply n_s bvec_guess = (S,) vector, initial guess for optimal household savings b_sp1 nb_guess = (2S,) vector, initial guesses for optimal household labor supply and savings (n_s, b_sp1) rBQ_args = length 2 tuple, (nb_guess, p) results_rBQ = root results object err_msg = string, error message text string r_ss = scalar > -delta, steady-state interest rate BQ_ss = scalar > 0, steady-state total bequests r_err_ss = scalar, error in steady-state optimal solution firm first order condition for r_ss BQ_err_ss = scalar, error in steady-state optimal solution bequests law of motion for BQ_ss w_ss = scalar > 0, steady-state wage b_init = scalar = 0, initial wealth of initial age individuals r_path = (S,) vector, constant interest rate time path over lifetime of individual w_path = (S,) vector, constant wage time path over lifetime of individual BQ_path = (S,) vector, constant total bequests time path over lifetime of individual c_ss = (S,) vector, steady-state consumption by age n_ss = (S,) vector, steady-state labor supply by age b_ss = (S+1,) vector, steady-state wealth or savings by age n_err_ss = (S,) vector, errors associated with optimal labor supply solution b_err_ss = (S,) vector, errors associated with optimal savings solution L_ss = scalar > 0, steady-state aggregate labor K_ss = scalar > 0, steady-state aggregate capital stock Y_ss = scalar > 0, steady-state aggregate output C_ss = scalar > 0, steady-state aggregate consumption I_ss = scalar, steady-state aggregate investment NX_ss = scalar, steady-state net exports RCerr_ss = scalar, steady-state resource constraint (goods market clearing) error ss_time = scalar, seconds elapsed for steady-state computation ss_output = length 18 dictionary, steady-state output {c_ss, n_ss, b_ss, n_err_ss, b_err_ss, r_ss, w_ss, BQ_ss, r_err_ss, BQ_err_ss, L_ss, K_ss, Y_ss, C_ss, I_ss, NX_ss, RCerr_ss, ss_time} FILES CREATED BY THIS FUNCTION: None RETURNS: ss_output -------------------------------------------------------------------- ''' start_time = time.clock() nvec_guess = 0.4 * p.l_tilde * np.ones(p.S) bvec_guess = 0.1 * np.ones(p.S) nb_guess = np.append(nvec_guess, bvec_guess) rBQ_args = (nb_guess, p) results_rBQ = opt.root(rBQ_errors, rBQ_init, args=rBQ_args, tol=p.SS_OutTol) if not results_rBQ.success: err_msg = ('SS Error: Steady-state root finder did not ' + 'solve. results_rBQ.success=False') raise ValueError(err_msg) else: print('SS SUCESSS: steady-state solution converged.') # print(results_rw) r_ss, BQ_ss = results_rBQ.x r_err_ss, BQ_err_ss = results_rBQ.fun # Solve for steady-state wage w_ss implied by r_ss w_ss = firms.get_wt(r_ss, p) # Solve for household steady-state decisions c_s, n_s, b_{s+1} given # r, w, and BQ b_init = 0.0 r_path = r_ss * np.ones(p.S) w_path = w_ss * np.ones(p.S) BQ_path = BQ_ss * np.ones(p.S) c_ss, n_ss, b_ss, n_err_ss, b_err_ss = \ hh.get_cnb_vecs(nb_guess, b_init, r_path, w_path, BQ_path, p.rho_ss, p.SS_EulDif, p, p.SS_EulTol) # Solve for steady-state aggregate labor and aggregate capital L_ss = aggr.get_Lt(n_ss, p) K_ss = aggr.get_Kt(b_ss[1:], p) # Solve for steady-state aggregate output Y, consumption C, # investment I, and net exports Y_ss = firms.get_Yt(K_ss, L_ss, p) C_ss = aggr.get_Ct(c_ss, p) I_ss = aggr.get_It(K_ss, p) NX_ss = aggr.get_NXt(b_ss[1:], p) # Solve for steady-state resource constraint error RCerr_ss = Y_ss - C_ss - I_ss - NX_ss ss_time = time.clock() - start_time ss_output = { 'c_ss': c_ss, 'n_ss': n_ss, 'b_ss': b_ss, 'n_err_ss': n_err_ss, 'b_err_ss': b_err_ss, 'r_ss': r_ss, 'w_ss': w_ss, 'BQ_ss': BQ_ss, 'r_err_ss': r_err_ss, 'BQ_err_ss': BQ_err_ss, 'L_ss': L_ss, 'K_ss': K_ss, 'Y_ss': Y_ss, 'C_ss': C_ss, 'I_ss': I_ss, 'NX_ss': NX_ss, 'RCerr_ss': RCerr_ss, 'ss_time': ss_time } print('n_ss=', n_ss) print('b_ss=', b_ss) print('K_ss=', K_ss) print('L_ss=', L_ss) print('r_ss=', r_ss, ', w_ss=', w_ss, ', BQ_ss=', BQ_ss) print('Maximum abs. labor supply Euler error is: ', np.absolute(n_err_ss).max()) print('Maximum abs. savings Euler error is: ', np.absolute(b_err_ss).max()) print('RC error is: ', RCerr_ss) # Print SS computation time utils.print_time(ss_time, 'SS') if graphs: ss_graphs(c_ss, n_ss, b_ss, p) return ss_output