@@ -7,75 +7,65 @@ Algorithm taken from:
7
7
Laub, "A Schur Method for Solving Algebraic Riccati Equations."
8
8
http://dspace.mit.edu/bitstream/handle/1721.1/1301/R-0859-05666488.pdf
9
9
"""
10
- function care (A, B, Q, R)
11
- G = try
12
- B* inv (R)* B'
13
- catch y
14
- if y isa SingularException
15
- error (" R must be non-singular in care." )
16
- else
17
- throw (y)
18
- end
19
- end
20
-
21
- Z = [A - G;
22
- - Q - A' ]
23
-
24
- S = schur (Z)
25
- S = ordschur (S, real (S. values).< 0 )
26
- U = S. Z
27
-
28
- (m, n) = size (U)
29
- U11 = U[1 : div (m, 2 ), 1 : div (n,2 )]
30
- U21 = U[div (m,2 )+ 1 : m, 1 : div (n,2 )]
31
- return U21/ U11
32
- end
33
-
34
- """ `dare(A, B, Q, R)`
35
-
36
- Compute `X`, the solution to the discrete-time algebraic Riccati equation,
37
- defined as A'XA - X - (A'XB)(B'XB + R)^-1(B'XA) + Q = 0, where Q>=0 and R>0
38
-
39
- Algorithm taken from:
40
- Laub, "A Schur Method for Solving Algebraic Riccati Equations."
41
- http://dspace.mit.edu/bitstream/handle/1721.1/1301/R-0859-05666488.pdf
42
- """
43
- function dare (A, B, Q, R)
44
- if ! issemiposdef (Q)
45
- error (" Q must be positive-semidefinite." );
46
- end
47
- if (! isposdef (R))
48
- error (" R must be positive definite." );
49
- end
50
-
51
- n = size (A, 1 );
52
-
53
- E = [
54
- Matrix {Float64} (I, n, n) B* (R\ B' );
55
- zeros (size (A)) A'
56
- ];
57
- F = [
58
- A zeros (size (A));
59
- - Q Matrix {Float64} (I, n, n)
60
- ];
61
-
62
- QZ = schur (F, E);
63
- QZ = ordschur (QZ, abs .(QZ. alpha./ QZ. beta) .< 1 );
10
+ # function care(A, B, Q, R)
11
+ # G = try
12
+ # B*inv(R)*B'
13
+ # catch y
14
+ # if y isa SingularException
15
+ # error("R must be non-singular in care.")
16
+ # else
17
+ # throw(y)
18
+ # end
19
+ # end
20
+ #
21
+ # Z = [A -G;
22
+ # -Q -A']
23
+ #
24
+ # S = schur(Z)
25
+ # S = ordschur(S, real(S.values).<0)
26
+ # U = S.Z
27
+ #
28
+ # (m, n) = size(U)
29
+ # U11 = U[1:div(m, 2), 1:div(n,2)]
30
+ # U21 = U[div(m,2)+1:m, 1:div(n,2)]
31
+ # return U21/U11
32
+ # end
33
+ #
34
+ # """`dare(A, B, Q, R)`
35
+ #
36
+ # Compute `X`, the solution to the discrete-time algebraic Riccati equation,
37
+ # defined as A'XA - X - (A'XB)(B'XB + R)^-1(B'XA) + Q = 0, where Q>=0 and R>0
38
+ #
39
+ # Algorithm taken from:
40
+ # Laub, "A Schur Method for Solving Algebraic Riccati Equations."
41
+ # http://dspace.mit.edu/bitstream/handle/1721.1/1301/R-0859-05666488.pdf
42
+ # """
43
+ # function dare(A, B, Q, R)
44
+ # if !ishermitian(Q)# !issemiposdef(Q)
45
+ # error("Q must be Hermitian");
46
+ # end
47
+ # if (!isposdef(R))
48
+ # error("R must be positive definite");
49
+ # end
50
+ #
51
+ # n = size(A, 1);
52
+ #
53
+ # E = [
54
+ # Matrix{Float64}(I, n, n) B*(R\B');
55
+ # zeros(size(A)) A'
56
+ # ];
57
+ # F = [
58
+ # A zeros(size(A));
59
+ # -Q Matrix{Float64}(I, n, n)
60
+ # ];
61
+ #
62
+ # QZ = schur(F, E);
63
+ # QZ = ordschur(QZ, abs.(QZ.alpha./QZ.beta) .< 1);
64
+ #
65
+ # return QZ.Z[(n+1):end, 1:n]/QZ.Z[1:n, 1:n];
66
+ # end
64
67
65
- return QZ. Z[(n+ 1 ): end , 1 : n]/ QZ. Z[1 : n, 1 : n];
66
- end
67
-
68
- """ `dlyap(A, Q)`
69
68
70
- Compute the solution `X` to the discrete Lyapunov equation
71
- `AXA' - X + Q = 0`.
72
- """
73
- function dlyap (A:: AbstractMatrix , Q)
74
- lhs = kron (A, conj (A))
75
- lhs = I - lhs
76
- x = lhs\ reshape (Q, prod (size (Q)), 1 )
77
- return reshape (x, size (Q))
78
- end
79
69
80
70
""" `gram(sys, opt)`
81
71
@@ -86,7 +76,7 @@ function gram(sys::AbstractStateSpace, opt::Symbol)
86
76
if ! isstable (sys)
87
77
error (" gram only valid for stable A" )
88
78
end
89
- func = iscontinuous (sys) ? lyap : dlyap
79
+ func = iscontinuous (sys) ? lyapc : lyapd
90
80
if opt === :c
91
81
# TODO probably remove type check in julia 0.7.0
92
82
return func (sys. A, sys. B* sys. B' )# ::Array{numeric_type(sys),2} # lyap is type-unstable
@@ -162,14 +152,14 @@ function covar(sys::AbstractStateSpace, W)
162
152
if ! isstable (sys)
163
153
return fill (Inf ,(size (C,1 ),size (C,1 )))
164
154
end
165
- func = iscontinuous (sys) ? lyap : dlyap
155
+
166
156
Q = try
167
- func (A, B* W* B' )
157
+ iscontinuous (sys) ? lyapc (A, B * W * B ' ) : lyapd (A, B* W* B' )
168
158
catch
169
159
error (" No solution to the Lyapunov equation was found in covar" )
170
160
end
171
161
P = C* Q* C'
172
- if ! isdiscrete (sys)
162
+ if iscontinuous (sys)
173
163
# Variance and covariance infinite for direct terms
174
164
direct_noise = D* W* D'
175
165
for i in 1 : size (C,1 )
0 commit comments