Skip to content

Commit ab6544e

Browse files
author
Arda Aytekin
committed
WIP: Add tests for TransferFunction
Started adding tests for `TransferFunction`. Will continue later to finish tests. Related to #1.
1 parent 9908f58 commit ab6544e

File tree

6 files changed

+64
-182
lines changed

6 files changed

+64
-182
lines changed

src/SystemsBase.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import Base: convert, promote_rule
3030
# Import identities for overloading
3131
import Base: one, zero
3232

33-
# Import num and den for overloading
33+
# Import num, den for getting numerator and denominator polynomials
3434
import Base: num, den
3535

3636
# Import inv and zeros

src/types/system/ltisystem.jl

+1-173
Original file line numberDiff line numberDiff line change
@@ -19,176 +19,4 @@ end
1919
iscontinuous{T}(::LtiSystem{Val{T},Val{:cont}}) = true
2020
iscontinuous{T}(::LtiSystem{Val{T},Val{:disc}}) = false
2121
isdiscrete(s::LtiSystem) = !iscontinuous(s)
22-
23-
function samplingtime(s::LtiSystem)
24-
warn("samplingtime(s) not implemented for s::$(typeof(s))")
25-
throw(MethodError(samplingtime, Tuple{typeof(s)}))
26-
end
27-
28-
# State, input, output information
29-
function numstates(s::LtiSystem)
30-
warn("numstates(s) not implemented for s::$(typeof(s))")
31-
throw(MethodError(numstates, Tuple{typeof(s)}))
32-
end
33-
34-
function numinputs(s::LtiSystem)
35-
warn("numinputs(s) not implemented for s::$(typeof(s))")
36-
throw(MethodError(numinputs, Tuple{typeof(s)}))
37-
end
38-
39-
function numoutputs(s::LtiSystem)
40-
warn("numoutputs(s) not implemented for s::$(typeof(s))")
41-
throw(MethodError(numoutputs, Tuple{typeof(s)}))
42-
end
43-
44-
# # Iteration interface (meaningful in MIMO)
45-
# function start(s::LtiSystem{Val{:mimo}})
46-
# warn("start(s) not implemented for s::$(typeof(s))")
47-
# throw(MethodError(start, Tuple{typeof(s)}))
48-
# end
49-
#
50-
# function next(s::LtiSystem{Val{:mimo}}, state)
51-
# warn("next(s, state) not implemented for (s::$(typeof(s)), state::$(typeof(state)))")
52-
# throw(MethodError(next, Tuple{typeof(s),typeof(state)}))
53-
# end
54-
#
55-
# function done(s::LtiSystem{Val{:mimo}}, state)
56-
# warn("done(s, state) not implemented for (s::$(typeof(s)), state::$(typeof(state)))")
57-
# throw(MethodError(done, Tuple{typeof(s),typeof(state)}))
58-
# end
59-
#
60-
# function eltype(s::Type{LtiSystem{Val{:mimo}}})
61-
# warn("eltype(s) not implemented for s::$(typeof(s))")
62-
# throw(MethodError(eltype, Tuple{typeof(s)}))
63-
# end
64-
#
65-
# function length(s::LtiSystem{Val{:mimo}})
66-
# warn("length(s) not implemented for s::$(typeof(s))")
67-
# throw(MethodError(length, Tuple{typeof(s)}))
68-
# end
69-
#
70-
# function size(s::LtiSystem{Val{:mimo}}, d)
71-
# warn("size(s, d) not implemented for (s::$(typeof(s)), d::$(typeof(d)))")
72-
# throw(MethodError(size, Tuple{typeof(s),typeof(d)}))
73-
# end
74-
#
75-
# # Indexing
76-
# function getindex(s::LtiSystem{Val{:mimo}}, i)
77-
# warn("getindex(s, i) not implemented for (s::$(typeof(s)), i::$(typeof(i)))")
78-
# throw(MethodError(getindex, Tuple{typeof(s),typeof(i)}))
79-
# end
80-
#
81-
# function setindex!(s::LtiSystem{Val{:mimo}}, v, i)
82-
# warn("setindex!(s, v, i) not implemented for (s::$(typeof(s)), v::$(typeof(v)), i::$(typeof(i)))")
83-
# throw(MethodError(setindex!, Tuple{typeof(s),typeof(v),typeof(i)}))
84-
# end
85-
#
86-
# function endof(s::LtiSystem{Val{:mimo}})
87-
# warn("endof(s) not implemented for s::$(typeof(s))")
88-
# throw(MethodError(endof, Tuple{typeof(s)}))
89-
# end
90-
#
91-
# # Simple analysis things
92-
# function poles(s::LtiSystem)
93-
# warn("poles(s) not implemented for s::$(typeof(s))")
94-
# throw(MethodError(poles, Tuple{typeof(s)}))
95-
# end
96-
#
97-
# function zeros(s::LtiSystem)
98-
# warn("zeros(s) not implemented for s::$(typeof(s))")
99-
# throw(MethodError(zeros, Tuple{typeof(s)}))
100-
# end
101-
#
102-
# function isproper(s::LtiSystem)
103-
# warn("isproper(s) not implemented for s::$(typeof(s1))")
104-
# throw(MethodError(evalfr, Tuple{typeof(s),typeof(ω)}))
105-
# end
106-
#
107-
# # is strictly proper, better function name?
108-
# function isstrictlyproper(s::LtiSystem)
109-
# warn("issproper(s) not implemented for s::$(typeof(s1))")
110-
# throw(MethodError(evalfr, Tuple{typeof(s),typeof(ω)}))
111-
# end
112-
#
113-
# function tzeros(s::LtiSystem)
114-
# warn("tzeros(s) not implemented for s::$(typeof(s))")
115-
# throw(MethodError(tzeros, Tuple{typeof(s)}))
116-
# end
117-
#
118-
# function zpkdata(s::LtiSystem)
119-
# warn("zpkdata(s) not implemented for s::$(typeof(s))")
120-
# throw(MethodError(zpkdata, Tuple{typeof(s)}))
121-
# end
122-
#
123-
# function num(s::LtiSystem)
124-
# warn("num(s) not implemented for s::$(typeof(s))")
125-
# throw(MethodError(num, Tuple{typeof(s)}))
126-
# end
127-
#
128-
# function den(s::LtiSystem)
129-
# warn("denpoly(s) not implemented for s::$(typeof(s))")
130-
# throw(MethodError(denpoly, Tuple{typeof(s)}))
131-
# end
132-
#
133-
# # Constructors among different types
134-
# function lfd(s::LtiSystem)
135-
# warn("mfd(s) not implemented for s::$(typeof(s))")
136-
# throw(MethodError(mfd, Tuple{typeof(s)}))
137-
# end
138-
#
139-
# function rfd(s::LtiSystem)
140-
# warn("mfd(s) not implemented for s::$(typeof(s))")
141-
# throw(MethodError(mfd, Tuple{typeof(s)}))
142-
# end
143-
#
144-
# function ss(s::LtiSystem)
145-
# warn("ss(s) not implemented for s::$(typeof(s))")
146-
# throw(MethodError(ss, Tuple{typeof(s)}))
147-
# end
148-
#
149-
# function tf(s::LtiSystem)
150-
# warn("tf(s) not implemented for s::$(typeof(s))")
151-
# throw(MethodError(tf, Tuple{typeof(s)}))
152-
# end
153-
154-
# Methods
155-
# function series{T1,T2,S}(s1::LtiSystem{Val{T1},Val{S}}, s2::LtiSystem{Val{T2},Val{S}})
156-
# warn("series(s1, s2) not implemented for (s1::$(typeof(s1)), s2::$(typeof(s2)))")
157-
# throw(MethodError(series, Tuple{typeof(s1),typeof(s2)}))
158-
# end
159-
#
160-
# function series(s1::LtiSystem, s2::LtiSystem)
161-
# warn("series(s1, s2) cannot be defined for (s1::$(typeof(s1)), s2::$(typeof(s2)))")
162-
# throw(MethodError(series, Tuple{typeof(s1),typeof(s2)}))
163-
# end
164-
#
165-
# function parallel{T1,T2,S}(s1::LtiSystem{Val{T1},Val{S}}, s2::LtiSystem{Val{T2},Val{S}})
166-
# warn("parallel(s1, s2) not implemented for (s1::$(typeof(s1)), s2::$(typeof(s2)))")
167-
# throw(MethodError(parallel, Tuple{typeof(s1),typeof(s2)}))
168-
# end
169-
#
170-
# function parallel(s1::LtiSystem, s2::LtiSystem)
171-
# warn("parallel(s1, s2) cannot be defined for (s1::$(typeof(s1)), s2::$(typeof(s2)))")
172-
# throw(MethodError(parallel, Tuple{typeof(s1),typeof(s2)}))
173-
# end
174-
#
175-
# function feedback{T1,T2,S}(s1::LtiSystem{Val{T1},Val{S}}, s2::LtiSystem{Val{T2},Val{S}},
176-
# neg::Bool = true)
177-
# warn("feedback(s1, s2, neg) not implemented for (s1::$(typeof(s1)), s2::$(typeof(s2)), neg::$(typeof(neg)))")
178-
# throw(MethodError(feedback, Tuple{typeof(s1),typeof(s2),typeof(neg)}))
179-
# end
180-
#
181-
# function feedback(s1::LtiSystem, s2::LtiSystem, neg::Bool = true)
182-
# warn("feedback(s1, s2, neg) cannot be defined for (s1::$(typeof(s1)), s2::$(typeof(s2)), neg::$(typeof(neg)))")
183-
# throw(MethodError(feedback, Tuple{typeof(s1),typeof(s2),typeof(neg)}))
184-
# end
185-
186-
function minreal(s::LtiSystem)
187-
warn("minreal(s) not implemented for s::$(typeof(s))")
188-
throw(MethodError(minreal, Tuple{typeof(s)}))
189-
end
190-
191-
function freqresp(s::LtiSystem, ω)
192-
warn("freqresp(s, ω) not implemented for (s::$(typeof(s1)), ω::$(typeof(ω)))")
193-
throw(MethodError(freqresp, Tuple{typeof(s),typeof(ω)}))
194-
end
22+
samplingtime{T}(::LtiSystem{Val{T},Val{:disc}}) = zero(Float64)

src/types/system/transferfunction.jl

+6
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,12 @@ one(s::TransferFunction{Val{:siso},Val{:disc}}) = one(typeof(s))
333333
zero(s::TransferFunction{Val{:siso},Val{:cont}}) = zero(typeof(s))
334334
zero(s::TransferFunction{Val{:siso},Val{:disc}}) = zero(typeof(s))
335335

336+
# Simple analysis
337+
num(s::TransferFunction{Val{:siso}}) = num(s.mat[1])
338+
num(s::TransferFunction{Val{:mimo}}) = map(x->num(x), s.mat)
339+
den(s::TransferFunction{Val{:siso}}) = den(s.mat[1])
340+
den(s::TransferFunction{Val{:mimo}}) = map(x->den(x), s.mat)
341+
336342
# Inverse of a transfer-function model
337343
function _tfinv(s::TransferFunction)
338344
if s.ny s.nu

test/runtests.jl

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
using SystemsBase
2-
using RationalFunctions
31
using Polynomials
2+
using RationalFunctions
43
using PolynomialMatrices
4+
5+
using SystemsBase
6+
57
using Base.Test
68
using Base.Test.@testset
79

@@ -13,6 +15,6 @@ include("methods/simulation.jl")
1315

1416
# types
1517
include("types/system/ltisystem.jl")
16-
include("types/system/rationaltf.jl")
18+
include("types/system/transferfunction.jl")
1719
include("types/system/statespace.jl")
1820
include("types/system/mfd.jl")

test/types/system/rationaltf.jl

-5
This file was deleted.

test/types/system/transferfunction.jl

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
info("Starting tests for `TransferFunction`...")
2+
3+
# Rational transfer function constructions for SISO systems
4+
rc1 = RationalFunction([1], [2, 1], :s) # 1/(s+2)
5+
syscs1= tf(rc1)
6+
syscs2= tf([1], [1, 2])
7+
syscs3= tf(1, [1, 2])
8+
syscs4= tf(Poly(1, :s), [1, 2])
9+
syscs5= tf(1, Poly([2, 1], :s))
10+
rd1 = RationalFunction([1], [-0.5, 1], :z) # 1/(z-0.5)
11+
sysds1= tf(rd1, 0.5)
12+
sysds2= tf([1], [1, -0.5], 0.5)
13+
sysds3= tf(1, [1, -0.5], 0.5)
14+
sysds4= tf(Poly(1, :z), [1, -0.5], 0.5)
15+
sysds5= tf(1, Poly([-0.5, 1], :z), 0.5)
16+
sysds6= tf([0, 1], [1, -0.5], 0.5, :z̄)
17+
18+
@test num(syscs1) == num(syscs2) == num(syscs3) == num(syscs4) == num(syscs5)
19+
@test den(syscs1) == den(syscs2) == den(syscs3) == den(syscs4) == den(syscs5)
20+
@test num(sysds1) == num(sysds2) == num(sysds3) == num(sysds4) == num(sysds5) == num(sysds6)
21+
@test den(sysds1) == den(sysds2) == den(sysds3) == den(sysds4) == den(sysds5) == den(sysds6)
22+
23+
# Rational transfer function constructions for MIMO systems
24+
rc2 = RationalFunction([1,1], [3,1], :s)
25+
matc = diagm([rc1, rc2])
26+
syscm = tf(matc)
27+
rd2 = RationalFunction([-0.1,1], [-0.3,1], :z)
28+
matd = diagm([rd1, rd2])
29+
sysdm = tf(matd, 0.5)
30+
31+
@test num(syscm) == [num(rc1) zero(num(rc1)); zero(num(rc1)) num(rc2)]
32+
@test den(syscm) == [den(rc1) one(num(rc1)); one(num(rc1)) den(rc2)]
33+
@test num(sysdm) == [num(rd1) zero(num(rd1)); zero(num(rd1)) num(rd2)]
34+
@test den(sysdm) == [den(rd1) one(num(rd1)); one(num(rd1)) den(rd2)]
35+
36+
@test num(tf(diagm([1,2]))) == [Poly(1,:s) Poly(0,:s); Poly(0,:s) Poly(2,:s)]
37+
@test den(tf(diagm([1,2]))) == [Poly(1,:s) Poly(1,:s); Poly(1,:s) Poly(1,:s)]
38+
39+
@test num(tf(diagm([1,2]), 0.5)) == [Poly(1,:z) Poly(0,:z); Poly(0,:z) Poly(2,:z)]
40+
@test den(tf(diagm([1,2]), 0.5)) == [Poly(1,:z) Poly(1,:z); Poly(1,:z) Poly(1,:z)]
41+
42+
# Sampling time
43+
@test samplingtime(syscs1) == samplingtime(syscm) == zero(Float64)
44+
@test samplingtime(sysds1) == samplingtime(sysdm) == 0.5
45+
46+
# Input/Output information
47+
@test numinputs(syscs1) == numinputs(sysds1) == numoutputs(syscs1) == numoutputs(sysds1) == 1
48+
@test numinputs(syscm) == numinputs(sysdm) == 2
49+
@test numoutputs(syscm) == numoutputs(sysdm) == 2
50+
51+
info("Tests for `TransferFunction` finished.")

0 commit comments

Comments
 (0)