0
$\begingroup$

I am trying to design a bandpass filter in MATLAB with following specs: $$\texttt{f_s = 20000Hz}$$ $$\texttt{3dB freq = [392 464]Hz}$$ $$\texttt{filter order = 8}$$

When I tried to implement the filter using inbuilt function :

   h  = fdesign.bandpass('N,F3dB1,F3dB2', N, Fc1, Fc2, Fs);
   Hd = design(h, 'butter');

I got the second order biquad filter coefficients as follows:

1   0   -1  1   -1.96987205062106   0.990718473985264
1   0   -1  1   -1.97676581609302   0.992045526683144
1   0   -1  1   -1.95973988650702   0.978659265852826
1   0   -1  1   -1.96334289961579   0.979977069966408

When I tried to implement using inbuilt functions butter and tf2sos, I got the second order biquad filter coefficients as follows:

1   1.99999999234270    0.999999988450783   1   -1.95973523410046   0.978656597594067
1   -1.99999999488179   0.999999991001735   1   -1.96333486913308   0.979967161667152
1   2.00000000765730    1.00000001154921    1   -1.96987710103010   0.990723209564209
1   -2.00000000511822   1.00000000899827    1   -1.97677344857326   0.992053519934887

Why is it different

$\endgroup$

1 Answer 1

1
$\begingroup$

They are mostly identical (except for some small numerical errors).

The SOS matrix is not a unique way to describe a filter. The same filter can be implemented with many different SOS matrices depending on zero/pole pairing, section scaling and section ordering. In fact, building a "good" SOS matrix is one of the more tricky parts of filter design.

In your case the main difference is in the zeros. The filter has 4 zeros at $z=1$ and another 4 zeros $z=-1$. The dfilt.df2sos object pairs one of each for each section resulting in a zero polynomial of $[1, 0, -1]$ for each.

zp2sos pairs two poles at $z=1$ and two poles $z=-1$ which gives the polynomials of $[1, 2, 1]$ and $[ 1,-2, 1]$.

The rest is just section ordering. If you want to compare two filters, compare the poles and zeros. They are unique. Avoid transfer function representation tf or $[b,a]$ since it's numerically by far the worst.

Either version is a bad filter. The relative bandwidth is way too small for the filter order and you get something that hovers around -40dB.

Here is the code to verify that the filters are the same.

%

% Compare two filters

N = 8;
Fc1 = 392;
Fc2 = 464;
Fs = 20000;
h  = fdesign.bandpass('N,F3dB1,F3dB2', N, Fc1, Fc2, Fs);
Hd = design(h, 'butter');
sos1 = Hd.sosMatrix;

%% 
[z,p,k] = butter(N/2,[Fc1 Fc2]*2/Fs);
sos0 = zp2sos(z,p,k);

%% compare poles and zeros
[z0,p0,k0] = sos2zp(sos0);
[z1,p1,k1] = sos2zp(sos1);

% sort and compare
d = sort(z0)-sort(z1);
fprintf('Mean errors for zeros = %6.2g\n',rms(d));
d = sort(p0)-sort(p1);
fprintf('Mean errors for poles = %6.2g\n',rms(d));
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.