Skip to content

Commit 20a0654

Browse files
authored
Merge pull request #639 from JuliaControl/typestab
type stability fixes and tests
2 parents 054054e + fcfbe5a commit 20a0654

File tree

5 files changed

+34
-11
lines changed

5 files changed

+34
-11
lines changed

src/types/SisoTfTypes/SisoRational.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
## User should just use TransferFunction
22
struct SisoRational{T} <: SisoTf{T}
3-
num::Polynomial{T}
4-
den::Polynomial{T}
5-
function SisoRational{T}(num::Polynomial{T}, den::Polynomial{T}) where T <: Number
3+
num::Polynomial{T, :x}
4+
den::Polynomial{T, :x}
5+
function SisoRational{T}(num::Polynomial{T, S}, den::Polynomial{T, S}) where {T <: Number, S}
66
if isequal(den, zero(den))
77
error("Cannot create SisoRational with zero denominator")
88
elseif isequal(num, zero(num))
@@ -14,12 +14,12 @@ struct SisoRational{T} <: SisoTf{T}
1414
end
1515
function SisoRational(num::Polynomial{T1}, den::Polynomial{T2}) where T1 <: Number where T2 <: Number
1616
T = promote_type(T1,T2)
17-
SisoRational{T}(Polynomial{T}(num.coeffs), Polynomial{T}(den.coeffs))
17+
SisoRational{T}(Polynomial{T, :x}(num.coeffs), Polynomial{T, :x}(den.coeffs))
1818
end
19-
SisoRational{T}(num::Polynomial, den::Polynomial) where T = SisoRational{T}(convert(Polynomial{T}, num), convert(Polynomial{T}, den))
19+
SisoRational{T}(num::Polynomial, den::Polynomial) where T = SisoRational{T}(convert(Polynomial{T, :x}, num), convert(Polynomial{T, :x}, den))
2020

2121
function SisoRational{T}(num::AbstractVector, den::AbstractVector) where T <: Number # NOTE: Typearguemnts on the parameters?
22-
SisoRational{T}(Polynomial{T}(reverse(num)), Polynomial{T}(reverse(den)))
22+
SisoRational{T}(Polynomial{T, :x}(reverse(num)), Polynomial{T, :x}(reverse(den)))
2323
end
2424
function SisoRational(num::AbstractVector{T1}, den::AbstractVector{T2}) where T1 <: Number where T2 <: Number
2525
T = promote_type(T1,T2)
@@ -126,7 +126,7 @@ end
126126
#.-(f::SisoRational, n::Number) = -(t, n)
127127
#.-(n::Number, f::SisoRational) = -(n, t)
128128

129-
-(f::SisoRational) = SisoRational(-f.num, f.den)
129+
-(f::SisoRational) = SisoRational((-f.num)::typeof(f.num), f.den) # typeassert due to https://github.com/JuliaMath/Polynomials.jl/issues/395 and can be removed once that is closed
130130

131131
# We overload this method to circumvent the Base methods use of promote_op(matprod,...)
132132
function (*)(A::AbstractMatrix{<:SisoRational}, B::AbstractMatrix{<:SisoRational})

src/types/StateSpace.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,9 @@ function *(sys1::ST, sys2::ST) where {ST <: AbstractStateSpace}
261261
#Note: sys1*sys2 = y <- sys1 <- sys2 <- u
262262
if xor(issiso(sys1), issiso(sys2))
263263
if issiso(sys1)
264-
sys1 = append(fill(sys1, sys2.ny)...)
264+
sys1 = append(fill(sys1, sys2.ny)...)::ST
265265
else
266-
sys2 = append(fill(sys2, sys1.nu)...)
266+
sys2 = append(fill(sys2, sys1.nu)...)::ST
267267
end
268268
elseif sys1.nu != sys2.ny
269269
error("sys1*sys2: sys1 must have same number of inputs as sys2 has outputs")

src/types/TransferFunction.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,12 @@ end
180180
## DIVISION ##
181181
function /(n::Number, G::TransferFunction)
182182
if issiso(G)
183-
matrix = reshape([n/G.matrix[1,1]], 1, 1)
183+
entry = n/G.matrix[1,1]
184+
matrix = fill(entry, 1, 1)
185+
return TransferFunction(matrix, G.timeevol)
184186
else
185187
error("MIMO TransferFunction inversion isn't implemented yet")
186188
end
187-
return TransferFunction(matrix, G.timeevol)
188189
end
189190
/(G::TransferFunction, n::Number) = G*(1/n)
190191
/(G1::TransferFunction, G2::TransferFunction) = G1*(1/G2)

test/test_statespace.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,14 @@
5555
@test C_222 + 1 == SS([-5 -3; 2 -9],[1 0; 0 2],[1 0; 0 1],[1 1; 1 1])
5656
@test D_111 + D_111 == SS([-0.5 0; 0 -0.5],[2; 2],[3 3],[0], 0.005)
5757

58+
@inferred C_111 + C_111
59+
5860
@test C_111 + false == C_111
5961
@test false + C_111 == C_111
6062
@test 1.0*C_111 + false == C_111
6163

64+
@inferred C_111 + false
65+
6266
@test C_222 + 1.5 == 1.0C_222 + 1.5 # C_222 has eltype Int
6367
@test 1.5 + C_222 == 1.0C_222 + 1.5
6468

@@ -80,6 +84,9 @@
8084
@test minreal(C_111*C_222_d - C_222_d*C_111, atol=1e-3) == ss(0*I(2)) # scalar times MIMO
8185
@test C_111*C_222 == ss([-5 0 2 0; 0 -5 0 2; 0 0 -5 -3; 0 0 2 -9], [0 0; 0 0; 1 0; 0 2], [3 0 0 0; 0 3 0 0], 0)
8286

87+
@inferred C_111 * C_221
88+
@inferred C_111 * I(2)
89+
8390
# Division
8491
@test 1/C_222_d == SS([-6 -3; 2 -11],[1 0; 0 2],[-1 0; -0 -1],[1 -0; 0 1])
8592
@test C_221/C_222_d == SS([-5 -3 -1 0; 2 -9 -0 -2; 0 0 -6 -3;
@@ -90,6 +97,9 @@
9097
fsys = ss(1,1,1,0)/3 # Int becomes FLoat after division
9198
@test fsys.B[]*fsys.C[] == 1/3
9299

100+
@inferred 1/C_222_d
101+
@inferred C_221/C_222_d
102+
93103
# Indexing
94104
@test size(C_222) == (2, 2)
95105
@test size(C_212) == (2, 1)

test/test_transferfunction.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
# {type}_{dims}
55
# type: C: Continuous, D: Discrete
66
# dims: "npnuny" (np = # poles)
7+
s = tf("s")
8+
@inferred 1.0/s
9+
@inferred 1/s
710

811
# CONTINUOUS
912
C_111 = tf([1, 2], [1, 5])
@@ -32,6 +35,9 @@ z = tf("z", 0.005)
3235
@test C_022 == tf([4 0;0 4])
3336
@test D_022 == tf([4 0;0 4], 0.005)
3437

38+
@inferred tf([4 0;0 4])
39+
@inferred tf([4 0;0 4], 0.005)
40+
3541
# Test equality
3642
@test tf([1,2], [2,3,4]) == tf(2*[1,2], 2*[2,3,4])
3743
@test tf([1.0], [2.0,3.0]) == tf*[1.0], π*[2.0,3.0])
@@ -62,12 +68,14 @@ z = tf("z", 0.005)
6268
@test C_222 + 1 == tf(vecarray(2, 2, [2,10,18], [1,9,17], [2,10,18], [1,9,17]),
6369
vecarray(2, 2, [1,8,15], [1,8,15], [1,8,15], [1,8,15]))
6470
@test D_111 + D_111 == tf([2,3,-2], [1,-1,0.25], 0.005)
71+
@inferred C_111 + C_111
6572

6673
# Subtraction
6774
@test C_111 - C_211 == tf([0,3,18,15], [1,13,55,75])
6875
@test 1 - C_222 == tf(vecarray(2, 2, [0,6,12], [1,7,13], [0,6,12], [1,7,13]), vecarray(2, 2, [1,8,15], [1,8,15], [1,8,15], [1,8,15]))
6976
# We are not doing enough to identify zero numerator here
7077
@test_broken D_111 - D_211 - tf([0,0.3,-2.55,1.2], [1,-0.7,-0.05,0.075], 0.005) == tf([0.0], [1], 0.005)
78+
@inferred C_111 - C_211
7179

7280
# Multiplication
7381
@test C_111 * C_221 == tf(vecarray(1, 2, [1,4,7,6], [0,1,4,4]),
@@ -80,6 +88,7 @@ z = tf("z", 0.005)
8088
@test_broken D_111 * D_221 - tf(vecarray(1, 2, [1,4,7,6], [0,1,4,4]),
8189
vecarray(1, 2, [1,-0.7,-0.05,0.075], [1.0,-0.7,-0.05,0.075]), 0.005) ==
8290
tf(vecarray(1, 2, [0], [0]), vecarray(1, 2, [1], [1]), 0.005)
91+
@inferred C_111 * C_221
8392

8493
@test tf(1) .* C_222 == C_222
8594
@test tf(1) .* I(2) == tf(I(2))
@@ -89,6 +98,9 @@ tf(vecarray(1, 2, [0], [0]), vecarray(1, 2, [1], [1]), 0.005)
8998
@test C_212/C_111 == tf(vecarray(2, 1, [1,7,13,15], [0,1,7,10]),
9099
vecarray(2, 1, [1,10,31,30], [1,10,31,30]))
91100
@test 1/D_111 == tf([1.0,-0.5], [1.0,2.0], 0.005)
101+
@inferred 1/C_111
102+
@inferred C_212/C_111
103+
@inferred 1/D_111
92104

93105
# Indexing
94106
@test size(C_222) == (2, 2)

0 commit comments

Comments
 (0)