Skip to content

Commit a75c48e

Browse files
committed
add Padé approximation with different numerator and denomenator degree
1 parent 10b3e51 commit a75c48e

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

lib/ControlSystemsBase/src/delay_systems.jl

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,32 @@ function pade(τ::Real, N::Int)
140140
return tf(_linscale(Q, -τ), _linscale(Q, τ)) # return Q(-τs)/Q(τs)
141141
end
142142

143+
# Pade approximation with different degree in numerator and denominator
144+
"""
145+
pade(τ::Real, N_num::Int, N_den::Int)
146+
147+
Compute the Padé approximation of a time-delay of length `τ` with `N_num` and `N_den` degrees in the numerator and denominator, respectively.
148+
"""
149+
function pade::Real, m::Int, n::Int)
150+
p = [(-1)^i * binomial(m, i) * factorial(m+n-i) / factorial(m+n)
151+
for i in 0:m] |> Polynomials.Polynomial
152+
153+
q = [binomial(n, i) * factorial(m+n-i) / factorial(m+n)
154+
for i in 0:n] |> Polynomials.Polynomial
155+
156+
return tf(_linscale(p, τ), _linscale(q, τ))
157+
end
158+
143159

144160
"""
145161
pade(G::DelayLtiSystem, N)
146162
147163
Approximate all time-delays in `G` by Padé approximations of degree `N`.
148164
"""
149-
function pade(G::DelayLtiSystem, N)
165+
function pade(G::DelayLtiSystem, N, args...)
150166
ny, nu = size(G)
151167
nTau = length(G.Tau)
152-
X = append(ss(pade(τ,N)) for τ in G.Tau) # Perhaps append should be renamed blockdiag
168+
X = append(ss(pade(τ,N,args...)) for τ in G.Tau) # Perhaps append should be renamed blockdiag
153169
return lft(G.P.P, X)
154170
end
155171

lib/ControlSystemsBase/test/test_delayed_systems.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,20 @@ P_wb = DemoSystems.woodberry()
229229

230230
@test freqresp(pade(feedback(eye_(2), P_wb), 3), Ω) freqresp(feedback(eye_(2), P_wb), Ω) atol=1e-4
231231

232+
## Test pade(tau, m, n)
233+
t = 1.5
234+
P15 = pade(t, 1, 5)
235+
dv = denvec(P15)[]
236+
dv1 = dv[1]/t^5 # Rescale to compare with https://www2.humusoft.cz/www/papers/tcp09/035_hanta.pdf
237+
@test numvec(P15)[] ./ dv1 [-120*t, 720]
238+
@test dv ./ dv1 [t^5, 10*t^4, 60*t^3, 240*t^2, 600*t, 720]
239+
240+
241+
P15 = pade(t, 2, 5)
242+
# Test vectors computed using RobustPade.robustpade(s->exp(-t*s), 2, 5)
243+
@test numvec(P15)[] [0.05357142857142857, -0.42857142857142855, 1.0]
244+
@test denvec(P15)[] [0.0030133928571428573, 0.03013392857142857, 0.1607142857142857, 0.5357142857142857, 1.0714285714285714, 1.0]
245+
232246
# test thiran
233247
for Ts = [1, 1.1]
234248
z = tf('z', Ts)

0 commit comments

Comments
 (0)