Getting NaN after filtfilt function
18 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Ritesh
el 15 de En. de 2024
Comentada: Star Strider
el 28 de En. de 2024
I am applying a simple butterworth bandpass filter to a signal having low cut off freq 0.5 and higher cutoff freq 3. But after designing the filter when i am applying filtfilt function i am getting the signal as array of NaN. To check if in the specified frequency range any signal does not exist, i crosschecked it with fft and there was some peaks in that range, which indicate the presence of signl in that range. I dont understand why i am getting NaN.
I am giving the data link of matlab drive, fft plots and code.

sampling_frequency = 1000000;
signal = concatenatedData(:, 2);
order = 11;
low_cutoff = 0.5;
high_cutoff = 3;
[b, a] = butter(order, [low_cutoff, high_cutoff] / (sampling_frequency / 2));
filtered_signal = filtfilt(b, a, signal);
0 comentarios
Respuesta aceptada
Star Strider
el 15 de En. de 2024
Editada: Star Strider
el 15 de En. de 2024
You are using transfer function (‘[b,a]’) output implementation. Often, this creates an unstable filter, producing NaN values in the fitlered output. Using freqz, the instability is readily apparent —
sampling_frequency = 1000000;
% signal = concatenatedData(:, 2);
order = 11;
low_cutoff = 0.5;
high_cutoff = 3;
[b, a] = butter(order, [low_cutoff, high_cutoff] / (sampling_frequency / 2));
% filtered_signal = filtfilt(b, a, signal);
figure
freqz(b, a, 2^16, sampling_frequency)
set(subplot(2,1,1), 'XScale','log')
set(subplot(2,1,2), 'XScale','log')
The solution is to use second-order-section implementation instead, as discussed in the butter documentation section on Limitations. (This is true generally, not simply with Butterworth filters, and the same discussion appears in the documentation on all of them.)
sampling_frequency = 1000000;
% signal = concatenatedData(:, 2);
order = 11;
low_cutoff = 0.5;
high_cutoff = 3;
[z, p, k] = butter(order, [low_cutoff, high_cutoff] / (sampling_frequency / 2));
[sos,g] = zp2sos(z,p,k);
% filtered_signal = filtfilt(sos, g, signal);
figure
freqz(sos, 2^16, sampling_frequency)
set(subplot(2,1,1), 'XScale','log')
set(subplot(2,1,2), 'XScale','log')
There is no instability in the second-order-section implementation.
EDIT — (15 Jan 2024 at 16:52)
Wp = [low_cutoff, high_cutoff] / (sampling_frequency / 2);
Ws = [0.9 1.1] .* Wp;
Rp = 1;
Rs = 60;
[n,Wn] = buttord(Wp,Ws,Rp,Rs)
[z,p,k] = butter(n,Wn);
[sos,g] = zp2sos(z,p,k);
% filtered_signal = filtfilt(sos, g, signal);
figure
freqz(sos, 2^16, sampling_frequency)
set(subplot(2,1,1), 'XScale','log')
xt1 = get(subplot(2,1,1), 'XTick')
set(subplot(2,1,2), 'XScale','log')
xt2 = get(subplot(2,1,2), 'XTick')
NOTE — A passband of [0.5 3.0] Hz with a 1 MHz sampling frequency may be difficult to realise in the best of circumstances.
.
17 comentarios
Más respuestas (1)
Hassaan
el 15 de En. de 2024
Editada: Hassaan
el 15 de En. de 2024
- Stability of the Filter: With high filter orders, like the 11th order you're using, the filter can become unstable, especially when applied in a forward-backward manner as filtfilt does. The Butterworth filter design should theoretically be stable, but numerical issues can arise due to finite precision arithmetic.
- Initial Conditions: The filtfilt function typically handles initial conditions to reduce transients by using a certain method of padding. If something is off with the initial conditions or the padding, it might lead to NaN values.
- Data Quality: Ensure there are no NaN or Inf values in your input signal. filtfilt will not be able to handle these and will propagate NaNs throughout the output.
- Filter Coefficients: Check the filter coefficients b and a for any NaN or Inf values. This could happen if the butter function encounters numerical issues.
- Signal Characteristics: If the signal has certain characteristics that are not compatible with the filtering process, it might lead to issues. However, since you mentioned that the FFT shows peaks within the passband, this seems less likely.
Here's what you can do to debug:
- Check for NaNs or Infs in your input signal and filter coefficients.
- Reduce the filter order. A lower order might be more stable numerically.
- Normalize your signal if it has very large or very small values. Such values could cause numerical instability.
- Use a different filtering approach or design method to see if it's specific to filtfilt or Butterworth design.
This script includes checks for NaNs in your signal, filter stability, and also reduces the filter order for better numerical stability.
% Load your signal data
% Assuming 'concatenatedData' is already in your workspace
signal = concatenatedData(:, 2);
% Check for NaNs or Infs in the input signal
if any(isnan(signal)) || any(isinf(signal))
error('Signal contains NaNs or Infs.');
end
% Define filter parameters
sampling_frequency = 1000000;
order = 2; % Reduced order for stability
low_cutoff = 0.5;
high_cutoff = 3;
% Calculate filter coefficients
[b, a] = butter(order, [low_cutoff, high_cutoff] / (sampling_frequency / 2), 'bandpass');
% Check for NaNs or Infs in filter coefficients
if any(isnan(b)) || any(isnan(a)) || any(isinf(b)) || any(isinf(a))
error('Filter coefficients contain NaNs or Infs.');
end
% Check stability of the filter
if any(abs(roots(a)) >= 1)
error('Filter is unstable.');
end
% Apply the filter using filtfilt
filtered_signal = filtfilt(b, a, signal);
% Check for NaNs in the filtered signal
if any(isnan(filtered_signal))
nan_indices = find(isnan(filtered_signal));
fprintf('NaNs start at index %d.\n', nan_indices(1));
else
fprintf('Filtering completed without NaNs.\n');
end
% Plot the original and filtered signals for comparison
figure;
subplot(2,1,1);
plot(signal);
title('Original Signal');
subplot(2,1,2);
plot(filtered_signal);
title('Filtered Signal');
---------------------------------------------------------------------------------------------------------------------------------------------------------
If you find the solution helpful and it resolves your issue, it would be greatly appreciated if you could accept the answer. Also, leaving an upvote and a comment are also wonderful ways to provide feedback.
Professional Interests
- Technical Services and Consulting
- Embedded Systems | Firmware Developement | Simulations
- Electrical and Electronics Engineering
Feel free to contact me.
Ver también
Categorías
Más información sobre Multirate and Multistage Filters en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!












