Summary: This article shows how to implement a low-pass single-pole IIR filter. The article is complemented by a Filter Design tool that allows you to create your own custom versions of the example filter that is shown below.
The low-pass single-pole IIR filter is a very useful tool to have in your DSP toolbox. Its performance in the frequency domain may not be stellar, but it is very computationally efficient.
A low-pass single-pole IIR filter has a single design parameter, which is the decay value \(d\). It is customary to define parameters \(a=d\) and \(b=1-d\) (the logic behind this follows from the general case below). For a typical value of \(d=0.99\), we have that \(a=0.99\) and \(b=0.01\). The recurrence relation is then given by
where the sequence \(x[n]\) is the input and \(y[n]\) is the output of the filter.
The recurrence relation directly shows the effect of the filter. The previous output value of the the filter, \(y[n-1]\), is decreased with the decay factor \(a=d\). The current input value, \(x[n]\), is taken into account by adding a small fraction \(b=1-d\) of it to the output value.
Substituting \(b=1-a\) in the given recurrence relation and rewriting leads to the expression
This then leads to compact update expressions such as
y += b * (x - y), in programming languages that support the
+=-operator (see the Python code below for an example).
For windowed-sinc filters (see, e.g., How to Create a Simple Low-Pass Filter), the impulse response is the filter. To apply the filter, you convolve the impulse response of the filter with the data. This is different for the single-pole IIR filter. Its action is essentially defined on a sample-by-sample basis, as described by the recurrence relation given above. The impulse response of a filter with \(d=0.9\) (\(b=0.1\)) is shown in Figure 1.
Of course, this impulse response is actually infinite. I’ve plotted the first 50 samples here, and at that point it is quite close to zero, but it never actually reaches zero.
The response of this filter is completely analogous to the response of an electronic low-pass filter consisting of a single resistor and a single capacitor.
The decay value \(d\) is related to the time constant \(\tau\) of the filter with the relation
Hence, if \(d\) is given, the value of \(\tau\) can be computed as \(\tau=-1/\ln(d)\). As for an electronic RC-filter, the time constant \(\tau\) gives the time (in samples for the discrete case) for the output to decrease to 36.8% (\(1/e\)) of the original value.
Another useful relation is that between \(d\) and the (-3 dB) cutoff frequency \(f_c\), which is
Hence, if \(d\) is given, the value of \(f_c\) can be computed as \(f_c=-\ln(d)/2\pi\).
The frequency response of the filter with the impulse response of Figure 1 is given in Figure 2.
In Python and in most other programming languages, the recurrence relation can be implemented through the already mentioned expression
y += b * (x - y). Below is a small Python class that implements this expression in its
# All scripts on TomRoelandts.com assume Python 3. decay = 0.9 # Decay between samples (in (0, 1)). class LowPassSinglePole: def __init__(self, decay): self.b = 1 - decay self.reset() def reset(self): self.y = 0 def filter(self, x): self.y += self.b * (x - self.y) return self.y low_pass_single_pole = LowPassSinglePole(decay)
This filter can then be applied by calling the
filter() member for each new input sample
x, resulting in a new output sample
y = low_pass_single_pole.filter(x)
Filter Design Tool
This article is complemented with a Filter Design tool. Experiment with different values for \(d\), visualize the resulting filters, and download the filter code. Try it now!
This last section is mainly here to have everything in one place for now. I plan to add a separate article on the Z-transform later.
A single-pole low-pass infinite impulse response (IIR) filter is given by the Z-transform
where \(a+b=1\) results in a filter with unity gain at DC.
The general form of this equation is