Skip to content

Commit 3a75d7a

Browse files
authored
Merge pull request #40 from JuliaControl/stabunstab
add stable/unstable decomposition
2 parents ebf840c + f2be311 commit 3a75d7a

File tree

4 files changed

+75
-3
lines changed

4 files changed

+75
-3
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "RobustAndOptimalControl"
22
uuid = "21fd56a4-db03-40ee-82ee-a87907bee541"
33
authors = ["Fredrik Bagge Carlson", "Marcus Greiff"]
4-
version = "0.3.2"
4+
version = "0.3.3"
55

66
[deps]
77
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
@@ -26,7 +26,7 @@ UnPack = "3a884ed6-31ef-47d7-9d2a-63182c4928ed"
2626
[compat]
2727
ChainRulesCore = "1"
2828
ComponentArrays = "0.9, 0.10, 0.11"
29-
ControlSystems = "0.11.9"
29+
ControlSystems = "0.12"
3030
DescriptorSystems = "1.2"
3131
Distributions = "0.25"
3232
GenericSchur = "0.5.2"

src/RobustAndOptimalControl.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ using ChainRulesCore
2424
export show_construction, vec2sys
2525
include("utils.jl")
2626

27-
export dss, hinfnorm2, h2norm, hankelnorm, nugap, νgap, baltrunc2
27+
export dss, hinfnorm2, h2norm, hankelnorm, nugap, νgap, baltrunc2, stab_unstab, baltrunc_unstab
2828
include("descriptor.jl")
2929

3030
export ExtendedStateSpace, system_mapping, performance_mapping, noise_mapping, ssdata_e, partition, ss

src/descriptor.jl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,52 @@ function baltrunc2(sys::LTISystem; residual=false, n=missing, kwargs...)
8686
ss(sysr), hs
8787
end
8888

89+
# function coprime_baltrunc(sys; residual=false, n=missing, kwargs...)
90+
# N,M = DescriptorSystems.glcf(dss(sys), mindeg=true, mininf=true, fast=false)
91+
# nu = size(N.B, 2)
92+
# # A,E,B,C,D = DescriptorSystems.dssdata(N)
93+
# # NM = DescriptorSystems.dss(A,E,[B M.B],C,[D M.D])
94+
# # Nr1, hs = DescriptorSystems.gbalmr(N; matchdc=residual, ord=n-size(M.A, 1), kwargs...)
95+
# NM = [N M]
96+
# sysr, hs = DescriptorSystems.gbalmr(NM; matchdc=residual, ord=n, kwargs...)
97+
98+
# A,E,B,C,D = DescriptorSystems.dssdata(sysr)
99+
100+
# Nr = DescriptorSystems.dss(A,E,B[:, 1:nu],C,D[:, 1:nu])
101+
# Mr = DescriptorSystems.dss(A,E,B[:, nu+1:end],C,D[:, nu+1:end])
102+
# sysr = Mr \ Nr
103+
# ss(sysr), hs
104+
# # Nr, Mr
105+
# end
106+
107+
108+
"""
109+
baltrunc_unstab(sys::LTISystem; residual = false, n = missing, kwargs...)
110+
111+
Balanced truncation for unstable models. An additive decomposition of sys into `sys = sys_stable + sys_unstable` is performed after which `sys_stable` is reduced. The order `n` must not be less than the number of unstable poles.
112+
113+
See `baltrunc2` for other keyword arguments.
114+
"""
115+
function baltrunc_unstab(sys::LTISystem; residual=false, n=missing, kwargs...)
116+
stab, unstab = DescriptorSystems.gsdec(dss(sys); job="stable", kwargs...)
117+
nx_unstab = size(unstab.A, 1)
118+
if n isa Integer && n < nx_unstab
119+
error("The model contains $(nx_unstab) poles outside the stability region, the reduced-order model must be of at least this order.")
120+
end
121+
sysr, hs = DescriptorSystems.gbalmr(stab; matchdc=residual, ord=n-nx_unstab, kwargs...)
122+
ss(sysr + unstab), hs
123+
end
124+
125+
"""
126+
stab, unstab = stab_unstab(sys; kwargs...)
127+
128+
Decompose `sys` into `sys = stab + unstab` where `stab` contains all stable poles and `unstab` contains unstable poles. See $(@doc(DescriptorSystems.gsdec)) for keyword arguments (argument `job` is set to `"stable"` in this function).
129+
"""
130+
function stab_unstab(sys; kwargs...)
131+
stab, unstab = DescriptorSystems.gsdec(dss(sys); job="stable", kwargs...)
132+
ss(stab), ss(unstab)
133+
end
134+
89135
##
90136

91137
function Base.:\(G1::AbstractStateSpace, G2::AbstractStateSpace)

test/test_descriptor.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,29 @@ G2 = ssrand(2,3,4, proper=true)
2121
end
2222
end >= 94
2323

24+
25+
##
26+
# sys = ssrand(2,3,4, stable=false)
27+
# # N,M = coprime_baltrunc(sys, n=3)
28+
# sysr, _ = coprime_baltrunc(sys, n=3)
29+
30+
# @test sysr.nx == 3
31+
32+
# bodeplot([sys, sysr])
33+
34+
## stab_unstab
35+
sys = ssrand(2,3,40, stable=false)
36+
stab, unstab = stab_unstab(sys)
37+
@test all(real(poles(stab)) .< 0)
38+
@test all(real(poles(unstab)) .>= 0)
39+
@test linfnorm(stab + unstab - sys)[1] < 1e-8
40+
41+
## baltrunc_unstab
42+
sys = ssrand(2,3,40, stable=true)
43+
sysus = ssrand(2,3,2, stable=true)
44+
sysus.A .*= -1
45+
sys = sys + sysus
46+
sysr, hs = baltrunc_unstab(sys, n=20)
47+
@test sysr.nx == 20
48+
@test linfnorm(sysr - sys)[1] < 1e-3
49+
# bodeplot([sys, sysr])

0 commit comments

Comments
 (0)