Wednesday, October 24, 2018

bandpass - The reasons for filter explosion


Assume signal x, sampled at fs=44100Hz. I tried to filter it using the Butterworth bandpass filter ( 30Hz70Hz) of order 8. However, as a result I get a vector with most elements being NaN (and some of them extremely small, approx. 2.510306`).


If I try the same filter of order 6, I get results as expected. What could be possible reason for order 8 filter to 'explode'?


Here is the MATLAB code, just in case I made an error which I don't see:


[b, a] = butter(4, [60 / fs, 140/fs]);

x_filtered = filter(b, a, x);

Answer



Basically you never want to use the Transfer Function representation (with b and a) and rather use the Zeros-Poles-Gain (z,p,k). This will allow you to avoid the numerical errors. In your case you might design your filter in following way:


fs = 44100;           % Sampling frequency
Wp = [30, 70]/(fs/2); % Pass band frequencies (as normalized frequency)
Ws = [20, 90]/(fs/2); % Stop band frequencies
Rp = 3; % Ripple at pass band
Rs = 50; % Ripple at stop band

[n, Wn] = buttord(Wp, Ws, Rp, Rs); % Get order and omega vector

[z, p, k] = butter(n, Wn, 'bandpass'); % Design filter accordingly
[sos, g] = zp2sos(z, p, k); % Convert to state matrix
Hd = dfilt.df2sos(sos, g); % Create the filter object

Which for some dummy random signal:


x = rand(1,100000);
y = filter(Hd, x);

Will produce a stable output:


enter image description here



And here is the filter frequency response (everything looks as requested):


enter image description here


No comments:

Post a Comment

periodic trends - Comparing radii in lithium, beryllium, magnesium, aluminium and sodium ions

Apparently the of last four, MgX2+ is closest in radius to LiX+. Is this true, and if so, why would a whole larger shell ($\ce{...