filtfilt vs filter gives strange results
7 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
I am attempting to use a bandstop filter on a signal with filtfilt(), but the results are unexpected. The code used to design the bandstop filter is
bfilt_spin = designfilt('bandstopiir', 'PassbandFrequency1', 1.90, 'StopbandFrequency1', 1.95, 'StopbandFrequency2', 2.05, 'PassbandFrequency2', 2.10, 'PassbandRipple1', 1, 'StopbandAttenuation', 60, 'PassbandRipple2', 1, 'SampleRate', (t_filt(2)-t_filt(1))^-1, 'DesignMethod', 'cheby2');
I have attached the signal I am trying to filter (wform is the signal, and time vector is t_filt) and the designed filter. When I plot the filtered signal or the FFT, something is clearly wrong in the filtfilt() case (see plots below). Am I using filtfilt() incorrectly, or is there something wrong with the data I am using? I have looked at the documentation for filter() and filtfilt() for clues, but I am stuck.
To troubleshoot, I tried using filter() for comparison. I would expect filtfilt to produce a similar result to filter, but with no phase-shift and better end effects, per the documentation. The digital filter performed as expected, here is the plot of the FFT:

When I use filtfilt() instead, it looks broken. It seems more than just a small side-effect, there's something wrong with this use-case that I don't know and I haven't found in the documentation. Note the magnitudes of the two plots.

Adjusting the parameters of the filter (frequencies, ripple, and attenuation - I always used cheby2) seems to affect how the strangeness looks, but not whether it is there. Plotting in the time domain reflects what is seen in the FFT.
Thanks for any suggestions.
0 comentarios
Respuestas (1)
Star Strider
el 19 de Mayo de 2015
I don’t usually use designfilt, preferring the ‘lower-level’ functions because I’m used to them. The filtfilt function is preferable for filtering because of its phase characteristics.
Much depends on how you designed and implemented your filter. I always use the ‘second-order-section’ (SOS) implementation rather than the transfer function, and check the filter for stability with the freqz function before I apply it to the signal. (I detailed my filter design procedure here.) Since I don’t have ‘t_filt’, I can’t run your code and use freqz to see how your filter functions.
Lacking those data, it’s not possible to determine what — if any — errors might be in your design.
2 comentarios
Star Strider
el 19 de Mayo de 2015
Editada: Star Strider
el 20 de Mayo de 2015
I found it to work well just as you designed it. The designfilt function automatically uses the SOS implementation (obvious from the code). The only suggestion I have is to set the passband ripple to 1dB and the stopband ripple to 10dB.
My code:
filt = load('Ryan filterdata.mat');
df = filt.bfilt_spin;
sg = filt.wform;
t = filt.t_filt;
%
Ts = mean(diff(t));
Fs = 1/Ts;
Fn = Fs/2;
fsg = fft(sg)/length(sg);
Fv = linspace(0, 1, fix(length(sg)/2)+1)*Fn; % Frequency Vector
Ix = 1:length(Fv); % Index Vector
%
figure(1)
plot(Fv, abs(fsg(Ix)))
grid
xlabel('Frequency')
ylabel('Amplitude')
axis([0 5 ylim])
%
fvtool(df)
axis([0 5 ylim])
%
ysg = filter(df, sg); % Filter Signal
fysg = fft(ysg)/length(ysg);
%
figure(3)
plot(Fv, abs(fysg(Ix)))
grid
xlabel('Frequency')
ylabel('Amplitude')
axis([0 5 ylim])
So you designed your filter correctly, and correctly implemented it. Other than the passband ripple (that I would reduce), I see no problems.
EDIT — The freqz plot is instructive. The filter appears to be unstable:
figure(4)
freqz(df, 1204)
axis([0 0.05 ylim])
EDIT 2 — I brought this to the attention of TMW with a Support Request, including the URL.
Ver también
Categorías
Más información sobre Digital Filtering en Help Center y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!