consumption EulErr_path = [S, T+S-1] matrix, equilibrium time path of the Euler errors for all the savings decisions tpi_time = scalar, number of seconds to compute TPI solution ResDiff = [T-1,] vector, errors in the resource constraint from period 1 to T-1. We don't use T because we are missing one individual's consumption in that period -------------------------------------------------------------------- ''' if TPI_solve == True: print 'BEGIN EQUILIBRIUM TIME PATH COMPUTATION' Gamma1 = 0.9 * b_ss # Make sure init. period distribution is feasible in terms of K K1, K_constr_tpi1 = ssf.get_K(Gamma1) rparams = (A, alpha, delta) r1 = ssf.get_r(rparams, K1, L) BQ1 = (1 + r1) * Gamma1[-1] if K1 <= 0 and Gamma1[-1] > 0: print 'Initial savings distribution is not feasible because K1<=0. Some element(s) of Gamma1 must increase.' elif K1 <= 0 and Gamma1[-1] <= 0: print 'Initial savings distribution is not feasible because K1<=0 and b_{S+1,1}<=0. Some element(s) of Gamma1 must increase.' elif K1 > 0 and Gamma1[-1] <= 0: print 'Initial savings distribution is not feasible because b_{S+1,1}<=0. b_{S+1,1} must increase.' else: # Choose initial guess of path of aggregate capital stock # and total bequests. Use parabola specification # aa*x^2 + bb*x + cc # Initial aggregate capital path Kpath_init = np.zeros(T + S - 2) # Kpath_init[:T] = np.linspace(K1, K_ss, T)
consumption EulErr_path = [S, T+S-1] matrix, equilibrium time path of the Euler errors for all the savings decisions tpi_time = scalar, number of seconds to compute TPI solution ResDiff = [T-1,] vector, errors in the resource constraint from period 1 to T-1. We don't use T because we are missing one individual's consumption in that period -------------------------------------------------------------------- ''' if TPI_solve == True: print 'BEGIN EQUILIBRIUM TIME PATH COMPUTATION' Gamma1 = 0.9 * b_ss # Make sure init. period distribution is feasible in terms of K K1, K_constr_tpi1 = ssf.get_K(Gamma1) rparams = (A, alpha, delta) r1 = ssf.get_r(rparams, K1, L) BQ1 = (1 + r1) * Gamma1[-1] if K1 <= 0 and Gamma1[-1] > 0: print 'Initial savings distribution is not feasible because K1<=0. Some element(s) of Gamma1 must increase.' elif K1 <= 0 and Gamma1[-1] <= 0: print 'Initial savings distribution is not feasible because K1<=0 and b_{S+1,1}<=0. Some element(s) of Gamma1 must increase.' elif K1 > 0 and Gamma1[-1] <= 0: print 'Initial savings distribution is not feasible because b_{S+1,1}<=0. b_{S+1,1} must increase.' else: # Choose initial guess of path of aggregate capital stock # and total bequests. Use parabola specification # aa*x^2 + bb*x + cc # Initial aggregate capital path Kpath_init = np.zeros(T+S-2) # Kpath_init[:T] = np.linspace(K1, K_ss, T)
def TPI(params, Kpath_init, BQpath_init, Gamma1, nvec, Lpath, b_ss, graphs): ''' Generates steady-state time path for all endogenous objects from initial state (K1, BQ1, Gamma1) to the steady state. Inputs: params = length 17 tuple, (S, T, beta, sigma, chi_b, L, A, alpha, delta, K1, K_ss, BQ_ss, C_ss maxiter_TPI, mindist_TPI, xi, TPI_tol) S = integer in [3,80], number of periods an individual lives T = integer > S, number of time periods until steady state beta = scalar in [0,1), discount factor for each model period sigma = scalar > 0, coefficient of relative risk aversion chi_b = scalar > 0, scale parameter on utility of bequests L = scalar > 0, exogenous aggregate labor A = scalar > 0, total factor productivity parameter in firms' production function alpha = scalar in (0,1), capital share of income delta = scalar in [0,1], model-period depreciation rate of capital K1 = scalar > 0, initial period aggregate capital stock K_ss = scalar > 0, steady-state aggregate capital stock BQ_ss = scalar > 0, steady-state total bequests maxiter_TPI = integer >= 1, Maximum number of iterations for TPI mindist_TPI = scalar > 0, Convergence criterion for TPI xi = scalar in (0,1], TPI path updating parameter TPI_tol = scalar > 0, tolerance level for fsolve's in TPI Kpath_init = [T+S-1,] vector, initial guess for the time path of the aggregate capital stock BQpath_init = [T+S-1,] vector, initial guess for the time path of total bequests Gamma1 = [S,] vector, initial period savings distribution nvec = [S,] vector, exogenous labor supply n_{s,t} Lpath = [T+S-1,] vector, exogenous time path for aggregate labor b_ss = [S,] vector, steady-state savings distribution graphs = boolean, =True if want graphs of TPI objects Functions called: c8ssf.get_r c8ssf.get_w get_cbepath c4ssf.get_K Objects in function: start_time = scalar, current processor time in seconds (float) iter_TPI = integer >= 0, current iteration of TPI dist_TPI = scalar >= 0, distance measure for fixed point Kpath_new = [T+S-2,] vector, new path of the aggregate capital stock implied by household and firm optimization BQpath_new = [T+S-1,] vector, new path of total bequests implied by household and firm optimization r_params = length 3 tuple, parameters passed in to get_r w_params = length 2 tuple, parameters passed in to get_w cbe_params = length 6 tuple. parameters passed in to get_cbepath rpath = [T+S-2,] vector, equilibrium time path of the interest rate wpath = [T+S-2,] vector, equilibrium time path of the real wage cpath = [S, T+S-2] matrix, equilibrium time path values of individual consumption c_{s,t} bpath = [S, T+S-1] matrix, equilibrium time path values of individual savings b_{s+1,t+1} EulErrPath = [S, T+S-1] matrix, equilibrium time path values of Euler errors corresponding to individual savings b_{s+1,t+1} (first column is zeros) Kpath_constr = [T+S-2,] boolean vector, =True if K_t<=0 Kpath = [T+S-2,] vector, equilibrium time path of the aggregate capital stock Y_params = length 2 tuple, parameters to be passed to get_Y Ypath = [T+S-2,] vector, equilibrium time path of aggregate output (GDP) Cpath = [T+S-2,] vector, equilibrium time path of aggregate consumption elapsed_time = scalar, time to compute TPI solution (seconds) Returns: bpath, cpath, BQpath, wpath, rpath, Kpath, Ypath, Cpath, EulErrpath, elapsed_time ''' start_time = time.clock() (S, T, beta, sigma, chi_b, L, A, alpha, delta, K1, K_ss, BQ_ss, C_ss, maxiter_TPI, mindist_TPI, xi, TPI_tol) = params iter_TPI = int(0) dist_TPI = 10. Kpath_new = Kpath_init BQpath_new = BQpath_init r_params = (A, alpha, delta) w_params = (A, alpha) cbe_params = (S, T, beta, sigma, chi_b, TPI_tol) while (iter_TPI < maxiter_TPI) and (dist_TPI >= mindist_TPI): iter_TPI += 1 Kpath_init = xi * Kpath_new + (1 - xi) * Kpath_init BQpath_init = xi * BQpath_new + (1 - xi) * BQpath_init rpath = ssf.get_r(r_params, Kpath_init, Lpath) wpath = ssf.get_w(w_params, Kpath_init, Lpath) cpath, bpath, EulErrPath = get_cbepath(cbe_params, nvec, rpath, wpath, BQpath_init, Gamma1, b_ss) Kpath_new = np.zeros(T+S-2) Kpath_new[:T], Kpath_constr = ssf.get_K(bpath[:, :T]) Kpath_new[T:] = K_ss Kpath_constr = np.append(Kpath_constr, np.zeros(S-1, dtype=bool)) Kpath_new[Kpath_constr] = 1 BQpath_new = np.zeros(T+S-2) BQpath_new[:T] = ssf.get_BQ(rpath[:T], bpath[S-1, :T]) BQpath_new[T:] = BQ_ss # Check the distance of Kpath_new and BQpath_new Kdist_TPI = (Kpath_new[1:T] - Kpath_init[1:T]) / Kpath_init[1:T] BQdist_TPI = (BQpath_new[1:T] - BQpath_init[1:T]) / BQpath_init[1:T] dist_TPI = np.absolute(np.append(Kdist_TPI, BQdist_TPI)).max() print ('iter: ', iter_TPI, ', dist: ', dist_TPI, ', max Eul err: ', np.absolute(EulErrPath).max()) if iter_TPI == maxiter_TPI and dist_TPI > mindist_TPI: print 'TPI reached maxiter and did not converge.' elif iter_TPI == maxiter_TPI and dist_TPI <= mindist_TPI: print 'TPI converged in the last iteration. Should probably increase maxiter_TPI.' Kpath = Kpath_new BQpath = BQpath_new Y_params = (A, alpha) Ypath = ssf.get_Y(Y_params, Kpath, Lpath) Cpath = np.zeros(T+S-2) Cpath[:T-1] = ssf.get_C(cpath[:, :T-1]) Cpath[T-1:] = C_ss elapsed_time = time.clock() - start_time if graphs == True: # Plot time path of aggregate capital stock tvec = np.linspace(1, T+S-2, T+S-2) minorLocator = MultipleLocator(1) fig, ax = plt.subplots() plt.plot(tvec, Kpath) # for the minor ticks, use no labels; default NullFormatter ax.xaxis.set_minor_locator(minorLocator) plt.grid(b=True, which='major', color='0.65',linestyle='-') plt.title('Time path for aggregate capital stock') plt.xlabel(r'Period $t$') plt.ylabel(r'Aggregate capital $K_{t}$') # plt.savefig('Kt_Chap8') plt.show() # Plot time path of total bequests tvec = np.linspace(1, T+S-2, T+S-2) minorLocator = MultipleLocator(1) fig, ax = plt.subplots() plt.plot(tvec, BQpath) # for the minor ticks, use no labels; default NullFormatter ax.xaxis.set_minor_locator(minorLocator) plt.grid(b=True, which='major', color='0.65',linestyle='-') plt.title('Time path for total bequests') plt.xlabel(r'Period $t$') plt.ylabel(r'Total bequests $BQ_{t}$') # plt.savefig('BQt_Chap8') plt.show() # Plot time path of aggregate output (GDP) tvec = np.linspace(1, T+S-2, T+S-2) minorLocator = MultipleLocator(1) fig, ax = plt.subplots() plt.plot(tvec, Ypath) # for the minor ticks, use no labels; default NullFormatter ax.xaxis.set_minor_locator(minorLocator) plt.grid(b=True, which='major', color='0.65',linestyle='-') plt.title('Time path for aggregate output (GDP)') plt.xlabel(r'Period $t$') plt.ylabel(r'Aggregate output $Y_{t}$') # plt.savefig('Yt_Chap8') plt.show() # Plot time path of aggregate consumption tvec = np.linspace(1, T+S-2, T+S-2) minorLocator = MultipleLocator(1) fig, ax = plt.subplots() plt.plot(tvec, Cpath) # for the minor ticks, use no labels; default NullFormatter ax.xaxis.set_minor_locator(minorLocator) plt.grid(b=True, which='major', color='0.65',linestyle='-') plt.title('Time path for aggregate consumption') plt.xlabel(r'Period $t$') plt.ylabel(r'Aggregate consumption $C_{t}$') # plt.savefig('Ct_Chap8') plt.show() # Plot time path of real wage tvec = np.linspace(1, T+S-2, T+S-2) minorLocator = MultipleLocator(1) fig, ax = plt.subplots() plt.plot(tvec, wpath) # for the minor ticks, use no labels; default NullFormatter ax.xaxis.set_minor_locator(minorLocator) plt.grid(b=True, which='major', color='0.65',linestyle='-') plt.title('Time path for real wage') plt.xlabel(r'Period $t$') plt.ylabel(r'Real wage $w_{t}$') # plt.savefig('wt_Chap8') plt.show() # Plot time path of real interest rate tvec = np.linspace(1, T+S-2, T+S-2) minorLocator = MultipleLocator(1) fig, ax = plt.subplots() plt.plot(tvec, rpath) # for the minor ticks, use no labels; default NullFormatter ax.xaxis.set_minor_locator(minorLocator) plt.grid(b=True, which='major', color='0.65',linestyle='-') plt.title('Time path for real interest rate') plt.xlabel(r'Period $t$') plt.ylabel(r'Real interest rate $r_{t}$') # plt.savefig('rt_Chap8') plt.show() # Plot time path of individual savings distribution tgrid = np.linspace(1, T, T) sgrid = np.linspace(2, S+1, S) tmat, smat = np.meshgrid(tgrid, sgrid) cmap_bp = matplotlib.cm.get_cmap('summer') fig = plt.figure() ax = fig.gca(projection='3d') ax.set_xlabel(r'period-$t$') ax.set_ylabel(r'age-$s$') ax.set_zlabel(r'individual savings $b_{s,t}$') strideval = max(int(1), int(round(S/10))) ax.plot_surface(tmat, smat, bpath[:, :T], rstride=strideval, cstride=strideval, cmap=cmap_bp) # plt.savefig('bpath_Chap8') plt.show() # Plot time path of individual consumption distribution tgrid = np.linspace(1, T-1, T-1) sgrid = np.linspace(1, S, S) tmat, smat = np.meshgrid(tgrid, sgrid) cmap_cp = matplotlib.cm.get_cmap('summer') fig = plt.figure() ax = fig.gca(projection='3d') ax.set_xlabel(r'period-$t$') ax.set_ylabel(r'age-$s$') ax.set_zlabel(r'individual consumption $c_{s,t}$') strideval = max(int(1), int(round(S/10))) ax.plot_surface(tmat, smat, cpath[:, :T-1], rstride=strideval, cstride=strideval, cmap=cmap_cp) # plt.savefig('cpath_Chap8') plt.show() return (bpath, cpath, BQpath, wpath, rpath, Kpath, Ypath, Cpath, EulErrPath, elapsed_time)