*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.

## Definition

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

\[y[n]=bx[n]+ay[n-1],\]

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

\[y[n]=y[n-1]+b(x[n]-y[n-1]).\]

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).

## Impulse Response

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.

## Properties

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

\[d=e^{-1/\tau}.\]

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

\[d=e^{-2\pi f_c}.\]

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.

## Python code

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 `filter()`

member.

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`

:

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!

## General Case

*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*

\[H[z]=\frac{bz}{z-a}=\frac{b}{1-az^{-1}},\]

where \(a+b=1\) results in a filter with unity gain at DC.

The general form of this equation is

\[H[z]=\frac{b_0+b_1z^{-1}+b_2z^{-2}+\ldots}{1-a_1z^{-1}-a_2z^{-2}+\ldots}=\frac{\sum\limits_{n=0}^{\infty}b_nz^{-n}}{1-\sum\limits_{n=1}^{\infty}a_nz^{-n}}.\]

## Comments

"where a+b=1 results in a filter with unity gain." Should be "... unity gain at DC."

Yes, at DC. I’ve added it in the article for completeness.

## Add new comment