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.
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 kHz. The s-plane is scaled by , moved right by 1, then mapped by . 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 . 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 , the analog cutoff 1054.8 Hz at 1000 Hz, 16 kHz at 3598 Hz, and infinity at . 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 , made for circuits. On this page I turn one into an , a digital filter that runs as code.
Analog and digital frequency meet on this page, so first a word on letters. Analog frequency is (rad/s), digital frequency is (rad/sample); Oppenheim and Schafer use the opposite letters.
An analog filter is a ratio of two polynomials in . So here is the plan: replace every by an expression in , and the ratio becomes one in . The replacement I’ll use is the bilinear transform:
Here is the sample period. The name says that the top and the bottom are both of first degree, linear, in .
Does the order of the filter change? Take one pole of the analog filter. Its factor turns into
So each analog pole gives one digital pole and one zero at . A filter of order stays a filter of order .
Where does a point land? Solve the transform for :
Put in a point of the jω axis, . The top is and the bottom is . They are mirror images, so they have the same length, and . The whole jω axis lands on the unit circle.
The z-transform (16.1) had another map, . It wraps the jω axis round the circle again and again, once every rad/s, and that is aliasing. The bilinear map goes round once.
Now the left half-plane. The top, , is the distance from the point to , and the bottom is its distance to . A point left of the vertical axis is closer to , so .
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 and moved right by 1, which is the top of the fraction, . There the jω axis is the vertical line through 1. Then the division by is faded in, and the line bends into the circle.
The filter on show is a 4th-order Butterworth at 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 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 on the point . Its top row gives the numerator , its bottom row the denominator . 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 the 1s hardly matter, and approaches . So the far end of the axis, infinity, lands at , which is .
A Butterworth has only a constant on top, so its gain falls toward 0 as grows without end. We say it has its zeros at infinity, one for each pole: four here. The map sends them to , the in each factor above. So the digital gain is exactly 0 at .
Where does a frequency in between land? The top, , has the angle . The bottom has the same angle with a minus sign. Dividing subtracts angles, so the angle of is twice that:
This is warping. For a small number, hardly changes it, so at low frequencies , the of Frequency in discrete time (12.1). To get hertz back, multiply by .
At 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, , into the transform. Multiplying the top and bottom by turns them into and :
So the digital gain at is the analog gain at . 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 we want.
The answer is the formula we just found, the landing formula turned round:
Designing the analog filter at is pre-warping. For 1000 Hz at 8 kHz, , and 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.
Describe this picture
Two stacked panels for 4th-order Butterworth filters at 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 , 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 kHz. There are four steps.
- Pre-warp. rad/s.
- Place the analog poles. 20.1’s Butterworth poles are for to . With and , their angles are 112.5°, 157.5°, 202.5° and 247.5°.
- Map. Send each pole to , and the four zeros at infinity to .
- Set the gain. Choose the constant in front so that . The point is , so the gain at 0 Hz is 1.
The poles land at and . All four zeros sit at , so the top of is a constant times , and is times 1, 4, 6, 4, 1. Step 4 gives .
Multiplying out the bottom gives the . Here are both, as the coefficients of in powers of , with :
| Delay (samples) | Top coefficient | Bottom coefficient |
|---|---|---|
| 0 | 0.01021 | 1 |
| 1 | 0.04084 | −1.96843 |
| 2 | 0.06126 | 1.73586 |
| 3 | 0.04084 | −0.72447 |
| 4 | 0.01021 | 0.12039 |
These are SciPy’s butter(4, 1000, fs=8000) to every digit shown. The bottom has beyond , 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 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 kHz, so per second.
1. Where frequencies land. Use , then multiply by for hertz. For 1000 Hz, , and rad/sample, which is 952.88 Hz.
| Analog (Hz) | Lands at (Hz) |
|---|---|
| 500 | 493.72 |
| 1000 | 952.88 |
| 2000 | 1695.38 |
| 4000 | 2556.37 |
| 8000 | 3215.25 |
| 16 000 | 3598.09 |
2. One pole by hand. The first analog pole is rad/s. Times it is , of length .
The top is , of length 0.92442 and angle 24.45°. The bottom is , of length 1.22008 and angle −18.28°.
Dividing, the length is and the angle is . That is SciPy’s pole.
3. Back from z to s. Which analog frequency lands on , a quarter of the way round, Hz? Put into the transform: , so . 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 . The pass edge needs , so there. The stop edge needs gain at most 0.01, so there.
Divide the two conditions: the ratio of the edges, 1.6131, raised to , must reach . Taking logarithms, , so 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 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
| Quantity | Formula | Notes |
|---|---|---|
| Bilinear transform | , | same order; jω axis → unit circle once |
| Warping | ∞ lands at | |
| Pre-warping | design the analog filter here | |
| Stability | left half-plane → inside the circle | stable stays stable |
| Zeros at infinity | land at | gain 0 at |
| Design steps | pre-warp, analog prototype, map, set the gain | butter(N, fc, fs=...) |