Infinite Impulse Response Filter (iirfilt)

API Keywords: iirfilt infinite impulse response IIR filter

The iirfilt_crcf object and family implement the infinite impulse response (IIR) filters. Also known as recursive filters, IIR filters allow a portion of the output to be fed back into the input, thus creating an impulse response which is non-zero for an infinite amount of time. Formally, the output signal y[n]y[n] may be written in terms of the input signalx[n]x[n] as

y[n]=1a0(j=0nb1bjx[nj]k=1na1aky[nk]) y[n] = \frac{1}{a_0} \left( \sum_{j=0}^{n_b-1}{ b_j x[n-j] } - \sum_{k=1}^{n_a-1}{ a_k y[n-k] } \right)

where b=[b0,b1,,bnb1]T\vec{b} = [b_0,b_1,\ldots,b_{n_b-1}]^T are the feed-forward parameters and a=[a0,a1,,ana1]T\vec{a} = [a_0,a_1,\ldots,a_{n_a-1}]^T are the feed-back parameters of length nbn_b and nan_a , respectively. The zz -transform of the transfer function is therefore

H(z)=Y(z)X(z)=j=0nb1bjzjk=0na1akzk=b0+b1z1++bnb1znb1a0+a1z1++ana1zna1 H(z) = \frac{Y(z)}{X(z)} = \frac{\sum\limits_{j=0}^{n_b-1}{b_j z^{-j}}} {\sum\limits_{k=0}^{n_a-1}{a_k z^{-k}}} = \frac{ b_0 + b_1 z^{-1} + \cdots + b_{n_b-1} z^{n_b-1}} { a_0 + a_1 z^{-1} + \cdots + a_{n_a-1} z^{n_a-1}}

Typically the coefficients in H(z)H(z) are normalized such that a0=1a_0=1 .

For larger order filters (even as small as n8n\approx 8 ) the filter can become unstable due to finite machine precision. It is often therefore useful to express H(z)H(z) in terms of second-order sections. For a filter of order nn , these sections are denoted by the two(L+r)×3(L+r)\times 3 matrices B\vec{B} and A\vec{A} where r=nmod  2r=n \mod 2 (0 for odd nn , 1 for even nn ) and L=(nr)/2L=(n-r)/2 .

Hd(z)=[Br,0+Br,1z11+Ar,1z1]rk=1L[Bk,0+Bk,1z1+Bk,2z21+Ak,1z1+Ak,2z2] H_d(z) = \left[ \frac{B_{r,0} + B_{r,1}z^{-1}} {1 + A_{r,1}z^{-1}} \right]^r \prod_{k=1}^{L} {\left[ \frac{B_{k,0} + B_{k,1}z^{-1} + B_{k,2}z^{-2}} {1 + A_{k,1}z^{-1} + A_{k,2}z^{-2}} \right]}

Notice that H(z)H(z) is now a series of cascaded second-order IIR filters. The sos form is practical when filters are designed from analog prototypes where the poles and zeros are known. liquid implements second-order sections efficiently with the internal iirfiltsos_crcf family of objects. For a cascaded second-order section IIR filter, use iirfilt_crcf_create_sos(B,A,n) . See also : iirdes (IIR filter design) in[ref:section-filter-iirdes] .

Listed below is the full interface to the iirfilt family of objects. The interface to the iirfilt object follows the convention of other liquid signal processing objects; while each method is listed for iirfilt_crcf , the same functionality applies to iirfilt_rrrf and iirfilt_cccf .

  • iirfilt_crcf_create(*b,Nb,*a,Nb) creates a new iirfilt object withNbN_b feed-forward coefficients b\vec{b} andNaN_a feed-back coefficients a\vec{a} .
  • iirfilt_crcf_create_sos(*B,*A,Nsos) creates a new iirfilt object using NsosN_{sos} second-order sections. The [Nsos×3][N_{sos} \times 3] feed-forward coefficient matrix is specified by B\vec{B} and the [Nsos×3][N_{sos} \times 3] feed-back coefficient matrix is specified by A\vec{A} .
  • iirfilt_crcf_create_prototype(ftype,btype,format,order,fc,f0,Ap,As) creates a new IIR filter object using the prototype interface described in [ref:section-filter-iirdes-iirdes] . This is the simplest method for designing an IIR filter with Butterworth, Chebyshev-I, Chebyshev-II, elliptic/Cauer, or Bessel coefficients.
  • iirfilt_crcf_destroy(q) destroys an iirfilt object, freeing all internally-allocated memory arrays and buffers.
  • iirfilt_crcf_print(q) prints the internals of an iirfilt object.
  • iirfilt_crcf_clear(q) clears the filter's internal state.
  • iirfilt_crcf_execute(q,x,*y) executes one iteration of the filter with an input xx , storing the result in yy , and updating its internal state.
  • iirfilt_crcf_get_length(q) returns the order of the filter.
  • iirfilt_crcf_freqresponse(q,fc,*H) computes the complex response HH of the filter at the normalized frequency fcf_c .
  • iirfilt_crcf_groupdelay(q,fc) returns the group delay of the filter at the normalized frequency fcf_c .

Listed below is a basic example of the interface. For more detailed and extensive examples, refer to examples/iirfilt_crcf_example.c in the main liquid project source directory.

#include <liquid/liquid.h>

int main() {
    // options
    unsigned int order=4;   // filter order

    unsigned int n = order+1;
    float b[n], a[n];

    // ... initialize filter coefficients ...

    // create filter object
    iirfilt_crcf q = iirfilt_crcf_create(b,n,a,n);

    float complex x;    // input sample
    float complex y;    // output sample

    // execute filter (repeat as necessary)
    iirfilt_crcf_execute(q,x,&y);

    // destroy filter object
    iirfilt_crcf_destroy(q);
}
doc/iirfilt/filter_iirfilt_crcf_time.png

Figure [fig-filter-iirfilt_crcf]. iirfilt_crcf (infinite impulse response filter) example.

An example of the iirfilt can be seen in[ref:fig-filter-iirfilt_crcf] in which a low-pass filter is applied to a signal to remove a high-frequency component.