Filtfilt returns NaN matrix
4 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Aboltabol
le 10 Mai 2023
Commenté : Star Strider
le 11 Mai 2023
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 commentaires
Walter Roberson
le 10 Mai 2023
If you have even 1 nan or inf in your data the filtered results will likely be nan
Réponse acceptée
Star Strider
le 10 Mai 2023
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 commentaires
Star Strider
le 11 Mai 2023
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.)
.
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Digital Filtering dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!