Infinite Impulse Response Filter (iirfilt
)¶
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]\) may be written in terms of the input signal
\(x[n]\) as
where \(\vec{b} = [b_0,b_1,\ldots,b_{n_b-1}]^T\) are the feed-forward parameters and \(\vec{a} = [a_0,a_1,\ldots,a_{n_a-1}]^T\) are the feed-back parameters of length \(n_b\) and \(n_a\), respectively. The \(z\)-transform of the transfer function is therefore
Typically the coefficients in \(H(z)\) are normalized such that \(a_0=1\).
For larger order filters (even as small as \(n\approx 8\)) the filter can become unstable due to finite machine precision. It is often therefore useful to express \(H(z)\) in terms of second-order sections. For a filter of order \(n\), these sections are denoted by the two \((L+r)\times 3\) matrices \(\vec{B}\) and \(\vec{A}\) where \(r=n \mod 2\) (0 for odd \(n\), 1 for even \(n\)) and \(L=(n-r)/2\).
Notice that \(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 create_sos().
Examples¶
Listed below is a basic example of the interface in which a low-pass filter is applied to a signal to remove a high-frequency component.
#include <stdio.h>
#include <math.h>
#include <complex.h>
#include "liquid.h"
int main(int argc, char*argv[])
{
// create filter object from prototype
iirfilt_crcf q = iirfilt_crcf_create_prototype(
LIQUID_IIRDES_ELLIP,
LIQUID_IIRDES_LOWPASS,
LIQUID_IIRDES_SOS,
7, // filter order
0.1f, // fc, cutoff frequency
0.0f, // f0, center frequency for bandpass
0.1f, // Ap, pass-band ripple [dB]
40.0f); // As, stop-band suppression [dB]
printf(" x-real x-imag y-real y-imag\n");
unsigned int i;
for (i=0; i<120; i++) {
// input (two tones)
float complex x = i >= 80 ? 0 :
1.0f*cexpf(_Complex_I*2*M_PI*0.057f*i) +
0.5f*cexpf(_Complex_I*2*M_PI*0.392f*i);
// compute filtered output
float complex y;
iirfilt_crcf_execute(q, x, &y);
printf("%12.8f %12.8f %12.8f %12.8f\n",
crealf(x), cimagf(x), crealf(y), cimagf(y));
}
// destroy filter object
iirfilt_crcf_destroy(q);
return 0;
}
The output of this example is plotted below in Figure 5, below:

Figure 5 iirfilt_crcf
(infinite impulse response filter) demonstration¶
You can create a filter from a given set of filter coefficients as well, viz.
#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);
}
Interface¶
Listed below is the full interface to the iirfilt
family of
objects.
create()
¶
Create infinite impulse response filter from external coefficients. Note that the number of feed-forward and feed-back coefficients do not need to be equal, but they do need to be non-zero. Furthermore, the first feed-back coefficient (a_0) cannot be equal to zero, otherwise the filter will be invalid as this value is factored out from all coefficients. For stability reasons the number of coefficients should reasonably not exceed about 8 for single-precision floating-point.
iirfilt_rrrf = iirfilt_rrrf_create(float * _b, unsigned int _nb, float * _a, unsigned int _na);
float * _b
: feed-forward coefficients (numerator)unsigned int _nb
: number of feed-forward coefficientsfloat * _a
: feed-back coefficients (denominator)unsigned int _na
: number of feed-back coefficientsreturns new
iirfilt_rrrf
object
iirfilt_crcf = iirfilt_crcf_create(float * _b, unsigned int _nb, float * _a, unsigned int _na);
float * _b
: feed-forward coefficients (numerator)unsigned int _nb
: number of feed-forward coefficientsfloat * _a
: feed-back coefficients (denominator)unsigned int _na
: number of feed-back coefficientsreturns new
iirfilt_crcf
object
iirfilt_cccf = iirfilt_cccf_create(float complex * _b, unsigned int _nb, float complex * _a, unsigned int _na);
float complex * _b
: feed-forward coefficients (numerator)unsigned int _nb
: number of feed-forward coefficientsfloat complex * _a
: feed-back coefficients (denominator)unsigned int _na
: number of feed-back coefficientsreturns new
iirfilt_cccf
object
create_sos()
¶
Create IIR filter using 2nd-order sections from external coefficients.
iirfilt_rrrf = iirfilt_rrrf_create_sos(float * _b, float * _a, unsigned int _nsos);
float * _b
: feed-forward coefficientsfloat * _a
: feed-back coefficientsunsigned int _nsos
: number of second-order sections (sos)returns new
iirfilt_rrrf
object
iirfilt_crcf = iirfilt_crcf_create_sos(float * _b, float * _a, unsigned int _nsos);
float * _b
: feed-forward coefficientsfloat * _a
: feed-back coefficientsunsigned int _nsos
: number of second-order sections (sos)returns new
iirfilt_crcf
object
iirfilt_cccf = iirfilt_cccf_create_sos(float complex * _b, float complex * _a, unsigned int _nsos);
float complex * _b
: feed-forward coefficientsfloat complex * _a
: feed-back coefficientsunsigned int _nsos
: number of second-order sections (sos)returns new
iirfilt_cccf
object
create_prototype()
¶
Create IIR filter from design template
iirfilt_rrrf = iirfilt_rrrf_create_prototype(liquid_iirdes_filtertype _ftype, liquid_iirdes_bandtype _btype, liquid_iirdes_format _format, unsigned int _order, float _fc, float _f0, float _ap, float _as);
liquid_iirdes_filtertype _ftype
: filter type (e.g. LIQUID_IIRDES_BUTTER)liquid_iirdes_bandtype _btype
: band type (e.g. LIQUID_IIRDES_BANDPASS)liquid_iirdes_format _format
: coefficients format (e.g. LIQUID_IIRDES_SOS)unsigned int _order
: filter orderfloat _fc
: low-pass prototype cut-off frequencyfloat _f0
: center frequency (band-passfloat _ap
: pass-band ripple in dBfloat _as
: stop-band ripple in dBreturns new
iirfilt_rrrf
object
iirfilt_crcf = iirfilt_crcf_create_prototype(liquid_iirdes_filtertype _ftype, liquid_iirdes_bandtype _btype, liquid_iirdes_format _format, unsigned int _order, float _fc, float _f0, float _ap, float _as);
liquid_iirdes_filtertype _ftype
: filter type (e.g. LIQUID_IIRDES_BUTTER)liquid_iirdes_bandtype _btype
: band type (e.g. LIQUID_IIRDES_BANDPASS)liquid_iirdes_format _format
: coefficients format (e.g. LIQUID_IIRDES_SOS)unsigned int _order
: filter orderfloat _fc
: low-pass prototype cut-off frequencyfloat _f0
: center frequency (band-passfloat _ap
: pass-band ripple in dBfloat _as
: stop-band ripple in dBreturns new
iirfilt_crcf
object
iirfilt_cccf = iirfilt_cccf_create_prototype(liquid_iirdes_filtertype _ftype, liquid_iirdes_bandtype _btype, liquid_iirdes_format _format, unsigned int _order, float _fc, float _f0, float _ap, float _as);
liquid_iirdes_filtertype _ftype
: filter type (e.g. LIQUID_IIRDES_BUTTER)liquid_iirdes_bandtype _btype
: band type (e.g. LIQUID_IIRDES_BANDPASS)liquid_iirdes_format _format
: coefficients format (e.g. LIQUID_IIRDES_SOS)unsigned int _order
: filter orderfloat _fc
: low-pass prototype cut-off frequencyfloat _f0
: center frequency (band-passfloat _ap
: pass-band ripple in dBfloat _as
: stop-band ripple in dBreturns new
iirfilt_cccf
object
create_lowpass()
¶
Create simplified low-pass Butterworth IIR filter
iirfilt_rrrf = iirfilt_rrrf_create_lowpass(unsigned int _order, float _fc);
unsigned int _order
: filter orderfloat _fc
: low-pass prototype cut-off frequencyreturns new
iirfilt_rrrf
object
iirfilt_crcf = iirfilt_crcf_create_lowpass(unsigned int _order, float _fc);
unsigned int _order
: filter orderfloat _fc
: low-pass prototype cut-off frequencyreturns new
iirfilt_crcf
object
iirfilt_cccf = iirfilt_cccf_create_lowpass(unsigned int _order, float _fc);
unsigned int _order
: filter orderfloat _fc
: low-pass prototype cut-off frequencyreturns new
iirfilt_cccf
object
create_integrator()
¶
Create 8th-order integrator filter
iirfilt_rrrf = iirfilt_rrrf_create_integrator();
returns new
iirfilt_rrrf
object
iirfilt_crcf = iirfilt_crcf_create_integrator();
returns new
iirfilt_crcf
object
iirfilt_cccf = iirfilt_cccf_create_integrator();
returns new
iirfilt_cccf
object
create_differentiator()
¶
Create 8th-order differentiator filter
iirfilt_rrrf = iirfilt_rrrf_create_differentiator();
returns new
iirfilt_rrrf
object
iirfilt_crcf = iirfilt_crcf_create_differentiator();
returns new
iirfilt_crcf
object
iirfilt_cccf = iirfilt_cccf_create_differentiator();
returns new
iirfilt_cccf
object
create_dc_blocker()
¶
Create simple first-order DC-blocking filter with transfer function ( H(z) = frac{1 - z^{-1}}{1 - (1-alpha)z^{-1}} )
iirfilt_rrrf = iirfilt_rrrf_create_dc_blocker(float _alpha);
float _alpha
: normalized filter bandwidthreturns new
iirfilt_rrrf
object
iirfilt_crcf = iirfilt_crcf_create_dc_blocker(float _alpha);
float _alpha
: normalized filter bandwidthreturns new
iirfilt_crcf
object
iirfilt_cccf = iirfilt_cccf_create_dc_blocker(float _alpha);
float _alpha
: normalized filter bandwidthreturns new
iirfilt_cccf
object
create_pll()
¶
Create filter to operate as second-order integrating phase-locked loop (active lag design)
iirfilt_rrrf = iirfilt_rrrf_create_pll(float _w, float _zeta, float _K);
float _w
: filter bandwidthfloat _zeta
: damping factorfloat _K
: loop gainreturns new
iirfilt_rrrf
object
iirfilt_crcf = iirfilt_crcf_create_pll(float _w, float _zeta, float _K);
float _w
: filter bandwidthfloat _zeta
: damping factorfloat _K
: loop gainreturns new
iirfilt_crcf
object
iirfilt_cccf = iirfilt_cccf_create_pll(float _w, float _zeta, float _K);
float _w
: filter bandwidthfloat _zeta
: damping factorfloat _K
: loop gainreturns new
iirfilt_cccf
object
copy()
¶
Copy object including all internal objects and state
iirfilt_rrrf = iirfilt_rrrf_copy(iirfilt_rrrf _q);
iirfilt_rrrf _q
:returns new
iirfilt_rrrf
object
iirfilt_crcf = iirfilt_crcf_copy(iirfilt_crcf _q);
iirfilt_crcf _q
:returns new
iirfilt_crcf
object
iirfilt_cccf = iirfilt_cccf_copy(iirfilt_cccf _q);
iirfilt_cccf _q
:returns new
iirfilt_cccf
object
destroy()
¶
Destroy iirfilt object, freeing all internal memory
int = iirfilt_rrrf_destroy(iirfilt_rrrf _q);
iirfilt_rrrf _q
:returns standard error code
int = iirfilt_crcf_destroy(iirfilt_crcf _q);
iirfilt_crcf _q
:returns standard error code
int = iirfilt_cccf_destroy(iirfilt_cccf _q);
iirfilt_cccf _q
:returns standard error code
print()
¶
Print iirfilt object properties to stdout
int = iirfilt_rrrf_print(iirfilt_rrrf _q);
iirfilt_rrrf _q
:returns standard error code
int = iirfilt_crcf_print(iirfilt_crcf _q);
iirfilt_crcf _q
:returns standard error code
int = iirfilt_cccf_print(iirfilt_cccf _q);
iirfilt_cccf _q
:returns standard error code
reset()
¶
Reset iirfilt object internals
int = iirfilt_rrrf_reset(iirfilt_rrrf _q);
iirfilt_rrrf _q
:returns standard error code
int = iirfilt_crcf_reset(iirfilt_crcf _q);
iirfilt_crcf _q
:returns standard error code
int = iirfilt_cccf_reset(iirfilt_cccf _q);
iirfilt_cccf _q
:returns standard error code
set_scale()
¶
Set output scaling for filter
int = iirfilt_rrrf_set_scale(iirfilt_rrrf _q, float _scale);
iirfilt_rrrf _q
: filter objectfloat _scale
: scaling factor to apply to each output samplereturns standard error code
int = iirfilt_crcf_set_scale(iirfilt_crcf _q, float _scale);
iirfilt_crcf _q
: filter objectfloat _scale
: scaling factor to apply to each output samplereturns standard error code
int = iirfilt_cccf_set_scale(iirfilt_cccf _q, float complex _scale);
iirfilt_cccf _q
: filter objectfloat complex _scale
: scaling factor to apply to each output samplereturns standard error code
get_scale()
¶
Get output scaling for filter
int = iirfilt_rrrf_get_scale(iirfilt_rrrf _q, float * _scale);
iirfilt_rrrf _q
: filter objectfloat * _scale
: scaling factor applied to each output samplereturns standard error code
int = iirfilt_crcf_get_scale(iirfilt_crcf _q, float * _scale);
iirfilt_crcf _q
: filter objectfloat * _scale
: scaling factor applied to each output samplereturns standard error code
int = iirfilt_cccf_get_scale(iirfilt_cccf _q, float complex * _scale);
iirfilt_cccf _q
: filter objectfloat complex * _scale
: scaling factor applied to each output samplereturns standard error code
execute()
¶
Compute filter output given a single input sample
int = iirfilt_rrrf_execute(iirfilt_rrrf _q, float _x, float * _y);
iirfilt_rrrf _q
: iirfilt objectfloat _x
: input samplefloat * _y
: output sample pointerreturns standard error code
int = iirfilt_crcf_execute(iirfilt_crcf _q, float complex _x, float complex * _y);
iirfilt_crcf _q
: iirfilt objectfloat complex _x
: input samplefloat complex * _y
: output sample pointerreturns standard error code
int = iirfilt_cccf_execute(iirfilt_cccf _q, float complex _x, float complex * _y);
iirfilt_cccf _q
: iirfilt objectfloat complex _x
: input samplefloat complex * _y
: output sample pointerreturns standard error code
execute_block()
¶
Execute the filter on a block of input samples; in-place operation is permitted (the input and output buffers may be the same)
int = iirfilt_rrrf_execute_block(iirfilt_rrrf _q, float * _x, unsigned int _n, float * _y);
iirfilt_rrrf _q
: filter objectfloat * _x
: pointer to input arrayunsigned int _n
: number of inputfloat * _y
: pointer to output arrayreturns standard error code
int = iirfilt_crcf_execute_block(iirfilt_crcf _q, float complex * _x, unsigned int _n, float complex * _y);
iirfilt_crcf _q
: filter objectfloat complex * _x
: pointer to input arrayunsigned int _n
: number of inputfloat complex * _y
: pointer to output arrayreturns standard error code
int = iirfilt_cccf_execute_block(iirfilt_cccf _q, float complex * _x, unsigned int _n, float complex * _y);
iirfilt_cccf _q
: filter objectfloat complex * _x
: pointer to input arrayunsigned int _n
: number of inputfloat complex * _y
: pointer to output arrayreturns standard error code
get_length()
¶
Return number of coefficients for iirfilt object (maximum between the feed-forward and feed-back coefficients). Note that the filter length = filter order + 1
unsigned int = iirfilt_rrrf_get_length(iirfilt_rrrf _q);
iirfilt_rrrf _q
:returns something good
unsigned int = iirfilt_crcf_get_length(iirfilt_crcf _q);
iirfilt_crcf _q
:returns something good
unsigned int = iirfilt_cccf_get_length(iirfilt_cccf _q);
iirfilt_cccf _q
:returns something good
freqresponse()
¶
Compute complex frequency response of filter object
int = iirfilt_rrrf_freqresponse(iirfilt_rrrf _q, float _fc, liquid_float_complex * _H);
iirfilt_rrrf _q
: filter objectfloat _fc
: normalized frequency for evaluationliquid_float_complex * _H
: pointer to output complex frequency responsereturns standard error code
int = iirfilt_crcf_freqresponse(iirfilt_crcf _q, float _fc, liquid_float_complex * _H);
iirfilt_crcf _q
: filter objectfloat _fc
: normalized frequency for evaluationliquid_float_complex * _H
: pointer to output complex frequency responsereturns standard error code
int = iirfilt_cccf_freqresponse(iirfilt_cccf _q, float _fc, liquid_float_complex * _H);
iirfilt_cccf _q
: filter objectfloat _fc
: normalized frequency for evaluationliquid_float_complex * _H
: pointer to output complex frequency responsereturns standard error code
get_psd()
¶
Compute power spectral density response of filter object in dB
float = iirfilt_rrrf_get_psd(iirfilt_rrrf _q, float _fc);
iirfilt_rrrf _q
: filter objectfloat _fc
: normalized frequency for evaluationreturns something good
float = iirfilt_crcf_get_psd(iirfilt_crcf _q, float _fc);
iirfilt_crcf _q
: filter objectfloat _fc
: normalized frequency for evaluationreturns something good
float = iirfilt_cccf_get_psd(iirfilt_cccf _q, float _fc);
iirfilt_cccf _q
: filter objectfloat _fc
: normalized frequency for evaluationreturns something good
groupdelay()
¶
Compute and return group delay of filter object
float = iirfilt_rrrf_groupdelay(iirfilt_rrrf _q, float _fc);
iirfilt_rrrf _q
: filter objectfloat _fc
: frequency to evaluatereturns something good
float = iirfilt_crcf_groupdelay(iirfilt_crcf _q, float _fc);
iirfilt_crcf _q
: filter objectfloat _fc
: frequency to evaluatereturns something good
float = iirfilt_cccf_groupdelay(iirfilt_cccf _q, float _fc);
iirfilt_cccf _q
: filter objectfloat _fc
: frequency to evaluatereturns something good