I am trying to implement an IIR bandpass in Matlab. There are two things I don't understand. But first of all, let me post the code.

fs = 50000; %Hz
f1filter = 1000;  %Hz
f2filter = 2000;  %Hz
filterOrdnung = 6;   %erzeugt (2 * filterOrdnung) Filterkoeffizienten
anzahlFilter = 5;    %Anzahl der zu berechnenden Filter zur Auswertung
schrittweiteVerschiebung = 1000;  %Verschiebung in Hz
astop = 20;           %Verstärkung an den Bandgrenzen des Bandpasses

k = zeros(anzahlFilter, 1);                 %Vektor für Gain

z = zeros(2*filterOrdnung,anzahlFilter);    %Matrix für

p = zeros(2*filterOrdnung, anzahlFilter);   %Matrix für

sos = zeros(anzahlFilter * filterOrdnung + (anzahlFilter - 1), 6);  %Matrix für Filterkoeffizienten
[z(:,1), p(:,1), k(1,1)] = cheby2(filterOrdnung, astop, [((2*f1filter)/fs)...

[sos(1:6,:), g] = zp2sos(z(:,1),p(:,1),k(1,1));    %Output form:[b01,b11,b21,1,a11,a21
                                                   %             b02,b12,b22,1,a12,a22
                                                   %             b0N,b1N...........a2N]

fvtool(sos(1:6, :),'Analysis','freq');

So I want to create a bandpass of the bandwith of 1000Hz to 2000Hz. The filter order is the 6th order and the stop attenuation should be 20dB. I want to have the Structure of second order form. (By the way, is there any specific Matlab function to create an IIR filter as a cascade of Directform II structures?)

I am creating "sos" much larger than I need it to be now because I want to create several different bandpasses, but let's just focus on this example.

1)First question: Why do I receive 12 numerator and 12 denominator coefficients when I only have 6th order IIR? In the books I have read, that for a 6th order IIR I should receive 7 numerator and 7 denominator coefficients, with the first denominator coefficient = 1.

2)At the header of the code, I declare astop as 20dB. The Matlab documentation of cheby2 tells me, that this is the attenuation of the stopband. But when I let the code run and look at the magnitude, the magnitude of the passband is about 20dB. I expected it to be 0dB while the stopband should be -20dB. The normed frequencys seem to be about correct though. I hope I could explain my problems well enough. IIR Filter response


In Matlab when designing standard IIR frequency selective filters (Chebyshev, Butterworth, Cauer), the resulting filter order of band pass and band stop filters is always twice the specified order (i.e., $2n$ instead of $n$), because they are obtained by transforming low pass filters of order $n$.

The reason why your maximum gain is not unity has to do with the number of output arguments you use in your call to zp2sos. You specify a gain g but you don't use it for the computation of the frequency response. It would be easier to call zp2sos with just one output argument sos, because in this way, the gain is incorporated in one of the second order sections. From the mathworks documentation of zp2sos:

sos = zp2sos(...) embeds the overall system gain, $g$, in the first section, $H_1(z)$, [...]

  • 1
    $\begingroup$ That's it, thank you! I am now receiving the outputs I had hoped to! $\endgroup$
    – user44791
    Aug 25 '19 at 8:31

Actually we are also facing the same problem, instead of (Z,P,k), even if you use (A,B,C,D), as soon as sos will come in syntax with g, your magnitude response will scaled by the attenuation factor. If you are concerned only with plotting magnitude response you can plot as freqz(sos) you will get exact magnitude response without scaling.


The help file for the cheby2 function states that

If Wn is a two-element vector, 
Wn = [W1 W2], CHEBY2 returns an 
order 2N bandpass filter with 
passband  W1 < W < W2. 

Since you design a bandpass filter, your order will be $2N$ instead of $N$, and the reason for this could possibly be using two filters; like a high-low combination to create your bandpass filter...

For your second problem, you understand it right that the parameter $R$ is the stobband attenuation in dB. So, $R=20$ means there will be 20 dB stopband attenuation, as the following Matlab/Octave code verifies:

[b,a] = cheby2(6, 20, [0.2,0.4]);  % 2x6 = 12-th order bandpass cheby-II filter 

figure,freqz(b,a);     % display the frequency response

enter image description here

So the problem is either about your zp2sos conversion or frequency response plot stages...

  • $\begingroup$ Thank you for the reply. The first answer makes sense, of course. I did not think of that. I am still facing the second problem though... can't really find an error on how I pass the arguments. $\endgroup$
    – user44791
    Aug 23 '19 at 22:08
  • $\begingroup$ Why do you have to use zp2sos to convert z,p,k into [b,a] coefficienst? Why don't you directly get the [b,a] from the cheby2 filter ? $\endgroup$
    – Fat32
    Aug 23 '19 at 23:03
  • $\begingroup$ It's an alternative that I can definitely try, but my thought was to get the coefficients into a cascade of Direct Form II structure for a later implementation. I have read that this is the most common way to implement an IIR for several reasons. But I will try your suggestion. $\endgroup$
    – user44791
    Aug 24 '19 at 8:24
  • $\begingroup$ Ha yes, you want second order sections and that's good. Then as MattL also stated, the problem is in your frequency response plot, where you should also use the gain g. If you wish you can embed this gain into one of the b coefficients inside the sos , such as sos(1,1:3) = g*sos(1,1:3), then your plot from fvtool() will be corrected without adding g into it. $\endgroup$
    – Fat32
    Aug 24 '19 at 22:20
  • $\begingroup$ Thank you, I follow MattL's advice on how to use the zp2sos function including the gain in the first section of the filter. $\endgroup$
    – user44791
    Aug 25 '19 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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