Skip to content

Commit 472cb96

Browse files
committed
Print method and some more tests for delay systems.
1 parent 972f004 commit 472cb96

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

src/types/DelayLtiSystem.jl

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function DelayLtiSystem{T,S}(sys::StateSpace, Tau::AbstractVector{S} = Float64[]
2828
ny = noutputs(sys) - length(Tau)
2929

3030
if nu < 0 || ny < 0
31-
throw(ArgumentError("Time vector is too long."))
31+
throw(ArgumentError("The delay vector of length $length(Tau) is too long."))
3232
end
3333

3434
psys = PartionedStateSpace{StateSpace{T,Matrix{T}}}(sys, nu, ny)
@@ -144,6 +144,14 @@ function Base.getindex(sys::DelayLtiSystem, i::AbstractArray, j::AbstractArray)
144144
sys.P.Ts), sys.Tau)
145145
end
146146

147+
function Base.show(io::IO, sys::DelayLtiSystem)
148+
show(io, sys.P.P)
149+
150+
println(io, "\n\nDelays: $(sys.Tau)")
151+
end
152+
153+
154+
147155
function +(sys1::DelayLtiSystem, sys2::DelayLtiSystem)
148156
psys_new = sys1.P + sys2.P
149157
Tau_new = [sys1.Tau; sys2.Tau]
@@ -190,15 +198,16 @@ Create a time delay of length `tau` with `exp(-τ*s)` where `s=tf("s")` and `τ`
190198
191199
See also: [`delay`](@ref) which is arguably more conenient than this function.
192200
"""
193-
function Base.exp(G::TransferFunction{SisoRational})
194-
if size(G.matrix) != (1,1)
195-
error("G must be a scalar transfer function. Consider using `delay` instead.")
201+
function Base.exp(G::TransferFunction{<:SisoRational})
202+
if size(G.matrix) != (1,1) && iscontinuous(G)
203+
error("G must be a continuous-time scalar transfer function. Consider using `delay` instead.")
196204
end
197205
G_siso = G.matrix[1,1]
198206

199-
if degree(G_siso.den) != 0 || degree(G_siso.num) != 1 || G_siso[1].num[1] < 0
207+
if !(Polynomials.degree(G_siso.den) == 0 && Polynomials.degree(G_siso.num) == 1
208+
&& G_siso.num[1]/G_siso.den[0] < 0 && G_siso.num[0] == 0)
200209
error("Input must be of the form -τ*s, τ>0. Consider using `delay` instead.")
201210
end
202211

203-
return delay(-G_siso.den[1] / G_siso.den[0])
212+
return delay(-G_siso.num[1] / G_siso.den[0])
204213
end

test/test_delayed_systems.jl

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@ using DelayDiffEq
55

66
# broken: typeof(promote(delay(0.2), ss(1))[1]) == DelayLtiSystem{Float64}
77

8+
89
@test typeof(promote(delay(0.2), ss(1.0 + im))[1]) == DelayLtiSystem{Complex{Float64}, Float64}
910

11+
@test sprint(show, ss(1,1,1,1)*delay(1.0)) == "StateSpace{Float64,Array{Float64,2}}\nA = \n 1.0\nB = \n 0.0 1.0\nC = \n 1.0\n 0.0\nD = \n 0.0 1.0\n 1.0 0.0\n\nContinuous-time state-space model\n\nDelays: [1.0]\n"
12+
13+
1014
# Extremely baseic tests
1115
@test freqresp(delay(1), ω) reshape(exp.(-im*ω), length(ω), 1, 1) rtol=1e-15
1216
@test freqresp(delay(2.5), ω)[:] exp.(-2.5im*ω) rtol=1e-15
@@ -43,6 +47,9 @@ P2_fr = (im*ω .+ 1) ./ (im*ω .+ 2)
4347
@test freqresp(delay(1) * P2, ω)[:] P2_fr .* exp.(-im*ω) rtol=1e-15
4448

4549

50+
51+
52+
4653
## Feedback
4754
# The first tests don't include delays, but the linear system is of DelayLtiForm type
4855
# (very simple system so easy to troubleshoot)
@@ -76,6 +83,16 @@ G_fr = 0.5 .+ 0.5*exp.(-2*im*ω)# + 0.5*exp.(-3*im*ω)
7683
@test freqresp(feedback(P2, G), ω)[:] P2_fr ./(1 .+ P2_fr .* G_fr) rtol=1e-15
7784

7885
s = tf("s")
86+
87+
# Test alternative exp constructor for delays
88+
d = exp(-2*s)
89+
@test freqresp(d, [0, 1, 2]) [1, exp(-2im), exp(-4im)]
90+
91+
@test_throws ErrorException exp(-s^2 - 2*s)
92+
@test_throws ErrorException exp(-2*s+1) # in principle ok, but not allowed anyway
93+
@test_throws ErrorException exp([-2*s; -s])
94+
@test_throws ErrorException exp(2*s) # Non-causal
95+
7996
# Random conversions
8097
sys1 = DelayLtiSystem(1.0/s)
8198
@test sys1.P.A == sys1.P.D == fill(0,1,1)
@@ -183,6 +200,4 @@ y_impulse, t, _ = impulse(sys_known, 3, alg=MethodOfSteps(Tsit5()))
183200
@test y_impulse dy_expected.(t, K) rtol=1e-2 # Two orders of magnitude better with BS3 in this case, which is default for impulse
184201
@test maximum(abs, y_impulse - dy_expected.(t, K)) < 1e-2
185202

186-
[s11; s12]
187-
188203
end

0 commit comments

Comments
 (0)