Skip to content

Commit

Permalink
Merge pull request #896 from JuliaControl/dspfilt
Browse files Browse the repository at this point in the history
add method to `DSP.filt` and `filtfilt`
  • Loading branch information
baggepinnen committed Oct 21, 2023
2 parents 963bcab + 002a315 commit b8a787e
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
28 changes: 27 additions & 1 deletion lib/ControlSystemsBase/src/dsp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,30 @@ end
function zpk(p::DSP.ZeroPoleGain, h::Real)
z,p,k = p.z, p.p, p.k
zpk(z, p, k, h)
end
end

"""
DSP.filt(P::ControlSystemsBase.TransferFunction, u)
Use a transfer function `P` to filter a signal `u`. This is equivalent to `lsim(P, u').y[:]`, but may be more efficient for single-input, single-output systems when the state sequence is not needed.
"""
function DSP.filt(P::ControlSystemsBase.TransferFunction, u, args...)
issiso(P) || error("Only single-input, single-output systems are supported in filt, call lsim instead.")
b, a = numvec(P)[], denvec(P)[]
nb, na = length(b), length(a)
if nb <= na
b = [zeros(na - nb); b]
end
DSP.filt(b, a, u, args...)
end


function DSP.filtfilt(P::ControlSystemsBase.TransferFunction, u, args...)
issiso(P) || error("Only single-input, single-output systems are supported in filtfilt.")
b, a = numvec(P)[], denvec(P)[]
nb, na = length(b), length(a)
if nb <= na
b = [zeros(na - nb); b]
end
DSP.filtfilt(b, a, u, args...)
end
13 changes: 13 additions & 0 deletions lib/ControlSystemsBase/test/test_dsp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,18 @@
uf = DSP.filt(f, u)
uls = lsim(fcs, u').y'
@test uf uls






u = randn(100)
res = lsim(Gd, u')
yf = res.y
@test yf' DSP.filt(Gd, u)

# The filtfilt function has a complicated initialization of the filter state, making it hard to compare to twice lsim
@test length(DSP.filtfilt(Gd, u)) == length(u)

end

0 comments on commit b8a787e

Please sign in to comment.