DSP package filt vs. filtfilt

I am wondering how I need to modify the a and b vectors to make filtfilt give the same amplitude as filt.

A minimum working example is:

using DSP
using Plots

ω1 = 2 * π * 15
ω2 = 2 * π * 21
t = 0:1/400:1
fs = 1/(t[2]-t[1])
s = - 3 .* sin.(ω1 .* t) .- 1.7 .* sin.(ω2 .* t .+ 1.1)
a = [1.0, -1.9960123177216844, 0.9960186216909017]
b = [0.0012557101596703034, 3.1519846085887753e-6, -0.0012525581750617144]

plot(t, [filt(b, a, s), filtfilt(b, a, s)], labels=["filt" "filtfilt"])

Which give the figure

filt

I believe it is tricky as it is filtered twice with the same filer. For band pass filters (including low pass and high pass) it usually works as it is, since there is no gain or attention in the pass band an filtering twice. Here filtfilt just zeros out the phase differences.

Thanks, the filter I used is a transition filter that effectively integrates the signal.

Thanks Jake, I suspect it would be difficult to obtain the same amplitude using some type of scaling as integration is basically a low-pass (i.e 1/s) characteristic and highly frequency dependent. Usually, filtfilt is used to reduce the impact of non-linear phase distortion in a non-causal situation.

The frequency response of the low-pass filter knocks out most energy from the input signal:

This can be seen by lowering the input signal frequencies by a factor of 100 (and increasing the recording time accordingly). Then this will pass through in better shape:

Nice plots! I agree: for high-, low-, or band-pass filters where the frequency response amplitude is close to one in some frequency region of interest, filtfilt is perfect for non-causal filtering. I.e. when we want to keep just some band of frequency components and remove the others from the signal.

1 Like