def stationary_values(self): """ Computes the limit of Sigma_t as t goes to infinity by solving the associated Riccati equation. Computation is via the doubling algorithm (see the documentation in riccati.dare). Returns the limit and the stationary Kalman gain. """ # === simplify notation === # A, Q, G, R = self.A, self.Q, self.G, self.R # === solve Riccati equation, obtain Kalman gain === # Sigma_infinity = riccati.dare(A.T, G.T, R, Q) temp1 = dot(dot(A, Sigma_infinity), G.T) temp2 = inv(dot(G, dot(Sigma_infinity, G.T)) + R) K_infinity = dot(temp1, temp2) return Sigma_infinity, K_infinity
def stationary_values(self): """ Computes the matrix P and scalar d that represent the value function .. math:: V(x) = x' P x + d in the infinite horizon case. Also computes the control matrix F from u = - Fx Returns ------- P : array_like(float) P is part of the value function representation of V(x) = xPx + d F : array_like(float) F is the policy rule that determines the choice of control in each period. d : array_like(float) d is part of the value function representation of V(x) = xPx + d """ # === simplify notation === # Q, R, A, B, C = self.Q, self.R, self.A, self.B, self.C # === solve Riccati equation, obtain P === # A0, B0 = np.sqrt(self.beta) * A, np.sqrt(self.beta) * B P = riccati.dare(A0, B0, Q, R) # == Compute F == # S1 = Q + self.beta * dot(B.T, dot(P, B)) S2 = self.beta * dot(B.T, dot(P, A)) F = solve(S1, S2) # == Compute d == # d = self.beta * np.trace(dot(P, dot(C, C.T))) / (1 - self.beta) # == Bind states and return values == # self.P, self.F, self.d = P, F, d return P, F, d
def stationary_values(self): """ Computes the matrix P and scalar d that represent the value function V(x) = x' P x + d Also computes the control matrix F from u = - Fx """ # === simplify notation === # Q, R, A, B, C = self.Q, self.R, self.A, self.B, self.C # === solve Riccati equation, obtain P === # A0, B0 = np.sqrt(self.beta) * A, np.sqrt(self.beta) * B P = riccati.dare(A0, B0, Q, R) # == Compute F == # S1 = Q + self.beta * dot(B.T, dot(P, B)) S2 = self.beta * dot(B.T, dot(P, A)) F = solve(S1, S2) # == Compute d == # d = self.beta * np.trace(dot(P, dot(C, C.T))) / (1 - self.beta) # == Bind states and return values == # self.P, self.F, self.d = P, F, d return P, F, d
def stationary_values(self): """ Computes the limit of :math:`Sigma_t` as :math:`t \to \infty` by solving the associated Riccati equation. Computation is via the doubling algorithm (see the documentation in riccati.dare). Returns ------- Sigma_infinity : array_like or scalar(float) The infinite limit of Sigma_t K_infinity : array_like or scalar(float) The stationary Kalman gain. """ # === simplify notation === # A, Q, G, R = self.A, self.Q, self.G, self.R # === solve Riccati equation, obtain Kalman gain === # Sigma_infinity = riccati.dare(A.T, G.T, R, Q) temp1 = dot(dot(A, Sigma_infinity), G.T) temp2 = inv(dot(G, dot(Sigma_infinity, G.T)) + R) K_infinity = dot(temp1, temp2) return Sigma_infinity, K_infinity