Skip to content

Commit 5ed4899

Browse files
committed
fixes to frequency weighted reduction
1 parent 979578c commit 5ed4899

5 files changed

Lines changed: 268 additions & 107 deletions

File tree

src/ExtendedStateSpace.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,9 @@ function partition(P::AbstractStateSpace; u=nothing, y=nothing,
491491
P.D[z, w], P.D[z, u], P.D[y, w], P.D[y, u], P.timeevol)
492492
end
493493

494+
"""
495+
partition(P::AbstractStateSpace, nw::Int, nz::Int)
496+
"""
494497
partition(P::AbstractStateSpace, nu1::Int, ny1::Int) = partition(P, w=1:nu1, z=1:ny1)
495498

496499

src/RobustAndOptimalControl.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ include("hinfinity_design.jl")
3131

3232
include("plotting.jl")
3333

34-
export frequency_weighted_reduction, controller_reduction, hsvd
34+
export frequency_weighted_reduction, hsvd
3535
include("reduction.jl")
3636

3737
export h2synthesize

src/reduction.jl

Lines changed: 143 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -2,92 +2,164 @@ using ControlSystems: ssdata
22
# TODO: Implement Reducing unstable linear control systems via real Schur transformation.
33
# By temporarily removing unstable dynamics, reduce, add dynamics back.
44

5-
# TODO: consider implementing methods on slides 158-161 https://cscproxy.mpi-magdeburg.mpg.de/mpcsc/benner/talks/lecture-MOR.pdf
6-
# this requires a generalization of the method below to take a function from
7-
# sys -> P, Q
8-
# see also https://reader.elsevier.com/reader/sd/pii/S0377042700003411?token=E6765A06972F9E3BB94F39600ED6CF86778E628727147EA9D663107BE62929BCAEB6DA92E8FDDDBF0C778059B55935FB&originRegion=eu-west-1&originCreation=20211021132238
9-
# Minimal state-space realization in linear system theory, De Schutter
10-
# Stabilized version of minreal https://perso.uclouvain.be/paul.vandooren/publications/VDooren81.pdf
115

126
"""
13-
frequency_weighted_reduction(G, Wo, Wi)
7+
frequency_weighted_reduction(G, Wo, Wi; residual=true)
148
159
Find Gr such that ||Wₒ(G-Gr)Wᵢ||∞ is minimized.
1610
For a realtive reduction, set Wo = inv(G) and Wi = I.
1711
18-
Ref: Robust and Optimal Control ch. 7.2
12+
If `residual = true`, matched static gain is achieved through "residualization", i.e., setting
13+
```math
14+
0 = A_{21}x_{1} + A_{22}x_{2} + B_{2}u
15+
```
16+
where indices 1/2 correspond to the remaining/truncated states respectively. This choice typically results in a better match in the low-frequency region and a smaller overall error.
17+
18+
Ref: Andras Varga and Brian D.O. Anderson, "Accuracy enhancing methods for the frequency-weighted balancing related model reduction"
19+
https://elib.dlr.de/11746/1/varga_cdc01p2.pdf
1920
"""
20-
function frequency_weighted_reduction(G, Wo, Wi, r)
21+
function frequency_weighted_reduction(G, Wo, Wi, r; residual=true)
22+
iscontinuous(G) || error("Discrete systems not supported yet.")
2123
A,B,C,D = ssdata(G)
24+
n = G.nx
25+
if Wo == 1 || Wo == I
26+
Q1 = grampd(G, :o)
27+
else
28+
Wo = ss(Wo)
29+
if issiso(Wo) && size(G, 1) > 1
30+
Wo = Wo*I(size(G, 1))
31+
end
32+
Ao,Bo,Co,Do = ssdata(Wo)
33+
As = [
34+
A zeros(size(A,1), size(Ao,2))
35+
Bo*C Ao
36+
]
37+
Bs = [
38+
B
39+
Bo*D
40+
]
41+
Cs = [
42+
Do*C Co
43+
]
44+
Ds = Do*D
45+
WoG = ss(As, Bs, Cs, Ds)
46+
Q1 = grampd(WoG, :o)[1:n, 1:n]
47+
end
2248

23-
sys = Wo*G*Wi
24-
n = nstates(G)
25-
2649
if Wi == 1 || Wi == I
27-
P = gram(G, :c)
50+
P1 = grampd(G, :c)
2851
else
29-
P0 = gram(sys, :c)
30-
m = size(P0, 1) - n
31-
P = [I(n) zeros(n, m)] * P0 * [I(n); zeros(m, n)]
52+
Wi = ss(Wi)
53+
if issiso(Wi) && size(G, 2) > 1
54+
Wi = Wi*I(size(G, 1))
55+
end
56+
Ai,Bi,Ci,Di = ssdata(ss(Wi))
57+
As = [
58+
A B*Ci
59+
zeros(size(Ai,1), size(A,2)) Ai
60+
]
61+
Bs = [
62+
B*Di
63+
Bi
64+
]
65+
Cs = [
66+
C D*Ci
67+
]
68+
Ds = D*Di
69+
GWi = ss(As, Bs, Cs, Ds)
70+
P1 = grampd(GWi, :c)[1:n, 1:n]
3271
end
33-
if Wo == 1 || Wo == I
34-
Q = gram(G, :o)
72+
73+
R = Q1
74+
S = P1
75+
U,Σ,V = svd!(R*S)
76+
i1 = 1:r
77+
i2 = r+1:size(A, 1)
78+
U1 = U[:,i1]
79+
V1 = V[:,i1]
80+
U2 = U[:,i2]
81+
V2 = V[:,i2]
82+
Σ1 = Σ[i1]
83+
Y = Matrix(qr!(R'U1).Q)
84+
X = Matrix(qr!(S*V1).Q)
85+
86+
@views if residual
87+
# The code for the residual case is adapted from
88+
# DescriptorSystems.jl and written by Andreas Varga
89+
# https://github.com/andreasvarga/DescriptorSystems.jl/blob/dd144828c3615bea2d5b4977d7fc7f9677dfc9f8/src/order_reduction.jl#L622
90+
# with license https://github.com/andreasvarga/DescriptorSystems.jl/blob/main/LICENSE.md
91+
ONE = one(eltype(A))
92+
L = [Y Matrix(qr!(R'U2).Q)]
93+
Tr = [X Matrix(qr!(S*V2).Q)]
94+
amin = L'A*Tr
95+
bmin = L'B
96+
cmin = C*Tr
97+
Ar = amin[i1,i1]
98+
Er = L[:,i1]'*Tr[:,i1]
99+
Br = bmin[i1,:]
100+
Cr = cmin[:,i1]
101+
Dr = copy(D)
102+
LUF = lu!(amin[i2,i2])
103+
ldiv!(LUF,amin[i2,i1])
104+
ldiv!(LUF,bmin[i2,:])
105+
# apply state residualization formulas
106+
mul!(Dr,cmin[:,i2],bmin[i2,:],-ONE, ONE)
107+
mul!(Br,amin[i1,i2],bmin[i2,:],-ONE, ONE)
108+
mul!(Cr,cmin[:,i2],amin[i2,i1],-ONE, ONE)
109+
mul!(Ar,amin[i1,i2],amin[i2,i1],-ONE, ONE)
110+
# determine a standard reduced system
111+
SV = svd!(Er)
112+
di2 = Diagonal(1 ./sqrt.(SV.S))
113+
return ss(di2*SV.U'*Ar*SV.Vt'*di2, di2*(SV.U'*Br), (Cr*SV.Vt')*di2, Dr)
35114
else
36-
Q0 = gram(sys, :o)
37-
m = size(Q0, 1) - n
38-
Q = [I(n) zeros(n, m)] * Q0 * [I(n); zeros(m, n)]
115+
L = (Y'X)\Y'
116+
T = X
117+
A = L*A*T
118+
B = L*B
119+
C = C*T
120+
D = D
39121
end
40-
41-
L = cholesky(Hermitian((Q+Q')./2), check=false)
42-
issuccess(L) || @warn("Balanced realization failed: Observability grammian not positive definite, system needs to be observable. Result may be inaccurate.")
43-
44-
Q1 = L.U
45-
U,Σ,V = svd(Q1*P*Q1')
46-
Σ .= sqrt.(Σ)
47-
Σ1 = diagm(0 => sqrt.(Σ))
48-
T = Σ1\(U'Q1)
49-
A,B,C,D = T*A/T, T*B, C/T, D
50-
ss(A[1:r, 1:r], B[1:r, :], C[:, 1:r], D, G.timeevol)
122+
ss(A,B,C,D, G.timeevol)
51123
end
52124

53125

54-
"
55-
Lemma 19.1 See Robust and Optimal Control Ch 19.1
56-
"
57-
function controller_reduction_weight(P::ExtendedStateSpace, K)
58-
A, B1, B2, C1, C2, D11, D12, D21, D22 = ssdata_e(P)
59-
Ak,Bk,Ck,Dk = ssdata(K)
60-
R = factorize(I - D22*Dk)
61-
= factorize(I - Dk*D22)
62-
Aw = [
63-
A+B2*Dk*(R\C2) B2*(R̃\Ck)
64-
Bk*(R\C2) Ak+Bk*D22*(R̃\Ck)
65-
]
66-
Bw = [
67-
B2/
68-
Bk*D22/
69-
]
70-
Cw = [R\C2 R\D22*Ck]
71-
Dw = D22/
72-
ss(Aw, Bw, Cw, Dw)
73-
end
74-
75-
"""
76-
controller_reduction(P, K, r, out=false)
126+
# "
127+
# Lemma 19.1 See Robust and Optimal Control Ch 19.1
128+
# "
129+
# function controller_reduction_weight(P::ExtendedStateSpace, K)
130+
# A, B1, B2, C1, C2, D11, D12, D21, D22 = ssdata_e(P)
131+
# Ak,Bk,Ck,Dk = ssdata(K)
132+
# R = factorize(I - D22*Dk)
133+
# R̃ = factorize(I - Dk*D22)
134+
# Aw = [
135+
# A+B2*Dk*(R\C2) B2*(R̃\Ck)
136+
# Bk*(R\C2) Ak+Bk*D22*(R̃\Ck)
137+
# ]
138+
# Bw = [
139+
# B2/R̃
140+
# Bk*D22/R̃
141+
# ]
142+
# Cw = [R\C2 R\D22*Ck]
143+
# Dw = D22/R̃
144+
# ss(Aw, Bw, Cw, Dw)
145+
# end
77146

78-
Minimize ||(K-Kᵣ) W||∞ if out=false
79-
||W (K-Kᵣ)||∞ if out=true
80-
See Robust and Optimal Control Ch 19.1
81-
out indicates if the weight will be applied as output or input weight.
82-
"""
83-
function controller_reduction(P, K, r, out=false)
84-
W = controller_reduction_weight(P, K)
85-
if out
86-
frequency_weighted_reduction(K, W, 1, r)
87-
else
88-
frequency_weighted_reduction(K, 1, W, r)
89-
end
90-
end
147+
# """
148+
# controller_reduction(P, K, r, out=false)
149+
150+
# Minimize ||(K-Kᵣ) W||∞ if out=false
151+
# ||W (K-Kᵣ)||∞ if out=true
152+
# See Robust and Optimal Control Ch 19.1
153+
# out indicates if the weight will be applied as output or input weight.
154+
# """
155+
# function controller_reduction(P, K, r, out=false)
156+
# W = controller_reduction_weight(P, K)
157+
# if out
158+
# frequency_weighted_reduction(K, W, 1, r)
159+
# else
160+
# frequency_weighted_reduction(K, 1, W, r)
161+
# end
162+
# end
91163

92164
"""
93165
hsvd(sys::AbstractStateSpace{Continuous})
@@ -96,10 +168,9 @@ Return the Hankel singular values of `sys`, computed as the eigenvalues of `QP`
96168
Where `Q` and `P` are the Gramians of `sys`.
97169
"""
98170
function hsvd(sys::AbstractStateSpace{Continuous})
99-
P = gram(sys, :c)
100-
Q = gram(sys, :o)
101-
e = eigvals(Q * P)
102-
sqrt.(e)
171+
P = MatrixEquations.plyapc(sys.A, sys.B)
172+
Q = MatrixEquations.plyapc(sys.A', sys.C')
173+
e = svdvals(Q * P)
103174
end
104175

105176
@deprecate minreal2 minreal

0 commit comments

Comments
 (0)