Serious Problem with FiltFilt Function

84 views (last 30 days)
Berk Kucukoglu
Berk Kucukoglu on 2 May 2021
Commented: Berk Kucukoglu on 5 May 2021
Hello everyone,
I designed a Bandpass Filter using the filterDesigner app. It is an 18th order IIR filter.
Then I export the filter both as df2sos object and "SOS and G" matrices.
Afterwards, I try filtering my data with:
y = filtfilt(Hd,x);
It gives the error: Not enough input arguments.
Well. Why don't I use:
y = filtfilt(Hd.sosMatrix,Hd.scaleValues,x);
% or
y = filtfilt(SOS,G,x);
These do not work for my filter; they result in unstable filters. Even though my originally designed filter is stable, they give unstable results. Here is the MATLAB page for this issue.
So, how to use FiltFilt function with my df2sos object or my "SOS and G" matrices, without getting an unstable result? I'd really appreaciate some help.
Regards,
Berk
Additional Details:
Here is the code to generate my filter object:
Fstop1 = 0.0001; % First Stopband Frequency
Fpass1 = 0.0004; % First Passband Frequency
Fpass2 = 0.08; % Second Passband Frequency
Fstop2 = 0.12; % Second Stopband Frequency
Astop1 = 50; % First Stopband Attenuation (dB)
Apass = 0.5; % Passband Ripple (dB)
Astop2 = 50; % Second Stopband Attenuation (dB)
h = fdesign.bandpass('fst1,fp1,fp2,fst2,ast1,ap,ast2', Fstop1, Fpass1, ...
Fpass2, Fstop2, Astop1, Apass, Astop2);
Hd = designfilt(h, 'cheby2', ...
'MatchExactly', 'stopband', ...
'SystemObject', true);
and the screenshot from the filterDesigner app:

Answers (1)

Star Strider
Star Strider on 2 May 2021
I have no idea what function was used to design the filter, since ‘FilterDesignerToolbox’ is nowhere to be found in the MATLAB or Signal Processing Toolbox documentation.
Use designfilt to create the filter. See the filtfilt documentation section on d for help with that.
  9 Comments
Paul
Paul on 5 May 2021
I'm becoming a bit more skeptical about the implementation of filtfilt(). Consider the following, where the filter is a harmless, 2nd order filter.
Fs = 2000;
Ts = 1./Fs;
n = 0:1:1*Fs;
f_max = Fs/10;
f = linspace(0,f_max,length(n));
x = cos(2*pi.*f.*n.*Ts); % Basic chirp
d = designfilt('lowpassiir', ... % Response type
'PassbandFrequency',50, ... % Frequency constraints
'StopbandFrequency',100, ...
'PassbandRipple',4, ... % Magnitude constraints
'StopbandAttenuation',15, ... % 15 for second order filter
'DesignMethod','ellip', ... % Design method
'MatchExactly','passband', ... % Design method options
'SampleRate',Fs); % Sample rate
[b,a] = tf(d);
[b;a]
ans = 2×3
0.0577 -0.1050 0.0577 1.0000 -1.9067 0.9231
y1 = filtfilt(d,x);
y2 = filtfilt(b,a,x);
plot([y1 ; y2].')
As we see, in this case filtfilt() returns the same result operating on either the digitalFilter object or the numerator and denominator coefficients directly.
Now change a filter design parameter to increase the order to a fourth-order filter
d = designfilt('lowpassiir', ... % Response type
'PassbandFrequency',50, ... % Frequency constraints
'StopbandFrequency',100, ...
'PassbandRipple',4, ... % Magnitude constraints
'StopbandAttenuation',55, ... % 15, 55 for second/fourth order filter
'DesignMethod','ellip', ... % Design method
'MatchExactly','passband', ... % Design method options
'SampleRate',Fs); % Sample rate
[b,a] = tf(d);
[b;a]
ans = 2×5
0.0012 -0.0039 0.0055 -0.0039 0.0012 1.0000 -3.8985 5.7250 -3.7529 0.9265
y1 = filtfilt(d,x);
y2 = filtfilt(b,a,x);
plot([y1 ; y2].')
Now there is a clear difference in the transient at the end, and zooming in at the beginning reveals a difference as well.
plot([y1 ; y2].')
set(gca,'XLim',[0 10])
Same filter, different results, and the results seem to be too different to ascribe to round-off effects for what appears to be very simple filter.
Berk Kucukoglu
Berk Kucukoglu on 5 May 2021
Hello @Paul,
I am very happy to see that this topic got your attention. I am also curious and trying to understand what is happening with filtfilt() function.
I have read your post and I think you are correct. The filter begins to act in a weird way as the filter order goes high.
Also, I would like to share what I have noticed. It might be a small detail but I find it interesting.
Say I have two different chirp signals:
x1 = cos(2*pi.*f.*n.*Ts); % Basic chirp 1
x2 = sin(2*pi.*f.*n.*Ts); % Basic chirp 2
Normally I would not even call these chirps "different". They are identical except a tiny phase shift. Now I filter these signals using the filtfilt() function.
y_filtfilt_1 = filtfilt(bpFilt,x1); % zero-phase filtering, Chirp 1
y_filtfilt_2 = filtfilt(bpFilt,x2); % zero-phase filtering, Chirp 2
And here comes the results...
Look at the difference in scales. I overlapped both of them and zoomed onto the initial transient:
I cannot understand what's wrong. I will keep searching. Probably won't use filtfilt() for a while now. Doing the search mainly for curiosity as well :)

Sign in to comment.

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!