Example #1
0
    def get_second_order_coeff_fi_from_fo(self, psi_x, psi_w, psi_q, d_first, d_second):

        gxtp1, gxt, gxtm1, gwtp1, gwpt, gq = d_first

        nx = psi_x.shape[1]
        nw = psi_w.shape[1]

        gxtp1xtp1 = d_second[0]
        gxtp1xt = d_second[1]
        gxtp1xtm1 = d_second[2]
        gxtp1wtp1 = d_second[3]
        gxtp1wt = d_second[4]
        gxtp1q = d_second[5]

        gxtxtp1 = d_second[6]
        gxtxt = d_second[7]
        gxtxtm1 = d_second[8]
        gxtwtp1 = d_second[9]
        gxtwt = d_second[10]
        gxtq = d_second[11]

        gxtm1xtp1 = d_second[12]
        gxtm1xt = d_second[13]
        gxtm1xtm1 = d_second[14]
        gxtm1wtp1 = d_second[15]
        gxtm1wt = d_second[16]
        gxtm1q = d_second[17]

        gwtp1xtp1 = d_second[18]
        gwtp1xt = d_second[19]
        gwtp1xtm1 = d_second[20]
        gwtp1wtp1 = d_second[21]
        gwtp1wt = d_second[22]
        gwtp1q = d_second[23]

        gwtxtp1 = d_second[24]
        gwtxt = d_second[25]
        gwtxtm1 = d_second[26]
        gwtwtp1 = d_second[27]
        gwtwt = d_second[28]
        gwtq = d_second[29]

        gqxtp1 = d_second[30]
        gqxt = d_second[31]
        gqxtm1 = d_second[32]
        gqwtp1 = d_second[33]
        gqwt = d_second[34]
        gqq = d_second[35]

        I_n = np.eye(nx)
        I_n_dot_j = [I_n[:, j].reshape((nx, 1)) for j in range(nx)]
        psiwkronIndotj_list = [np.kron(psi_w, c) for c in I_n_dot_j]
        psiwkronIndotj = np.concatenate(psiwkronIndotj_list, axis=1)
        psiwkronIk = np.kron(psi_w, np.eye(nw))
        psixkronIn = np.kron(psi_x, np.eye(nx))
        psixkronIk = np.kron(psi_x, np.eye(nw))
        psiqkronIn = np.kron(psi_q, np.eye(nx))
        psiqkronIk = np.kron(psi_q, np.eye(nw))

        Inkronpsix = np.kron(np.eye(nx), psi_x)
        Inkronpsiw = np.kron(np.eye(nx), psi_w)
        Inkronpsiq = np.kron(np.eye(nx), psi_q)
        Inkronpsixsquared = np.kron(np.eye(nx), np.dot(psi_x, psi_x))
        Ikkronpsix = np.kron(np.eye(nw), psi_x)

        psixkronpsix = np.kron(psi_x, psi_x)
        psixkronpsiw = np.kron(psi_x, psi_w)
        psiwkronpsix = np.kron(psi_w, psi_x)
        psixkronpsiq = np.kron(psi_x, psi_q)
        psiqkronpsix = np.kron(psi_q, psi_x)
        psiwkronpsiq = np.kron(psi_w, psi_q)
        psiqkronpsiw = np.kron(psi_q, psi_w)
        psiwkronpsiw = np.kron(psi_w, psi_w)

        # equation for psi_xx
        # A psi_xx + gxtp1 psi_xx B + C
        # A = gxt + gxtp1 psi_x
        # B = (psi_x kron psi_x)
        # C =big constant
        # vectorized solution:
        # [(I_nn kron A) + (B' kron gxtp1)] vec(psi_xx) = -vec(C)

        A_for_psixx = gxt + np.dot(gxtp1, psi_x)
        B_for_psixx = np.kron(psi_x, psi_x)

        C_for_psixx_1 = gxtm1xtm1 + 2*np.dot(gxtm1xt, Inkronpsix)
        C_for_psixx_2 = gxtxt + 2*np.dot(gxtxtp1, Inkronpsix) \
            + np.dot(gxtp1xtp1, psixkronpsix)
        C_for_psixx_3 = 2*np.dot(gxtm1xtp1, Inkronpsixsquared)
        C_for_psixx = C_for_psixx_1 + np.dot(C_for_psixx_2, psixkronpsix) \
            + C_for_psixx_3
        leftmat = np.kron(np.eye(nx*nx), A_for_psixx) + \
            np.kron(B_for_psixx.T, gxtp1)
        rightmat = - C_for_psixx.T.flatten()  # one dimensional array
        # two dimensional column array
        rightmat2d = - C_for_psixx.T.reshape(-1, 1)

        invleftmat = linalg.inv(leftmat)

        vec_psixx_sol = np.dot(invleftmat, rightmat)
        vec_psixx_sol2d = np.dot(invleftmat, rightmat2d)

        vec_psi_x_x_bysolve = linalg.solve(leftmat, rightmat)  # twice as fast

        psi_x_x = vec_psixx_sol.reshape((nx, nx*nx), order='F')
        psi_x_x_2d = vec_psixx_sol2d.reshape((nx, nx*nx), order='F')

        # equation for psi_x_w
        # 0= 2*Gammax2*psi_xw + 2*gtm1wt + Gammaxw*(psi_x kron Ik) +
        # Gammaxtm1xt*(In kron psi_x)

        Gamma_xtp1_2 = gxtp1
        Gamma_xtp1_xtp1 = gxtp1xtp1
        Gamma_xtp1_wtp1 = 2*gxtp1wtp1 + np.dot(Gamma_xtp1_xtp1, psiwkronIndotj)
        Gamma_xtp1_wt = 2*gxtp1wt
        Gamma_xtp1_q = 2*gxtp1q + np.dot(Gamma_xtp1_xtp1, psiqkronIn)

        Gamma_xt_2 = gxt + np.dot(Gamma_xtp1_2, psi_x)
        Gamma_xt_xtp1 = 2*gxtxtp1 + np.dot(Gamma_xtp1_xtp1, psixkronIn)
        Gamma_xt_xt = gxtxt + \
            np.dot(Gamma_xtp1_2, psi_x_x) + np.dot(Gamma_xt_xtp1, Inkronpsix)
        Gamma_xt_wt = 2*gxtwt + \
            np.dot(Gamma_xtp1_wt, psixkronIk) + \
            np.dot(Gamma_xt_xt, psiwkronIndotj)

        Gamma_xtm1_xtp1 = 2*gxtm1xtp1
        Gamma_xtm1_xt = 2*gxtm1xt + \
            np.dot(Gamma_xt_xt, psixkronIn) + \
            np.dot(Gamma_xtm1_xtp1, Inkronpsix)

        Gamma_wtp1_wt = np.dot(Gamma_xtp1_wt, psiwkronIk)

        A_for_psi_x_w = 2*Gamma_xt_2
        b_for_psi_x_w = - 2*gxtm1wt + \
            np.dot(Gamma_xt_wt, psixkronIk) + np.dot(Gamma_xtm1_xt, Inkronpsiw)
        psi_x_w = np.dot(linalg.inv(A_for_psi_x_w), b_for_psi_x_w)
        psi_x_w_bysolve = linalg.solve(A_for_psi_x_w, b_for_psi_x_w)

        Gamma_xt_wtp1 = 2*gxtwtp1 + 2 * np.dot(Gamma_xtp1_2, psi_x_w) + np.dot(
            Gamma_xtp1_wtp1, psixkronIk) + np.dot(Gamma_xt_xtp1, Inkronpsiw)
        Gamma_xtm1_wtp1 = 2*gxtm1wtp1 + \
            np.dot(Gamma_xt_wtp1, psixkronIk) + \
            np.dot(Gamma_xtm1_xtp1, Inkronpsiw)

        Gamma_wt_wtp1 = 2*gwtwtp1 + np.dot(Gamma_xt_wtp1, psiwkronIk)

        # equation for psi_x_w
        # Gammax2*psi_xw + gww +  Gammaxw*(psi_w kron Ik)
        A_for_psi_w_w = Gamma_xt_2
        b_for_psi_w_w = gwtwt + np.dot(Gamma_xt_wt, psiwkronIk)
        psi_w_w = np.dot(linalg.inv(A_for_psi_w_w), b_for_psi_w_w)
        psi_w_w_bysolve = linalg.solve(A_for_psi_w_w, b_for_psi_w_w)

        # Compute Vxx
        utility_sym_mat = sympy.Matrix([self.utility])
        du_dx = utility_sym_mat.jacobian([self.xvar_t_sym])
        du_dx_nopar = [u.subs(self.par_to_values_dict) for u in list(du_dx)]
        du_dx_at_ss = [u.subs(self.normal_and_0_to_ss).subs(
            self.ss_solutions_dict) for u in du_dx_nopar]
        du_dx_at_ss = utils.matrix2numpyfloat(sympy.Matrix(du_dx_at_ss))

        beta = self.beta.subs(self.par_to_values_dict)
        Ibetaphi = np.eye(nx) - beta*psi_x
        Ibetaphi = utils.matrix2numpyfloat(Ibetaphi)
        invIbetaphi = linalg.inv(Ibetaphi)
        Vx = np.dot(du_dx_at_ss.T, invIbetaphi)

        du_dx = utility_sym_mat.jacobian([self.xvar_t_sym])
        du_dx_dx = du_dx.jacobian(self.xvar_t_sym)
        du_dx_dx_nopar = du_dx_dx.subs(self.par_to_values_dict)
        du_dx_dx_at_ss = du_dx_dx_nopar.subs(
            self.normal_and_0_to_ss).subs(self.ss_solutions_dict)
        du_dx_dx_at_ss = utils.matrix2numpyfloat(du_dx_dx_at_ss)
        # now, vectorize and then transpose the hessian. Becomes 1 \times nx^2
        # vector
        du_dx_dx_at_ss = du_dx_dx_at_ss.T.reshape(-1, 1).T

        Vxx_term_1 = du_dx_dx_at_ss + beta * np.dot(Vx, psi_x_x)
        inv_of_Vxx_term_2 = np.eye(nx*nx) - beta*psixkronpsix
        inv_of_Vxx_term_2 = utils.matrix2numpyfloat(inv_of_Vxx_term_2) 
        Vxx = np.dot(Vxx_term_1, linalg.inv(inv_of_Vxx_term_2))

        # Gx
        Gx_term_1 = np.dot(gxtp1, psi_w) + gwtp1
        Gx_term_2 = 2*np.dot(Vx, psi_x_w) + np.dot(Vxx, psixkronpsiw)
        Gx_term_2 = utils.matrix2numpyfloat(Gx_term_2)
        matGx_term_2 = Gx_term_2.reshape(nw, nx, order='F')
        Gx_term_3 = np.dot(Vxx, psiwkronpsix)
        Gx_term_3 = utils.matrix2numpyfloat(Gx_term_3)
        matGx_term_3 = Gx_term_3.reshape(nx, nw, order='F')

        theta = self.theta
        Gx = np.dot(Gx_term_1, matGx_term_2 + matGx_term_3.T)/theta

        # Equation (50) bearing on determintation of psi_x_q
        # coe1 psixq + coe2 psixq coe3 + constant terms = 0
        # convert it as
        # (I kron coe1) vec(psixq) + (coe3' kron coe2) vec(psixq) = -vec(constant terms)
        # [(I kron coe1) + (coe3' kron coe2)] vec(psixq)  = -vec(constant terms)
        # Solve it as Ax = b

        coe1 = 2*Gamma_xt_2  # is 7x7
        coe2 = 2*Gamma_xtp1_2  # is 7x7
        coe3 = psi_x  # is 7x7

        # now some constant terms:
        eq50cons_1 = 2*gxtm1q + \
            np.dot(Gamma_xtm1_xtp1, Inkronpsiq) + \
            np.dot(Gamma_xtm1_xt, Inkronpsiq)

        eq50cons_2_a = 2*gxtq + 2*np.dot(Gamma_xtp1_q, psi_x)
        eq50cons_2_b = np.dot(
            Gamma_xt_xtp1, Inkronpsiq) + np.dot(Gamma_xt_xt, psiqkronIn)
        eq50cons_2 = np.dot(eq50cons_2_a+eq50cons_2_b, psi_x)

        E_w_dist = - np.dot(Vx, psi_w).T/theta
        eq50cons_3_list = [np.dot(E_w_dist.T, Gamma_xtm1_wtp1[i, :].reshape(
            (nw, nx), order='F')) for i in range(nx)]

        eq50cons_3 = np.concatenate(eq50cons_3_list)

        eq50cons = eq50cons_1 + eq50cons_2 + eq50cons_3

        cons_for_psixq = eq50cons + np.dot(Gx, psi_x)
        # (coe3' kron coe2) is 49x49, then the I in (I kron coe1) must be 7x7
        A_for_vecpsixq = np.kron(np.eye(nx), coe1) + np.kron(coe3.T, coe2)
        b_for_vecpsixq = -cons_for_psixq.reshape((-1, 1))
        vec_psixq = linalg.solve(A_for_vecpsixq, b_for_vecpsixq)
        psi_x_q = vec_psixq.reshape((nx, nx), order='F')

        # equation for psi_w_q:
        # A psiwq + constants = 0
        # A is 2*Gamma_{x2}
        # psiwq is a matrix and so it is constants. We could vectorize the equation as
        # (I kron A) vec(psiwq) = - vec(constants)

        eq51_coe = 2 * Gamma_xt_2
        eq51_cons_1 = 2*gwtq + \
            np.dot(Gamma_xtp1_wt, psiqkronIk) + np.dot(Gamma_xt_wt, psiqkronIk)

        Gamma_xt_q_1of2 = 2*gxtq + 2 * \
            np.dot(Gamma_xtp1_2, psi_x_q) + np.dot(Gamma_xtp1_q, psi_x)
        Gamma_xt_q_2of2 = np.dot(
            Gamma_xt_xtp1, Inkronpsiq)+np.dot(Gamma_xt_xt, psiqkronIn)
        Gamma_xt_q = Gamma_xt_q_1of2 + Gamma_xt_q_2of2

        eq51_cons_2 = np.dot(Gamma_xt_q, psi_w)

        eq51_cons_3a_list = [np.dot(E_w_dist.T, Gamma_wtp1_wt[i, :].reshape(
            (nw, nw), order='F')) for i in range(nx)]
        eq51_cons_3a = np.concatenate(eq51_cons_3a_list)

        eq51_cons_3b_list = [np.dot(E_w_dist.T, Gamma_wt_wtp1[i, :].reshape(
            (nw, nw), order='F')) for i in range(nx)]
        eq51_cons_3b = np.concatenate(eq51_cons_3b_list)

        eq51_cons_3 = eq51_cons_3a + eq51_cons_3b

        eq51_cons = eq51_cons_1 + eq51_cons_2 + eq51_cons_3
        cons_for_psiwq = eq51_cons + np.dot(Gx, psi_w)

        A_for_vecpsiwq = np.kron(np.eye(nw, nw), eq51_coe)
        b_for_vecpsiwq = -cons_for_psiwq.reshape((-1, 1))
        vec_psiwq = linalg.solve(A_for_vecpsiwq, b_for_vecpsiwq)
        psi_w_q = vec_psiwq.reshape((nx, nw), order='F')

        # equation for Vxq:
        #du_dx =  utility_sym_mat.jacobian([self.xvar_t_sym])
        du_dx_dq = du_dx.jacobian(sympy.Matrix([self.q]))
        du_dx_dq_nopar = du_dx_dq.subs(self.par_to_values_dict)
        du_dx_dq_at_ss = du_dx_dq_nopar.subs(
            self.normal_and_0_to_ss).subs(self.ss_solutions_dict)
        du_dx_dq_at_ss = utils.matrix2numpyfloat(du_dx_dq_at_ss)
        # now, vectorize and then transpose the hessian. Becomes 1 \times nx^2
        # vector
        du_dx_dq_at_ss = du_dx_dq_at_ss.T.reshape(-1, 1).T
        uxq = du_dx_dq_at_ss

        Vxiq_term1 = beta*np.dot(Vx, psi_x_q)+0.5 * \
            np.dot(Vxx, psixkronpsiq+psiqkronpsix)

        Vxq_term2a = 2*np.dot(Vx, psi_x_w) + np.dot(Vxx, psixkronpsiw)
        Vxq_term2a = Vxq_term2a.reshape((nw, nx), order='F')
        Vxq_term2b = np.dot(Vxx, psiwkronpsix)
        Vxq_term2b = Vxq_term2b.reshape((nx, nw), order='F')
        Vxq_term2c = np.dot(Vx, psi_w)
        Vxq_term2 = -beta*0.5 * \
            np.dot(Vxq_term2c, (Vxq_term2a + Vxq_term2b.T))/theta
        Vxq_rhs = uxq + Vxiq_term1 + Vxq_term2
        Vxq_lhs = np.eye(nx) - beta*psi_x
        #Vxq = np.dot(Vxq_rhs, scipy.linalg.inv(Vxq_lhs))
        Vxq_rhs = utils.matrix2numpyfloat(Vxq_rhs)
        Vxq_lhs = utils.matrix2numpyfloat(Vxq_lhs)
        
        Vxq = linalg.solve(Vxq_lhs.T, Vxq_rhs.T).T  # solving A.T x.T = b.T

        # equation for psi_q_q
        Eq52_coe = Gamma_xtp1_2 + Gamma_xt_2
        Eq52_cons_1 = gqq + np.dot(Gamma_xtp1_q + Gamma_xt_q, psi_q)

        Gamma_wtp1_q_a = 2*gwtp1q + 2 * \
            np.dot(Gamma_xtp1_2, psi_w_q) + np.dot(Gamma_xtp1_wtp1, psiqkronIk)
        Gamma_wtp1_q_b = np.dot(
            Gamma_xtp1_q, psi_w) + np.dot(Gamma_xt_wtp1, psiqkronIk)
        Gamma_wtp1_q = Gamma_wtp1_q_a + Gamma_wtp1_q_b

        Eq52_cons_2a = np.dot(Gamma_wtp1_q, E_w_dist)

        Gamma_wtp1_wtp1 = gwtp1wtp1 + \
            np.dot(Gamma_xtp1_2, psi_w_w)+np.dot(Gamma_xtp1_wtp1, psiwkronIk)

        E_wkronw_dist = np.eye(
            nw) + np.dot(np.dot(Vx, psi_w).T, np.dot(Vx, psi_w))/(theta**2)
        E_wkronw_dist = E_wkronw_dist.reshape((-1, 1))
        Eq52_cons_2b = np.dot(Gamma_wtp1_wtp1, E_wkronw_dist)
        Eq52_cons_2 = Eq52_cons_2a + Eq52_cons_2b
        Eq52_cons = Eq52_cons_1 + Eq52_cons_2

        cons_psiqq_a = (np.dot(gxtp1, psi_w) + gwtp1)/theta

        cons_psiqq_b = 2*np.dot(Vx, psi_w_q) + np.dot(Vxx,
                                                      (psiwkronpsiq+psiqkronpsiw)) + 2*np.dot(Vxq, psi_w)
        cons_psiqq_ab = np.dot(cons_psiqq_a, cons_psiqq_b.T)

        cons_psiqq_c_1 = (
            np.dot(Vx, psi_w_w) + np.dot(Vxx, psiwkronpsiw)).reshape((nw, nw), order='F')
        cons_psiqq_c = np.dot(cons_psiqq_c_1.T, E_w_dist)
        cons_psiqq_ac = np.dot(cons_psiqq_a, cons_psiqq_c)

        cons_psiqq_d = np.dot(cons_psiqq_c_1, E_w_dist)
        cons_psiqq_ad = np.dot(cons_psiqq_a, cons_psiqq_d)

        terms_in_Eq56 = np.dot(
            Gx, psi_q) - cons_psiqq_ab - cons_psiqq_ac - cons_psiqq_ad
        #terms_in_Eq56 =  np.dot(Gx, psi_q) + cons_psiqq_ab - cons_psiqq_ac - cons_psiqq_ad

        cons_for_psiqq = Eq52_cons + terms_in_Eq56
        cons_for_psiqq = utils.matrix2numpyfloat(cons_for_psiqq)

        psi_q_q = linalg.solve(Eq52_coe, -cons_for_psiqq)

        self.psi_x_x = psi_x_x
        self.psi_x_w = psi_x_w
        self.psi_x_q = psi_x_q
        self.psi_w_w = psi_w_w
        self.psi_w_q = psi_w_q
        self.psi_q_q = psi_q_q
        
        return psi_x_x, psi_x_w, psi_x_q, psi_w_w, psi_w_q, psi_q_q
Example #2
0
    def get_first_order_approx_coeff_fi(self, eqs=[], param_vals_d={}, mod='numpy',
        return_evaluated_der=False):

        beta = self.beta.subs(self.par_to_values_dict)
        theta = self.theta
        d_first, d_second = self.get_dgdxw12_evaluated_at_ss(mod='numpy')

        gxtp1_ss, gx_ss, gxtm1_ss, gwtp1_ss, gwt_ss, gq_ss = d_first
                    
        gxtp1_ss = utils.matrix2numpyfloat(gxtp1_ss)
        gx_ss = utils.matrix2numpyfloat(gx_ss)
        gxtm1_ss = utils.matrix2numpyfloat(gxtm1_ss)
        gwtp1_ss = utils.matrix2numpyfloat(gwtp1_ss)
        gwt_ss = utils.matrix2numpyfloat(gwt_ss)

        nx = gxtp1_ss.shape[1]
        # quad_coeffmat_in_eq_for_P is Uhlig's \Psi matrix, sensible
        quad_coeffmat_in_eq_for_P = gxtp1_ss
        # lin_coeffmat_in_eq_for_P is Uhlig's (-\Gamma) matrix, sensible
        lin_coeffmat_in_eq_for_P = gx_ss
        # cons_coeffmat_in_eq_for_P is Uhlig's (-\Theta)\Psi matrix, sensible
        cons_coeffmat_in_eq_for_P = gxtm1_ss

        nnzero = np.zeros((nx, nx))

        # this is Uhlig's Chi matrix:
        lin_con_mat = np.bmat(
            [[-lin_coeffmat_in_eq_for_P, -cons_coeffmat_in_eq_for_P],
             [np.identity(nx), nnzero]])

        # this is Uhlig's Delta matrix:
        quad_mat = np.bmat(
            [[quad_coeffmat_in_eq_for_P, nnzero], [nnzero, np.identity(nx)]])

        stable_psi_x = utils.solve_quad_matrix_stable_sol_QZ(lin_con_mat,
                                                            quad_mat, nx)
        # print 'stable_psi_x', stable_psi_x   
        psi_x = stable_psi_x
        psi_w_inner = np.dot(gxtp1_ss, stable_psi_x) + gx_ss
        psi_w = - np.dot(np.linalg.inv(psi_w_inner), gwt_ss)

        psi_q_inv_term = linalg.inv(np.dot(gxtp1_ss, psi_x) +
                                    gxtp1_ss + gx_ss)

        coef_on_dist_E = np.dot(gxtp1_ss, psi_w) + gwtp1_ss

        utility_sym_mat = sympy.Matrix([self.utility])

        du_dx = utility_sym_mat.jacobian([self.xvar_t_sym])
        du_dx_nopar = [u.subs(self.par_to_values_dict) for u in list(du_dx)]
        du_dx_at_ss = [u.subs(self.normal_and_0_to_ss).subs(
            self.ss_solutions_dict) for u in du_dx_nopar]


        du_dx_at_ss = utils.matrix2numpyfloat(sympy.Matrix(du_dx_at_ss))
        nx = len(self.xvar_t_sym)
        Ibetaphi = np.eye(nx) - beta*psi_x 
        Ibetaphi = utils.matrix2numpyfloat(Ibetaphi)
        invIbetaphi = linalg.inv(Ibetaphi)

        Vx = np.dot(du_dx_at_ss.T, invIbetaphi)

        E_w_dist = - np.dot(Vx, psi_w).T/theta

        vec_for_diag = np.dot(coef_on_dist_E, E_w_dist)

        diag_mat = np.diag(vec_for_diag)

        psi_q = - np.dot(psi_q_inv_term, gq_ss + diag_mat)

        self.psi_x = psi_x
        self.psi_w = psi_w
        self.psi_q = psi_q
        


        if return_evaluated_der:
            return psi_x, psi_w, psi_q, d_first, d_second
        else:
            return psi_x, psi_w, psi_q