Filtfilt returns NaN matrix
3 次查看(过去 30 天)
显示 更早的评论
I am running the following operation (please download the attached file to your working directory):
load('Channel_Sim.mat');
[b,a] = butter(4, [3 20] ./ (1000/2)); % Sampling frequency is 1000 Hz.
chan_filtered = filtfilt(b, a, chan_data)
However, chan_filtered is a NaN matrix. Why?
I have checked that chan_data does not contain any NaN or Inf. I also tried resetting the butterworth filter range (3-20) over a wide range of values but to no avail. A PSD plot (see attached jpeg file) shows that chan_data encompasses a wide range of frequencies inluding the target frequency (3-20).
2 个评论
Walter Roberson
2023-5-10
If you have even 1 nan or inf in your data the filtered results will likely be nan
采纳的回答
Star Strider
2023-5-10
The transfer function implementation of the filter is unstable, however I cannot determine the reasson for the instability, although it may simply be the relative magnitudes of the numerator and denominator coefficients.
The easiest way to solve that problem is to use second-order-section implementation of the same filter —
load('Channel_Sim.mat')
% chan_data
Fs = 1000;
[b,a] = butter(4, [3 20] ./ (1000/2));
[z,p,k] = butter(4, [3 20] ./ (1000/2));
[sos,g] = zp2sos(z,p,k);
figure
freqz(b,a, 2^18, 1000)
set(subplot(2,1,1), 'XLim',[0 50])
set(subplot(2,1,2), 'XLim',[0 50])
Check = nnz(isnan(chan_data))
L = numel(chan_data);
t = linspace(0, L-1, L)/Fs;
figure
plot(t, chan_data)
grid
Fn = Fs/2;
NFFT = 2^nextpow2(L)
FTcd = fft((chan_data-mean(chan_data)).*hann(L), NFFT)/L;
Fv = linspace(0, 1, NFFT/2+1)*Fn;
Iv = 1:numel(Fv);
figure
plot(Fv, abs(FTcd(Iv))*2)
grid
chan_filtered = filtfilt(b, a, chan_data)
chan_filtered = filtfilt(sos, g, chan_data);
figure
plot(t, chan_filtered)
grid
chan_filtered = bandpass(chan_data, [3 20], Fs, 'ImpulseResponse','iir');
figure
plot(t, chan_filtered)
grid
The second-order-section implementation of the same Butterworth filter then works, and produces essentially the same result as an elliptic bandpass filter with the same essential parameters.
.
2 个评论
Star Strider
2023-5-11
The second-order-section implementation of a filter is always stable (at least in my experience).
The reason has to do with the way the filters are implemented and how filtfilt handles them. The relevant discussion is in the sos documentation section for filtfilt, and a more extensive discussion is in the sosfilt documentation. (I cannot determine from reading the documentation if sosfilt does the same forward-backward filtering that filtfilt does, so filtfilt still appears to be the preferred method of doing the actual filtering.)
.
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Digital Filtering 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!