Lyapunov Equation
lyapunov.Rd
This function solves the Lyapunov equation
$$P = A P A' + Q$$
where \(A,Q\) are real valued, square matrices and \(Q\) is symmetric.
The Lyapunov equation has a unique solution if
\(\lambda_i(A)\lambda_j(A) \neq 1\) holds
for all eigenvalues of \(A\).
If \(A\) is stable (i.e. the spectral radius of \(A\) is less than one) and
\(Q\) is positive semidefinite then the solution \(P\) is also positive semidefinite.
The procedure uses the Schur decomposition(s) of \(A\) and computes
the solution "column by column",
see (Kitagawa 1977; Hammarling 1982)
.
Usage
lyapunov(A, Q, non_stable = c("ignore", "warn", "stop"), attach_lambda = FALSE)
Arguments
- A, Q
\((m,m)\) matrices. Note that the routine silently assumes that \(Q\) is symmetric (and hence the solution \(P\) is also symmetric).
- non_stable
(character string) indicates what to do, when \(A\) is not stable.
- attach_lambda
(boolean) if yes, then the eigenvalues of \(A\) are attached to the solution \(P\) as an attribute.
References
Kitagawa G (1977). “An algorithm for solving the matrix equation X = FXF T + S.” International Journal of Control, 25(5), 745-753. doi:10.1080/00207177708922266 , http://dx.doi.org/10.1080/00207177708922266, http://dx.doi.org/10.1080/00207177708922266 .
Hammarling SJ (1982). “Numerical solution of the stable, nonnegative definite Lyapunov equation.” IMA Journal of Numerical Analysis, 2(3), 303--323. ISSN 0272-4979 (print), 1464-3642 (electronic).
Examples
# A is stable and Q is positve definite
m = 4
A = diag(runif(m, min = -0.9, max = 0.9))
V = matrix(rnorm(m*m), nrow = m, ncol = m)
A = V %*% A %*% solve(V)
B = matrix(rnorm(m*m), nrow = m, ncol = m)
Q = B %*% t(B)
P = lyapunov(A, Q)
all.equal(P, A %*% P %*% t(A) + Q)
#> [1] TRUE
# unstable matrix A
A = diag(runif(m, min = -0.9, max = 0.9))
A[1,1] = 2
V = matrix(rnorm(m*m), nrow = m, ncol = m)
A = V %*% A %*% solve(V)
P = lyapunov(A, Q)
all.equal(P, A %*% P %*% t(A) + Q)
#> [1] TRUE
# note that the solution P (in general) is not positive semidefinite
eigen(P, only.values= TRUE, symmetric = TRUE)$values
#> [1] 57.7361397 2.0927215 0.4027596 -4.3775638
# attach the eigenvalues of A to the solution P
P = lyapunov(A, Q, attach = TRUE)
print(P)
#> [,1] [,2] [,3] [,4]
#> [1,] 41.585908 5.9572096 3.2297975 25.1086162
#> [2,] 5.957210 2.5636481 -0.6642377 3.9508067
#> [3,] 3.229797 -0.6642377 -3.3056971 -0.2716796
#> [4,] 25.108616 3.9508067 -0.2716796 15.0101978
#> attr(,"lambda")
#> [1] 2.00000000+0i -0.75513101+0i 0.03647497+0i 0.04727284+0i
# issue a warning message
P = lyapunov(A, Q, non_stable = 'warn')
#> Warning: "A" matrix is not stable
if (FALSE) {
# throw an error
P = lyapunov(A, Q, non_stable = 'stop')
}