Serious Problem with FiltFilt Function
58 views (last 30 days)
Show older comments
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:

1 Comment
Answers (1)
Paul
on 12 Jan 2025
Edited: Paul
on 12 Jan 2025
The filter is not unstable. Rather, the issue is an interaction between how filtfilt works and the implementation of the biquadratic sections of the filter as designed.
Design the filter
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);
This call no longer works (assuming it did when this question was first posted)
try
Hd = designfilt(h, 'cheby2', ...
'MatchExactly', 'stopband', ...
'SystemObject', true);
catch ME
ME
end
But this does, so we'll go with this
Hd = design(h, 'cheby2', ...
'MatchExactly', 'stopband', ...
'SystemObject', true);
Define an input for testing
rng(100)
N = 2e5;
x = randn(1,N);
Hd is a dsp.SOSFilter object
whos Hd
which does not have filtfilt() method (I wonder why not?)
methods(Hd)
which is why this call doesn't work (I think it resolves to filtfilt, which doesn't work with these input arguments)
try
y = filtfilt(Hd,x);
catch ME
ME
end
The properties of Hd are
Hd
which is why this call won't work
%y = filtfilt(Hd.sosMatrix,Hd.scaleValues,x);
y = filtfilt([Hd.Numerator,Hd.Denominator],Hd.ScaleValues,x);
figure
plot(y)
The filtfilt operation is not unstable; it just has a massive transient at the start that takes a long time to damp out.
This issue is also discussed here, which includes a link to this Question and Answer from the @MathWorks Support Team that shows two suggested workarounds. Here is the approach using the second of the two suggestions. The other is based on using reorder.
The approach is to convert the second order sections to zero/pole/gain form and then convert back to sos. Without checking the details, the idea is that this process results in better "balancing" amongst all of the sections that eliminates the transient.
Do the conversion and then filtfilt
[z,p,k] = sos2zp([Hd.Numerator,Hd.Denominator],prod(Hd.ScaleValues));
[Hdsos,g] = zp2sos(z,p,k);
y1 = filtfilt(Hdsos,g,x);
The transient is eliminated
figure
plot(y1)
and the output has the expected response relative to the input, at least until the gain gets extremely low.
[h,w] = freqz(Hdsos,8192); h = h*g;
figure
[h1,w1] = tfestimate(x,y1);
plot(w1,db(abs(h1)),w,db(abs(h).^2)),grid
0 Comments
See Also
Categories
Find more on Digital Filtering in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!