Skip to content

Commit f133825

Browse files
authored
use ME for gram (#588)
Improves balred and baltrunc significantly
1 parent c2c65dc commit f133825

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

src/ControlSystems.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export LTISystem,
2828
hinfnorm,
2929
linfnorm,
3030
gram,
31+
grampd,
3132
ctrb,
3233
obsv,
3334
place,

src/matrix_comps.jl

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,45 @@ function dlyap(A::AbstractMatrix, Q)
3333
lyapd(A, Q)
3434
end
3535

36-
"""`gram(sys, opt)`
3736

38-
Compute the grammian of system `sys`. If `opt` is `:c`, computes the
39-
controllability grammian. If `opt` is `:o`, computes the observability
40-
grammian."""
41-
function gram(sys::AbstractStateSpace, opt::Symbol)
37+
"""
38+
U = grampd(sys, opt)
39+
40+
Return a Cholesky factor `U` of the grammian of system `sys`. If `opt` is `:c`, computes the
41+
controllability grammian `G = U*U'`. If `opt` is `:o`, computes the observability
42+
grammian `G = U'U`.
43+
44+
Obtain a `Cholesky` object by `Cholesky(U)` for observability grammian
45+
"""
46+
function grampd(sys::AbstractStateSpace, opt::Symbol)
4247
if !isstable(sys)
4348
error("gram only valid for stable A")
4449
end
45-
lyapf = iscontinuous(sys) ? lyapc : lyapd
50+
func = iscontinuous(sys) ? MatrixEquations.plyapc : MatrixEquations.plyapd
4651
if opt === :c
47-
return lyapf(sys.A, sys.B*sys.B')
52+
func(sys.A, sys.B)
4853
elseif opt === :o
49-
return lyapf(Matrix(sys.A'), sys.C'*sys.C)
54+
func(sys.A', sys.C')
5055
else
5156
error("opt must be either :c for controllability grammian, or :o for
5257
observability grammian")
5358
end
5459
end
5560

61+
"""
62+
gram(sys, opt)
63+
64+
Compute the grammian of system `sys`. If `opt` is `:c`, computes the
65+
controllability grammian. If `opt` is `:o`, computes the observability
66+
grammian.
67+
68+
See also [`grampd`](@ref)
69+
"""
70+
function gram(sys::AbstractStateSpace, opt::Symbol)
71+
U = grampd(sys, opt)
72+
opt === :c ? U*U' : U'U
73+
end
74+
5675
"""
5776
obsv(A, C, n=size(A,1))
5877
obsv(sys, n=sys.nx)
@@ -459,13 +478,9 @@ Glad, Ljung, Reglerteori: Flervariabla och Olinjära metoder
459478
"""
460479
function balreal(sys::ST) where ST <: AbstractStateSpace
461480
P = gram(sys, :c)
462-
Q = gram(sys, :o)
481+
Q1 = grampd(sys, :o)
482+
Q = Q1'Q1
463483

464-
Q1 = try
465-
cholesky(Hermitian(Q)).U
466-
catch
467-
throw(ArgumentError("Balanced realization failed: Observability grammian not positive definite, system needs to be observable"))
468-
end
469484
U,Σ,V = svd(Q1*P*Q1')
470485
Σ .= sqrt.(Σ)
471486
Σ1 = diagm(0 => sqrt.(Σ))
@@ -487,7 +502,7 @@ function balreal(sys::ST) where ST <: AbstractStateSpace
487502
display(Σ)
488503
end
489504

490-
sysr = ST(T*sys.A/T, T*sys.B, sys.C/T, sys.D, sys.timeevol), diagm(Σ), T
505+
sysr = ST(T*sys.A/T, T*sys.B, sys.C/T, sys.D, sys.timeevol), Diagonal(Σ), T
491506
end
492507

493508

0 commit comments

Comments
 (0)