Skip to content

IIR design by the bilinear transform

Map an analog filter to a digital one with the bilinear transform, watch frequencies warp, pre-warp the cutoff, and design a Butterworth by hand.

Before this20.1 · 6 more
Chapter 20 · Lesson 2 of 6

First, the picture

An analog filter becomes a digital one by a change of variable that bends the s-plane. Below, the jω axis curls into the unit circle, and a filter’s four poles ride along. Watch where each tick on the axis lands.

The jω axis curls into the unit circle

A 4th-order Butterworth, analog cutoff 1054.8 Hz, at f_s = 8 kHz: s is scaled by T_s/2, moved right by 1, then mapped by z = (1 + sT_s/2)/(1 − sT_s/2).

The s-plane, scaled and moved right by 1: its jω axis is the vertical line, and the four Butterworth poles sit on a circle round z = 1.

analog cutoff
1054.8 Hz
lands at
not yet
0.00 / 12.00 s
Describe this picture

One plane, with the real part across and the imaginary part up on one scale both ways, for a 4th-order Butterworth with its analog cutoff at 1054.8 Hz, at fs=8f_s=8 kHz. The s-plane is scaled by Ts/2T_s/2, moved right by 1, then mapped by z=(1+sTs/2)/(1−sTs/2)z=(1+sT_s/2)/(1-sT_s/2). A thin unit circle is drawn throughout, as the target. The image of the jω axis is a solid line, labelled “jω axis” until it lies on that circle. Short ticks on it mark analog 0, 1054.8, 4000 and 16 000 Hz, each labelled with its analog frequency, and their mirrors. The image of the left half-plane is lightly shaded and hatched, and the four poles are crosses. The readouts are the analog cutoff and where it lands. There is no control.

The clip lasts 12 s. It starts with the scaled and moved s-plane: its jω axis is the vertical line, and the four Butterworth poles sit on a circle round z=1z=1. From 3 s to 8 s the map bends the line into the unit circle and the poles ride along; at 8.5 s each tick also shows where it landed. At the end the jω axis is the unit circle: 0 Hz at z=1z=1, the analog cutoff 1054.8 Hz at 1000 Hz, 16 kHz at 3598 Hz, and infinity at z=−1z=-1. All four poles landed inside: stable stays stable.

The jω axis curls into the unit circle

Analog prototype filters (20.1) gave us a shelf of good analog filters: Butterworth, Chebyshev, elliptic and Bessel. Each one is an H(s)H(s), made for circuits. On this page I turn one into an H(z)H(z), a digital filter that runs as code.

Analog and digital frequency meet on this page, so first a word on letters. Analog frequency is ω\omega (rad/s), digital frequency is Ω\Omega (rad/sample); Oppenheim and Schafer use the opposite letters.

An analog filter is a ratio of two polynomials in ss. So here is the plan: replace every ss by an expression in zz, and the ratio becomes one in zz. The replacement I’ll use is the bilinear transform:

s=2Ts z−1z+1.s=\frac{2}{T_s}\,\frac{z-1}{z+1}.

Here Ts=1/fsT_s=1/f_s is the sample period. The name says that the top and the bottom are both of first degree, linear, in zz.

Does the order of the filter change? Take one pole pkp_k of the analog filter. Its factor turns into

1s−pk=z+1(2/Ts−pk) z−(2/Ts+pk).\begin{aligned} &\frac{1}{s-p_k}\\ &\quad=\frac{z+1}{(2/T_s-p_k)\,z-(2/T_s+p_k)}. \end{aligned}

So each analog pole gives one digital pole and one zero at z=−1z=-1. A filter of order NN stays a filter of order NN.

Where does a point ss land? Solve the transform for zz:

z=1+sTs/21−sTs/2.z=\frac{1+sT_s/2}{1-sT_s/2}.

Put in a point of the jω axis, s=jωs=j\omega. The top is 1+jωTs/21+j\omega T_s/2 and the bottom is 1−jωTs/21-j\omega T_s/2. They are mirror images, so they have the same length, and ∣z∣=1\lvert z\rvert=1. The whole jω axis lands on the unit circle.

The z-transform (16.1) had another map, z=esTsz=e^{sT_s}. It wraps the jω axis round the circle again and again, once every 2π/Ts2\pi/T_s rad/s, and that is aliasing. The bilinear map goes round once.

Now the left half-plane. The top, ∣1+sTs/2∣\lvert1+sT_s/2\rvert, is the distance from the point sTs/2sT_s/2 to −1-1, and the bottom is its distance to +1+1. A point left of the vertical axis is closer to −1-1, so ∣z∣<1\lvert z\rvert<1.

So every pole of a stable analog filter (Poles, zeros and the s-plane, 9.3) lands inside the unit circle. That is what a stable digital filter needs (Stability and causality, 16.4).

The picture at the top of the page shows the map as a motion. It starts from the s-plane scaled by Ts/2T_s/2 and moved right by 1, which is the top of the fraction, 1+sTs/21+sT_s/2. There the jω axis is the vertical line through 1. Then the division by 1−sTs/21-sT_s/2 is faded in, and the line bends into the circle.

The filter on show is a 4th-order Butterworth at fs=8f_s=8 kHz, with its analog cutoff at 1054.8 Hz. That odd number is on purpose, and the second instrument explains it.

Watch the tick at 1054.8 Hz: it lands on 1000 Hz. And 16 kHz, far above fs/2=4f_s/2=4 kHz, lands at 3598 Hz, still below 4 kHz. Nothing aliases, because each analog frequency gets its own place on the circle.

The maths behind it · Möbius transformations

The bilinear map is a Möbius transformation: the action of the 2×2 matrix (11−11)\begin{pmatrix}1&1\\-1&1\end{pmatrix} on the point sTs/2sT_s/2. Its top row gives the numerator sTs/2+1sT_s/2+1, its bottom row the denominator −sTs/2+1-sT_s/2+1. Such maps send lines and circles to lines and circles, which is why the jω axis becomes exactly the unit circle. Composing two of them multiplies their matrices.

Where each frequency lands

Follow a tick up the jω axis. For a very large ω\omega the 1s hardly matter, and zz approaches jω/(−jω)=−1j\omega/(-j\omega)=-1. So the far end of the axis, infinity, lands at z=−1z=-1, which is fs/2f_s/2.

A Butterworth H(s)H(s) has only a constant on top, so its gain falls toward 0 as ω\omega grows without end. We say it has its zeros at infinity, one for each pole: four here. The map sends them to z=−1z=-1, the z+1z+1 in each factor above. So the digital gain is exactly 0 at fs/2f_s/2.

Where does a frequency in between land? The top, 1+jωTs/21+j\omega T_s/2, has the angle arctan⁡(ωTs/2)\arctan(\omega T_s/2). The bottom has the same angle with a minus sign. Dividing subtracts angles, so the angle of zz is twice that:

Ω=2arctan⁡ωTs2.\Omega=2\arctan\frac{\omega T_s}{2}.

This is warping. For a small number, arctan⁡\arctan hardly changes it, so at low frequencies Ω≈ωTs\Omega\approx\omega T_s, the Ω=2πf/fs\Omega=2\pi f/f_s of Frequency in discrete time (12.1). To get hertz back, multiply Ω\Omega by fs/(2π)f_s/(2\pi).

At fs=8f_s=8 kHz, analog 500 Hz lands at 493.7 Hz, only 1.3 % low. High frequencies are squeezed instead. Everything from analog 4 kHz up to infinity fits between 2556.4 Hz and 4 kHz.

Pre-warp, and the cutoff lands where you asked

Warping moves frequencies, but it keeps the gains. Put a point of the unit circle, z=ejΩz=e^{j\Omega}, into the transform. Multiplying the top and bottom by e−jΩ/2e^{-j\Omega/2} turns them into 2jsin⁡(Ω/2)2j\sin(\Omega/2) and 2cos⁡(Ω/2)2\cos(\Omega/2):

ejΩ−1ejΩ+1=jtan⁡Ω2.\frac{e^{j\Omega}-1}{e^{j\Omega}+1}=j\tan\frac{\Omega}{2}.

So the digital gain at Ω\Omega is the analog gain at ω=2Tstan⁡Ω2\omega=\frac{2}{T_s}\tan\frac{\Omega}{2}. Every value on the analog gain curve shows up on the digital one, at a moved frequency.

That is a problem for the cutoff. Design a Butterworth with its −3 dB point at 1000 Hz, map it, and the −3 dB point lands at 952.9 Hz. The fix is to aim off: ask where an analog frequency must be to land on the Ω\Omega we want.

The answer is the formula we just found, the landing formula turned round:

ωpw=2Tstan⁡Ω2.\omega_\text{pw}=\frac{2}{T_s}\tan\frac{\Omega}{2}.

Designing the analog filter at ωpw\omega_\text{pw} is pre-warping. For 1000 Hz at 8 kHz, Ω=2π⋅1000/8000=π/4\Omega=2\pi\cdot1000/8000=\pi/4, and ωpw=16 000tan⁡(π/8)=6627.4\omega_\text{pw}=16\,000\tan(\pi/8)=6627.4 rad/s, which is 1054.8 Hz. That is the odd cutoff of the first instrument.

The instrument below designs two filters for each wanted cutoff. One has its analog cutoff set to the wanted one; the other has it pre-warped. It is like aiming at a stone under water: you aim where the bent light says, not where the stone seems to be. Watch where the two curves cross −3 dB.

Pre-warp, and the cutoff lands where you asked

4th-order Butterworth filters at f_s = 8 kHz, analog cutoff set to the wanted one, or pre-warped.

Wanted: −3 dB at 1000 Hz. The rulers show the map: low frequencies barely move, high ones are squeezed toward 4 kHz.

wanted cutoff
1000 Hz
lands at, no pre-warp
not yet
analog, pre-warped
not yet
0.00 / 13.00 s
Describe this picture

Two stacked panels for 4th-order Butterworth filters at fs=8f_s=8 kHz, with the analog cutoff set to the wanted one, or pre-warped. The first, “where frequencies land”, has two rulers, analog from 0 to 16 000 Hz and digital from 0 to 4000 Hz. Thin lines join 0, 1000, 2000, 4000, 8000 and 16 000 Hz on the analog ruler to where they land. A bold line runs from the pre-warped analog cutoff to the wanted one, and a dashed line from the wanted frequency to where it lands without pre-warping. The second plots the gain from −40 to 5 dB against frequency from 0 to 4000 Hz: the design without pre-warping is a dashed curve and the pre-warped one is solid. A dotted vertical marks the wanted cutoff, and a dotted level marks −3 dB; a ring marks where the dashed curve crosses −3 dB, and a dot where the solid one does. The readouts are the wanted cutoff, where it lands without pre-warping, and the pre-warped analog cutoff.

The clip lasts 13 s. First only the rulers are drawn: low frequencies barely move, and high ones are squeezed toward 4 kHz. Then the dashed curve draws, and after it the solid one. At 4.5 s the filter designed at 1000 Hz lands at 952.9 Hz, and the one designed at the pre-warped 1054.8 Hz lands exactly on 1000 Hz. From 5 s to 8 s the wanted cutoff eases up to 3000 Hz. At the end, without pre-warping it lands at 2207.8 Hz, 792 Hz low; pre-warped to 6147.7 Hz, the analog filter lands on 3000 Hz. After the clip the wanted line is a handle named “Wanted cutoff”, from 100 to 3800 Hz in steps of 50 Hz, with a value like “3000 Hz: lands at 2207.8 Hz without pre-warping”. The arrow keys move it by 50 Hz, Page Up and Page Down by 500 Hz, and Home and End jump to 100 and 3800 Hz. At 1000 and 3000 Hz the clip’s captions come back. The position is kept in the link, as prewarp.f.

Notice how the miss grows with the cutoff: 47 Hz at 1000 Hz, but 792 Hz at 3000 Hz. The squeeze is strongest near fs/2f_s/2, so a high cutoff moves furthest.

After the clip, drag the wanted line, or use the arrow keys, to move the wanted cutoff yourself. At 2000 Hz the plain design lands at 1695.4 Hz, and the pre-warped analog cutoff is 2546.5 Hz. Try 3500 Hz: the plain design lands at 2398.3 Hz, and the analog filter has to sit at 12 802.0 Hz. Then try 100 Hz, where the two designs nearly agree.

Pre-warping puts one frequency where you want it, and the rest of the curve still warps around it. For a low-pass that frequency is the cutoff. For a spec with two edges, you pre-warp both, as the worked example does.

The complete design

Now let’s design a whole filter by hand: a 4th-order Butterworth low-pass, −3 dB at 1 kHz, with fs=8f_s=8 kHz. There are four steps.

  1. Pre-warp. ωpw=2⋅8000tan⁡(π/8)=6627.4\omega_\text{pw}=2\cdot8000\tan(\pi/8)=6627.4 rad/s.
  2. Place the analog poles. 20.1’s Butterworth poles are pk=ωcejπ(2k+N+1)/(2N)p_k=\omega_ce^{j\pi(2k+N+1)/(2N)} for k=0k=0 to N−1N-1. With ωc=ωpw\omega_c=\omega_\text{pw} and N=4N=4, their angles are 112.5°, 157.5°, 202.5° and 247.5°.
  3. Map. Send each pole to (1+pkTs/2)/(1−pkTs/2)(1+p_kT_s/2)/(1-p_kT_s/2), and the four zeros at infinity to z=−1z=-1.
  4. Set the gain. Choose the constant in front so that H(1)=1H(1)=1. The point z=1z=1 is Ω=0\Omega=0, so the gain at 0 Hz is 1.

The poles land at 0.7577∠±42.73°0.7577\angle\pm42.73° and 0.4579∠±20.94°0.4579\angle\pm20.94°. All four zeros sit at −1-1, so the top of H(z)H(z) is a constant KK times (1+z−1)4(1+z^{-1})^4, and bkb_k is KK times 1, 4, 6, 4, 1. Step 4 gives K=0.01021K=0.01021.

Multiplying out the bottom gives the aka_k. Here are both, as the coefficients of H(z)H(z) in powers of z−1z^{-1}, with a0=1a_0=1:

Delay (samples)Top coefficientBottom coefficient
00.010211
10.04084−1.96843
20.061261.73586
30.04084−0.72447
40.010210.12039

These are SciPy’s butter(4, 1000, fs=8000) to every digit shown. The bottom has aka_k beyond a0a_0, so the output feeds back on itself and the impulse response never quite ends: this is an IIR filter. butter with fs does all four steps for you.

Now the running spec of Filter specifications (18.1): the pass band to 1 kHz within ±0.05, the stop band from 1.5 kHz at 40 dB. A Butterworth peaks at gain 1, so the pass band allows a loss of −20log⁡100.95=0.4455-20\log_{10}0.95=0.4455 dB.

buttord(1000, 1500, 0.4455, 40, fs=8000) pre-warps both edges and returns order 12, with −3 dB at 1086.2 Hz. That design has gain 0.950 at 1 kHz, right on the limit, and −40.18 dB at 1.5 kHz. Its twelve poles sit at radii from 0.381 to 0.906.

Twelve poles is a lot to run in one piece. Second-order sections (21.2) shows how to run it safely.

Worked example

Let’s check the page’s numbers, by hand where we can and with SciPy where we can’t. Everything is at fs=8f_s=8 kHz, so 2/Ts=16 0002/T_s=16\,000 per second.

1. Where frequencies land. Use Ω=2arctan⁡(ωTs/2)\Omega=2\arctan(\omega T_s/2), then multiply by fs/(2π)f_s/(2\pi) for hertz. For 1000 Hz, ωTs/2=π⋅1000/8000=0.3927\omega T_s/2=\pi\cdot1000/8000=0.3927, and 2arctan⁡(0.3927)=0.74872\arctan(0.3927)=0.7487 rad/sample, which is 952.88 Hz.

Analog (Hz)Lands at (Hz)
500493.72
1000952.88
20001695.38
40002556.37
80003215.25
16 0003598.09

2. One pole by hand. The first analog pole is 6627.4 ej112.5°=−2536.2+6122.9j6627.4\,e^{j112.5°}=-2536.2+6122.9j rad/s. Times Ts/2T_s/2 it is −0.15851+0.38268j-0.15851+0.38268j, of length tan⁡(π/8)=0.41421\tan(\pi/8)=0.41421.

The top is 1+(−0.15851+0.38268j)=0.84149+0.38268j1+(-0.15851+0.38268j)=0.84149+0.38268j, of length 0.92442 and angle 24.45°. The bottom is 1.15851−0.38268j1.15851-0.38268j, of length 1.22008 and angle −18.28°.

Dividing, the length is 0.92442/1.22008=0.757670.92442/1.22008=0.75767 and the angle is 24.45°+18.28°=42.73°24.45°+18.28°=42.73°. That is SciPy’s pole.

3. Back from z to s. Which analog frequency lands on z=jz=j, a quarter of the way round, fs/4=2000f_s/4=2000 Hz? Put z=jz=j into the transform: (j−1)/(j+1)=j(j-1)/(j+1)=j, so s=16 000js=16\,000j. That is 16 000 rad/s, or 2546.5 Hz, the pre-warped value for 2000 Hz in the second instrument.

4. The gain of the 4th-order design. At 0, 500, 1000, 1500 and 2000 Hz it is 0, −0.012, −3.010, −16.707 and −30.626 dB. The −3.010 dB at 1000 Hz is where we asked for it.

5. The order for the running spec, by hand. Pre-warp both edges: 1000 Hz gives 6627.4 rad/s and 1500 Hz gives 10 690.9 rad/s, a ratio of 1.6131.

20.1’s Butterworth gain satisfies 1/∣H∣2=1+(ω/ωc)2N1/\lvert H\rvert^2=1+(\omega/\omega_c)^{2N}. The pass edge needs 1/∣H∣2≤1/0.9521/\lvert H\rvert^2\le1/0.95^2, so (ω/ωc)2N≤0.10803(\omega/\omega_c)^{2N}\le0.10803 there. The stop edge needs gain at most 0.01, so (ω/ωc)2N≥9999(\omega/\omega_c)^{2N}\ge9999 there.

Divide the two conditions: the ratio of the edges, 1.6131, raised to 2N2N, must reach 9999/0.10803=92 5559999/0.10803=92\,555. Taking logarithms, 2N≥4.9664/0.207672N\ge4.9664/0.20767, so N≥11.96N\ge11.96 and the order is 12, as buttord said.

Where you’ll meet this

The bilinear transform is the standard way to turn an analog design into code. SciPy’s butter, cheby1, cheby2 and ellip use it for every digital design, and bilinear and bilinear_zpk do the map on its own. MATLAB’s design functions work the same way.

It is also how analog circuits become software: guitar tone stacks, synthesiser filters and old equalisers are modelled by writing down the circuit’s H(s)H(s) and mapping it. Audio equalisers and biquads (20.5) builds the standard equaliser filters this way.

There is another way to sample an analog filter, Impulse invariance (20.3). High-pass, band-pass and band-stop shapes come from the same low-pass prototypes in Frequency transformations (20.4). Whether an IIR filter is the right choice at all is Choosing FIR or IIR (20.6).

The maths behind it · the trapezoidal rule

The bilinear transform is the trapezoidal rule for integrating a differential equation, the same rule used to integrate a density numerically. It keeps stability where the simple forward-difference rule does not.

Reference card

QuantityFormulaNotes
Bilinear transforms=2Tsz−1z+1s=\dfrac{2}{T_s}\dfrac{z-1}{z+1}, z=1+sTs/21−sTs/2z=\dfrac{1+sT_s/2}{1-sT_s/2}same order; jω axis → unit circle once
WarpingΩ=2arctan⁡(ωTs/2)\Omega=2\arctan(\omega T_s/2)∞ lands at π\pi
Pre-warpingωpw=2Tstan⁡Ω2\omega_\text{pw}=\dfrac{2}{T_s}\tan\dfrac{\Omega}{2}design the analog filter here
Stabilityleft half-plane → inside the circlestable stays stable
Zeros at infinityland at z=−1z=-1gain 0 at fs/2f_s/2
Design stepspre-warp, analog prototype, map, set the gainbutter(N, fc, fs=...)

End of lesson 20.2

Where to go next.

Phasorium
LibraryEvery lesson, in order

Parts

About Phasorium
Look