def simulate(simT, par, sol, m, delta, c, P, C, m0s, tau0, delta0, psi, xi): # parallel over initial m for j in prange(m0s.size): # time loop for t in range(simT): tau = np.fmax(tau0 - t, 0) # i. initialize if t == 0: delta[j, t, :] = delta0 m[j, t, :] = m0s[j] P[j, t, :] = 1 # ii. choice linear_interp.interp_2d_vec(par.grid_delta, par.grid_m, sol.c[tau, :, :], delta[j, t, :], m[j, t, :], c[j, t, :]) C[j, t:] = P[j, t, :] * c[j, t, :] # iii. next-period if t < simT - 1: delta[j, t + 1, :] = delta[j, t, :] / (par.G * psi[t + 1, :]) a = m[j, t, :] - c[j, t, :] if tau == 0: a += delta[j, t, :] m[j, t + 1, :] = par.R * a / (par.G * psi[t + 1, :]) + xi[t + 1, :] P[j, t + 1, :] = par.G * psi[t + 1, :] * P[j, t, :]
def solve(t,sol,par): w = sol.w[t] wa = sol.wa[t] wb = sol.wb[t] # a. solve each segment solve_ucon(sol.ucon_c[t,:,:],sol.ucon_d[t,:,:],sol.ucon_v[t,:,:],w,wa,wb,par) solve_dcon(sol.dcon_c[t,:,:],sol.dcon_d[t,:,:],sol.dcon_v[t,:,:],w,wa,par) solve_acon(sol.acon_c[t,:,:],sol.acon_d[t,:,:],sol.acon_v[t,:,:],w,wb,par) solve_con(sol.con_c[t,:,:],sol.con_d[t,:,:],sol.con_v[t,:,:],w,par) # b. upper envelope seg_max = np.zeros(4) for i_n in range(par.Nn): for i_m in range(par.Nm): # i. find max seg_max[0] = sol.ucon_v[t,i_n,i_m] seg_max[1] = sol.dcon_v[t,i_n,i_m] seg_max[2] = sol.acon_v[t,i_n,i_m] seg_max[3] = sol.con_v[t,i_n,i_m] i = np.argmax(seg_max) # ii. over-arching optimal choices sol.inv_v[t,i_n,i_m] = -1.0/seg_max[i] if i == 0: sol.c[t,i_n,i_m] = sol.ucon_c[t,i_n,i_m] sol.d[t,i_n,i_m] = sol.ucon_d[t,i_n,i_m] elif i == 1: sol.c[t,i_n,i_m] = sol.dcon_c[t,i_n,i_m] sol.d[t,i_n,i_m] = sol.dcon_d[t,i_n,i_m] elif i == 2: sol.c[t,i_n,i_m] = sol.acon_c[t,i_n,i_m] sol.d[t,i_n,i_m] = sol.acon_d[t,i_n,i_m] elif i == 3: sol.c[t,i_n,i_m] = sol.con_c[t,i_n,i_m] sol.d[t,i_n,i_m] = sol.con_d[t,i_n,i_m] # c. derivatives # i. m vm = utility.marg_func(sol.c[t],par) sol.inv_vm[t,:,:] = 1.0/vm # ii. n a = par.grid_m_nd - sol.c[t] - sol.d[t] b = par.grid_n_nd + sol.d[t] + pens.func(sol.d[t],par) wb_now = np.zeros(a.shape) linear_interp.interp_2d_vec(par.grid_b_pd,par.grid_a_pd,wb,b.ravel(),a.ravel(),wb_now.ravel()) vn = wb_now sol.inv_vn[t,:,:] = 1.0/vn
def solve_con(out_c,out_d,out_v,w,par): # i. choices c = par.grid_m_nd d = np.zeros(c.shape) # ii. post-decision states a = np.zeros(c.shape) b = par.grid_n_nd # iii. post decision value w_con = np.zeros(c.shape) linear_interp.interp_2d_vec(par.grid_b_pd,par.grid_a_pd,w,b.ravel(),a.ravel(),w_con.ravel()) # iv. value v = utility.func(c,par) + w_con out_c[:] = c out_d[:] = d out_v[:] = v