def find_PFd(A, B, Q, R, Rf, beta=.95): """ Taking the parameters A, B, Q, R as found in the `setup_matrices`, we find the value function of the optimal linear regulator problem. This is steps 2 and 3 in the lecture notes. Parameters ---------- (A, B, Q, R) : Array(Float, ndim=2) The matrices that describe the oligopoly problem Returns ------- (P, F, d) : Array(Float, ndim=2) The matrix that describes the value function of the optimal linear regulator problem. """ lq = LQ(Q, -R, A, B, beta=beta) P, F, d = lq.stationary_values() Af = np.vstack((np.hstack([A-np.dot(B,F), np.array([[0., 0., 0., 0., 0.]]).T]),np.array([[0., 0., 0., 0., 0., 1.]]))) Bf = np.array([[0., 0., 0., 0., 0., 1.]]).T lqf = LQ(Q, -Rf, Af, Bf, beta=beta) Pf, Ff, df = lqf.stationary_values() return P, F, d, Pf, Ff, df
def canonical(self): """ Compute canonical preference representation Uses auxiliary problem of 9.4.2, with the preference shock process reintroduced Calculates pihat, llambdahat and ubhat for the equivalent canonical household technology """ Ac1 = np.hstack((self.deltah,np.zeros((self.nh,self.nz)))) Ac2 = np.hstack((np.zeros((self.nz,self.nh)),self.a22)) Ac = np.vstack((Ac1,Ac2)) Bc = np.vstack((self.thetah,np.zeros((self.nz,self.nc)))) Cc = np.vstack((np.zeros((self.nh,self.nw)),self.c2)) Rc1 = np.hstack((self.llambda.T.dot(self.llambda),-self.llambda.T.dot(self.ub))) Rc2 = np.hstack((-self.ub.T.dot(self.llambda),self.ub.T.dot(self.ub))) Rc = np.vstack((Rc1,Rc2)) Qc = self.pih.T.dot(self.pih) Nc = np.hstack((self.pih.T.dot(self.llambda),-self.pih.T.dot(self.ub))) lq_aux = LQ(Qc, Rc, Ac, Bc, N = Nc, beta=self.beta) P1, F1, d1 = lq_aux.stationary_values() self.F_b = F1[:,0:self.nh] self.F_f = F1[:,self.nh:] self.pihat = np.linalg.cholesky(self.pih.T.dot(self.pih) + self.beta.dot(self.thetah.T).dot(P1[0:self.nh,0:self.nh]).dot(self.thetah)).T self.llambdahat = self.pihat.dot(self.F_b) self.ubhat = - self.pihat.dot(self.F_f) return
def find_PFd(A, B, Q, R, beta=.95): """ Taking the parameters A, B, Q, R as found in the `setup_matrices`, we find the value function of the optimal linear regulator problem. This is steps 2 and 3 in the lecture notes. Parameters ---------- (A, B, Q, R) : Array(Float, ndim=2) The matrices that describe the oligopoly problem Returns ------- (P, F, d) : Array(Float, ndim=2) The matrix that describes the value function of the optimal linear regulator problem. """ lq = LQ(Q, -R, A, B, beta=beta) P, F, d = lq.stationary_values() return P, F, d
def computeG(A0, A1, d, Q0, tau0, beta, mu): """ Compute government income given mu and return tax revenues and policy matrixes for the planner. Parameters ---------- A0 : float A constant parameter for the inverse demand function A1 : float A constant parameter for the inverse demand function d : float A constant parameter for quadratic adjustment cost of production Q0 : float An initial condition for production tau0 : float An initial condition for taxes beta : float A constant parameter for discounting mu : float Lagrange multiplier Returns ------- T0 : array(float) Present discounted value of government spending A : array(float) One of the transition matrices for the states B : array(float) Another transition matrix for the states F : array(float) Policy rule matrix P : array(float) Value function matrix """ # Create Matrices for solving Ramsey problem R = np.array([[0, -A0 / 2, 0, 0], [-A0 / 2, A1 / 2, -mu / 2, 0], [0, -mu / 2, 0, 0], [0, 0, 0, d / 2]]) A = np.array([[1, 0, 0, 0], [0, 1, 0, 1], [0, 0, 0, 0], [-A0 / d, A1 / d, 0, A1 / d + 1 / beta]]) B = np.array([0, 0, 1, 1 / d]).reshape(-1, 1) Q = 0 # Use LQ to solve the Ramsey Problem. lq = LQ(Q, -R, A, B, beta=beta) P, F, d = lq.stationary_values() # Need y_0 to compute government tax revenue. P21 = P[3, :3] P22 = P[3, 3] z0 = np.array([1, Q0, tau0]).reshape(-1, 1) u0 = -P22**(-1) * P21.dot(z0) y0 = np.vstack([z0, u0]) # Define A_F and S matricies AF = A - B.dot(F) S = np.array([0, 1, 0, 0]).reshape(-1, 1).dot(np.array([[0, 0, 1, 0]])) # Solves equation (25) temp = beta * AF.T.dot(S).dot(AF) Omega = solve_discrete_lyapunov(np.sqrt(beta) * AF.T, temp) T0 = y0.T.dot(Omega).dot(y0) return T0, A, B, F, P
def computeG(A0, A1, d, Q0, tau0, beta, mu): """ Compute government income given mu and return tax revenues and policy matrixes for the planner. Parameters ---------- A0 : float A constant parameter for the inverse demand function A1 : float A constant parameter for the inverse demand function d : float A constant parameter for quadratic adjustment cost of production Q0 : float An initial condition for production tau0 : float An initial condition for taxes beta : float A constant parameter for discounting mu : float Lagrange multiplier Returns ------- T0 : array(float) Present discounted value of government spending A : array(float) One of the transition matrices for the states B : array(float) Another transition matrix for the states F : array(float) Policy rule matrix P : array(float) Value function matrix """ # Create Matrices for solving Ramsey problem R = np.array([[0, -A0/2, 0, 0], [-A0/2, A1/2, -mu/2, 0], [0, -mu/2, 0, 0], [0, 0, 0, d/2]]) A = np.array([[1, 0, 0, 0], [0, 1, 0, 1], [0, 0, 0, 0], [-A0/d, A1/d, 0, A1/d+1/beta]]) B = np.array([0, 0, 1, 1/d]).reshape(-1, 1) Q = 0 # Use LQ to solve the Ramsey Problem. lq = LQ(Q, -R, A, B, beta=beta) P, F, d = lq.stationary_values() # Need y_0 to compute government tax revenue. P21 = P[3, :3] P22 = P[3, 3] z0 = np.array([1, Q0, tau0]).reshape(-1, 1) u0 = -P22**(-1) * P21.dot(z0) y0 = np.vstack([z0, u0]) # Define A_F and S matricies AF = A - B.dot(F) S = np.array([0, 1, 0, 0]).reshape(-1, 1).dot(np.array([[0, 0, 1, 0]])) # Solves equation (25) temp = beta * AF.T.dot(S).dot(AF) Omega = solve_discrete_lyapunov(np.sqrt(beta) * AF.T, temp) T0 = y0.T.dot(Omega).dot(y0) return T0, A, B, F, P
def __init__(self, information, technology, preferences): # === Unpack the tuples which define information, technology and preferences === # self.a22, self.c2, self.ub, self.ud = information self.phic, self.phig, self.phii, self.gamma, self.deltak, self.thetak = technology self.beta, self.llambda, self.pih, self.deltah, self.thetah = preferences # === Computation of the dimension of the structural parameter matrices === # self.nb,self.nh = self.llambda.shape self.nd,self.nc = self.phic.shape self.nz,self.nw = self.c2.shape junk,self.ng = self.phig.shape self.nk,self.ni = self.thetak.shape # === Creation of various useful matrices === # uc = np.hstack((np.eye(self.nc),np.zeros((self.nc,self.ng)))) ug = np.hstack((np.zeros((self.ng,self.nc)),np.eye(self.ng))) phiin = np.linalg.inv(np.hstack((self.phic,self.phig))) phiinc = uc.dot(phiin) phiing = ug.dot(phiin) b11 = - self.thetah.dot(phiinc).dot(self.phii) a1 = self.thetah.dot(phiinc).dot(self.gamma) a12 = np.vstack((self.thetah.dot(phiinc).dot(self.ud), np.zeros((self.nk,self.nz)))) # === Creation of the A Matrix for the state transition of the LQ problem === # a11 = np.vstack((np.hstack((self.deltah,a1)), np.hstack((np.zeros((self.nk,self.nh)),self.deltak)))) self.A = np.vstack((np.hstack((a11,a12)), np.hstack((np.zeros((self.nz,self.nk+self.nh)),self.a22)))) # === Creation of the B Matrix for the state transition of the LQ problem === # b1 = np.vstack((b11,self.thetak)) self.B = np.vstack((b1,np.zeros((self.nz,self.ni)))) # === Creation of the C Matrix for the state transition of the LQ problem === # self.C = np.vstack((np.zeros((self.nk+self.nh,self.nw)),self.c2)) # === Define R,W and Q for the payoff function of the LQ problem === # self.H = np.hstack((self.llambda,self.pih.dot(uc).dot(phiin).dot(self.gamma),self.pih.dot(uc).dot(phiin).dot(self.ud)-self.ub,-self.pih.dot(uc).dot(phiin).dot(self.phii))) self.G = ug.dot(phiin).dot(np.hstack((np.zeros((self.nd,self.nh)),self.gamma,self.ud,-self.phii))) self.S = (self.G.T.dot(self.G) + self.H.T.dot(self.H))/2 self.nx = self.nh+self.nk+self.nz self.n = self.ni+self.nh+self.nk+self.nz self.R = self.S[0:self.nx,0:self.nx] self.W = self.S[self.nx:self.n,0:self.nx] self.Q = self.S[self.nx:self.n,self.nx:self.n] # === Use quantecon's LQ code to solve our LQ problem === # lq = LQ(self.Q, self.R, self.A, self.B, self.C, N=self.W, beta=self.beta) self.P, self.F, self.d = lq.stationary_values() # === Construct output matrices for our economy using the solution to the LQ problem === # self.A0 = self.A - self.B.dot(self.F) self.Sh = self.A0[0:self.nh,0:self.nx] self.Sk = self.A0[self.nh:self.nh+self.nk,0:self.nx] self.Sk1 = np.hstack((np.zeros((self.nk,self.nh)),np.eye(self.nk),np.zeros((self.nk,self.nz)))) self.Si = -self.F self.Sd = np.hstack((np.zeros((self.nd,self.nh+self.nk)),self.ud)) self.Sb = np.hstack((np.zeros((self.nb,self.nh+self.nk)),self.ub)) self.Sc = uc.dot(phiin).dot(-self.phii.dot(self.Si) + self.gamma.dot(self.Sk1) + self.Sd) self.Sg = ug.dot(phiin).dot(-self.phii.dot(self.Si) + self.gamma.dot(self.Sk1) + self.Sd) self.Ss = self.llambda.dot(np.hstack((np.eye(self.nh),np.zeros((self.nh,self.nk+self.nz))))) + self.pih.dot(self.Sc) # === Calculate eigenvalues of A0 === # self.A110 = self.A0[0:self.nh+self.nk,0:self.nh+self.nk] self.endo = np.linalg.eigvals(self.A110) self.exo = np.linalg.eigvals(self.a22) # === Construct matrices for Lagrange Multipliers === # self.Mk = -2*np.asscalar(self.beta)*(np.hstack((np.zeros((self.nk,self.nh)),np.eye(self.nk),np.zeros((self.nk,self.nz))))).dot(self.P).dot(self.A0) self.Mh = -2*np.asscalar(self.beta)*(np.hstack((np.eye(self.nh),np.zeros((self.nh,self.nk)),np.zeros((self.nh,self.nz))))).dot(self.P).dot(self.A0) self.Ms = -(self.Sb - self.Ss) self.Md = -(np.linalg.inv(np.vstack((self.phic.T,self.phig.T))).dot(np.vstack((self.thetah.T.dot(self.Mh) + self.pih.T.dot(self.Ms),-self.Sg)))) self.Mc = -(self.thetah.T.dot(self.Mh) + self.pih.T.dot(self.Ms)) self.Mi = -(self.thetak.T.dot(self.Mk))