Skip to content

Commit 695e4b9

Browse files
committed
add find_similarity_transform
this was previously implemented in ControlSystemIdentification
1 parent dbe65e6 commit 695e4b9

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

lib/ControlSystemsBase/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name = "ControlSystemsBase"
22
uuid = "aaaaaaaa-a6ca-5380-bf3e-84a91bcd477e"
33
authors = ["Dept. Automatic Control, Lund University"]
44
repo = "https://github.com/JuliaControl/ControlSystems.jl.git"
5-
version = "1.16.1"
5+
version = "1.17.0"
66

77
[deps]
88
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"

lib/ControlSystemsBase/src/matrix_comps.jl

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ D̃ = D
710710
```
711711
712712
If `unitary=true`, `T` is assumed unitary and the matrix adjoint is used instead of the inverse.
713-
See also [`balance_statespace`](@ref).
713+
See also [`balance_statespace`](@ref), [`find_similarity_transform`](@ref).
714714
"""
715715
function similarity_transform(sys::ST, T; unitary=false) where ST <: AbstractStateSpace
716716
if unitary
@@ -726,6 +726,42 @@ function similarity_transform(sys::ST, T; unitary=false) where ST <: AbstractSta
726726
ST(A,B,C,D,sys.timeevol)
727727
end
728728

729+
"""
730+
find_similarity_transform(sys1, sys2, method = :obsv)
731+
732+
Find T such that `ControlSystemsBase.similarity_transform(sys1, T) == sys2`
733+
734+
Ref: Minimal state-space realization in linear system theory: an overview, B. De Schutter
735+
736+
If `method == :obsv`, the observability matrices of `sys1` and `sys2` are used to find `T`, whereas `method == :ctrb` uses the controllability matrices.
737+
738+
```jldoctest
739+
julia> T = randn(3,3);
740+
741+
julia> sys1 = ssrand(1,1,3);
742+
743+
julia> sys2 = ControlSystemsBase.similarity_transform(sys1, T);
744+
745+
julia> T2 = find_similarity_transform(sys1, sys2);
746+
747+
julia> T2 ≈ T
748+
true
749+
```
750+
"""
751+
function find_similarity_transform(sys1, sys2, method = :obsv)
752+
if method === :obsv
753+
O1 = obsv(sys1)
754+
O2 = obsv(sys2)
755+
return O1\O2
756+
elseif method === :ctrb
757+
C1 = ctrb(sys1)
758+
C2 = ctrb(sys2)
759+
return C1/C2
760+
else
761+
error("Unknown method $method")
762+
end
763+
end
764+
729765
"""
730766
time_scale(sys::AbstractStateSpace{Continuous}, a; balanced = false)
731767
time_scale(G::TransferFunction{Continuous}, a; balanced = true)

lib/ControlSystemsBase/test/test_matrix_comps.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ sysdb, _ = balance_statespace(sysd)
3939

4040
@test ControlSystemsBase.balance_transform(A,B,C) ControlSystemsBase.balance_transform(sys)
4141

42+
@testset "similarity transform" begin
43+
@info "Testing similarity transform"
44+
T = randn(3,3)
45+
sys1 = ssrand(1,1,3)
46+
sys2 = ControlSystemsBase.similarity_transform(sys1, T)
47+
T2 = ControlSystemIdentification.find_similarity_transform(sys1, sys2)
48+
@test T2 T atol=1e-8
49+
50+
T3 = ControlSystemIdentification.find_similarity_transform(sys1, sys2, :ctrb)
51+
@test T3 T atol=1e-8
52+
53+
end
54+
4255
W = [1 0; 0 1]
4356
@test covar(sys, W) [0.002560975609756 0.002439024390244; 0.002439024390244 0.002560975609756]
4457
D2 = [1 0; 0 1]

0 commit comments

Comments
 (0)