Skip to content

Frequency transformations

Turn one low-pass prototype into a high-pass, band-pass or band-stop by substitution, and retune a digital low-pass with one all-pass number.

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

First, the picture

One low-pass design can be turned into a high-pass, a band-pass or a band-stop. Below, an order-3 Butterworth takes the four shapes in turn. Watch the zeros, the open circles, more than the poles.

One prototype, four shapes

An order-3 Butterworth at f_s = 8 kHz: low-pass and high-pass at 1 kHz, band-pass and band-stop from 1 to 2 kHz.

Low-pass, 1 kHz: three poles, and a triple zero at z = −1 that makes the gain 0 at 4 kHz.

shape
low-pass
poles
3
zeros at
z = −1
Shape
0.00 / 16.00 s
Describe this picture

Two panels for an order-3 Butterworth at fs=8f_s=8 kHz: low-pass and high-pass at 1 kHz, band-pass and band-stop from 1 to 2 kHz. The plane has the real part across and the imaginary part up, both from −1.2 to 1.2, and always shows the unit circle. Poles are crosses and zeros are open circles; a repeated zero carries its count beside it, such as “○3”. The gain panel plots the gain from −60 to 5 dB against frequency from 0 to 4000 Hz as a solid curve, with dotted verticals at 1000 and 2000 Hz. The readouts are the shape, the number of poles and where the zeros are.

The clip lasts 16 s, with a blank caption while the picture moves. The low-pass at 1 kHz has three poles and a triple zero at z=−1z=-1 that makes the gain 0 at 4 kHz. The triple zero slides round the circle to z=1z=1, and at 5.5 s the high-pass has the same three poles, with 0 Hz now blocked. Then each pole splits into two and moves, and three of the zeros return to −1. At 10 s the band-pass has six poles near the band, and three zeros at z=1z=1 and three at z=−1z=-1 block both ends. Then the zeros slide along the circle to ±65.5°. At the end the band-stop has the same six poles and all six zeros on the circle at ±65.5°, the band’s centre, 1456 Hz, where the gain falls below −60 dB. After the clip four buttons in a group named “Shape” choose a shape; choosing one plays the move to it, and the choice is kept in the link, as types.s.

One prototype, four shapes

In Filter specifications (18.1) a spec came in four shapes: low-pass, high-pass, band-pass and band-stop. Analog prototype filters (20.1) gave us only low-passes. IIR design by the bilinear transform (20.2) turned them into digital filters. So where do the other three shapes come from?

I don’t design them from scratch. I take the low-pass and replace its variable by something else, and that move is called a frequency transformation. Think of one stencil: flip it, or repeat it, and the same cut-out makes new patterns.

Analog and digital frequencies meet again on this page, so here are the letters once more. Analog frequency is ω\omega (rad/s), digital frequency is Ω\Omega (rad/sample); Oppenheim and Schafer use the opposite letters.

Start from 20.1’s analog Butterworth prototype, the low-pass with its cutoff at 1 rad/s. Its squared gain is ∣H(jω)∣2=1/(1+ω2N)\lvert H(j\omega)\rvert^2=1/(1+\omega^{2N}), and its NN poles sit evenly on the left half of the unit circle. For N=3N=3 they are −0.5±j0.866-0.5\pm j0.866 and −1-1.

Four substitutions

The low-pass is the plainest case. Replace every ss by s/ωcs/\omega_c. The new filter does at ω\omega what the prototype did at ω/ωc\omega/\omega_c, so the cutoff moves from 1 rad/s to ωc\omega_c.

For a high-pass, replace ss by ωc/s\omega_c/s. At low frequencies ωc/(jω)\omega_c/(j\omega) is large, so the filter acts like the prototype’s stop band. At high frequencies it is small, like the prototype’s pass band. At ω=ωc\omega=\omega_c it equals −j-j, of size 1, so that is the cutoff, at −3 dB.

A band-pass from ω1\omega_1 to ω2\omega_2 needs a substitution with its own centre, ω0\omega_0, and width, BW\mathrm{BW}:

s→s2+ω02s BW,ω0=ω1ω2,BW=ω2−ω1.\begin{aligned} s&\to\frac{s^2+\omega_0^2}{s\,\mathrm{BW}},\\ \omega_0&=\sqrt{\omega_1\omega_2},\qquad\mathrm{BW}=\omega_2-\omega_1. \end{aligned}

On the axis, s=jωs=j\omega becomes −j(ω02−ω2)/(ω BW)-j(\omega_0^2-\omega^2)/(\omega\,\mathrm{BW}). At ω=ω0\omega=\omega_0 that is 0, the prototype’s zero frequency, so the band’s centre passes. Near 0 and far above the band it is large, which is the prototype’s stop band. At ω1\omega_1 and at ω2\omega_2 its size is 1, so both edges sit at −3 dB.

A band-stop uses the reciprocal, s→s BW/(s2+ω02)s\to s\,\mathrm{BW}/(s^2+\omega_0^2). Now the band’s centre goes where the prototype’s frequency is infinite, deep in its stop band, and both far ends pass.

Each band substitution is quadratic in ss. A prototype pole pp becomes the two roots of s2−p BW s+ω02=0s^2-p\,\mathrm{BW}\,s+\omega_0^2=0, so each pole becomes two. An order-3 prototype gives an order-6 band filter.

The digital design adds 20.2’s two steps. Pre-warp the edges with ωpw=2Tstan⁡Ω2\omega_\text{pw}=\frac2{T_s}\tan\frac\Omega2, substitute, and map with the bilinear transform. SciPy does all of it in one call, such as butter(3, 1000, btype='high', fs=8000).

The picture at the top of the page shows the four results in the z-plane, where the filter is used. Watch where the poles, drawn as crosses, and the zeros, drawn as open circles, go.

After the clip, choose a shape with its button to play the move to it again. Notice that both band filters have six poles, twice the prototype’s three.

Why the poles stay where they are

The high-pass surprised me the first time I drew it: its poles are the low-pass’s poles. The prototype’s poles lie on the unit circle, where 1/p=p∗1/p=p^*. So the high-pass substitution sends a pole pp to ωc/p=ωc p∗\omega_c/p=\omega_c\,p^*. That is the low-pass pole ωc p\omega_c\,p reflected across the real axis, and poles come in such pairs, so the set does not change.

The zeros are what moves. The prototype has no zeros at finite ss, but its gain falls like 1/ω31/\omega^3 as ω\omega grows: three zeros “at infinity”. By 20.2 the bilinear map lands those at z=−1z=-1, which is why the low-pass’s gain is 0 at 4 kHz. The high-pass substitution swaps 0 and infinity, so its three zeros sit at s=0s=0, which the map sends to z=1z=1.

The band-pass substitution is infinite both at s=0s=0 and at infinity. So its six zeros split three and three: three at z=1z=1 and three at z=−1z=-1, blocking both ends. The band-stop substitution is infinite at s=±jω0s=\pm j\omega_0, so its zeros sit there, three on each, and the map puts them on the unit circle at the band’s centre. By the same 1/p=p∗1/p=p^* argument, its poles are the band-pass’s poles.

On the circle, the band’s centre is not 1500 Hz, the middle of 1000 and 2000 Hz. The pre-warp bends the axis, and the centre lands at 1456 Hz. The worked example below does the arithmetic.

The maths behind it · changes of variable

Each substitution is a change of variable, and changes of variable compose like functions. A low-pass to band-pass transformation is the low-pass composed with a degree-2 map, so the order doubles. Composing polynomials multiplies their degrees in the same way.

One number retunes the filter

There is a second route. Instead of substituting for ss before the map, substitute for z−1z^{-1} after it. Use the first-order all-pass of All-pass systems (17.1), with a real number aa between −1 and 1:

z−1→z−1−a1−az−1.z^{-1}\to\frac{z^{-1}-a}{1-az^{-1}}.

Why an all-pass? By 17.1 it has gain 1 at every frequency. So when z−1=e−jΩz^{-1}=e^{-j\Omega}, it gives back another point on the circle, which I’ll write e−jθe^{-j\theta}. The new filter at Ω\Omega then gives what the old one gave at θ\theta.

The gain keeps its values; they only move along the frequency axis. As Ω\Omega runs from 0 to π\pi, θ\theta also runs from 0 to π\pi, always climbing, so nothing is folded or repeated.

Constantinides worked out an all-pass for each shape, and Oppenheim and Schafer print his table in their chapter 7. For the band shapes it is a second-order all-pass, so the order doubles there too. To move a low-pass’s cutoff, the first-order one above is enough, and it needs one number, aa.

The tuning constant

Let’s find aa. I want the new cutoff Ωnew\Omega_\text{new} to land on the old cutoff Ωc\Omega_c:

e−jΩc=e−jΩnew−a1−a e−jΩnew.e^{-j\Omega_c}=\frac{e^{-j\Omega_\text{new}}-a}{1-a\,e^{-j\Omega_\text{new}}}.

Multiply out and collect the terms with aa. Then take half of each angle out of the top and the bottom, and use ejx−e−jx=2jsin⁡xe^{jx}-e^{-jx}=2j\sin x from Complex exponentials & phasors (3.4). That gives the tuning constant:

a=e−jΩnew−e−jΩc1−e−j(Ωc+Ωnew)=sin⁡((Ωc−Ωnew)/2)sin⁡((Ωc+Ωnew)/2).\begin{aligned} a&=\frac{e^{-j\Omega_\text{new}}-e^{-j\Omega_c}}{1-e^{-j(\Omega_c+\Omega_\text{new})}}\\ &=\frac{\sin\big((\Omega_c-\Omega_\text{new})/2\big)}{\sin\big((\Omega_c+\Omega_\text{new})/2\big)}. \end{aligned}

A lower cutoff gives a positive aa and a higher one a negative aa. With no change, a=0a=0 and the all-pass is z−1z^{-1} itself.

Each pole and zero moves too. Put the all-pass into a factor 1−rz−11-rz^{-1} of 16.3’s factored form, and the root rr goes to (r+a)/(1+ar)(r+a)/(1+ar). A zero at −1-1 goes to (−1+a)/(1−a)=−1(-1+a)/(1-a)=-1, so it stays, and the gain at 4 kHz stays 0.

The instrument below applies this to the 1 kHz low-pass of the first instrument. Think of a synthesiser’s cutoff knob: you turn one thing, and the whole filter follows. Watch the poles slide together while the curve keeps its shape.

One number retunes the filter

The order-3 Butterworth low-pass at 1 kHz, every z⁻¹ replaced by (z⁻¹ − a)/(1 − az⁻¹).

Cutoff 1 kHz, a = 0: nothing is substituted yet.

cutoff
1000 Hz
a
0.0000
0.00 / 13.00 s
Describe this picture

The same two panels as the first instrument, the plane and the gain, for the order-3 Butterworth low-pass at 1 kHz with every z−1z^{-1} replaced by (z−1−a)/(1−az−1)(z^{-1}-a)/(1-az^{-1}). The 1 kHz design’s poles stay in the plane as faint crosses for reference, and a dotted path shows how far each pole has travelled. The readouts are the cutoff and aa. Every frame is the design at the current cutoff, on a 10 Hz grid, so the picture and the readouts follow the cutoff as it moves.

The clip lasts 13 s. It starts at a cutoff of 1 kHz with a=0a=0: nothing is substituted yet. The cutoff eases down to 500 Hz, and all three poles slide together. At 5.5 s, a=0.3512a=0.3512: the poles have moved toward z=1z=1, and the curve has kept its shape. Then the cutoff eases up to 2000 Hz. At the end a=−0.4142a=-0.4142: the real pole has reached the centre and the pair sits at ±90°, and the caption adds that each frame is exactly the Butterworth design at that cutoff. After the clip the gain curve’s −3 dB point is a handle, a ring on the curve named “Cutoff”, from 100 to 3900 Hz in steps of 10 Hz, with a value like “2000 Hz, a = −0.4142”. The arrow keys move it by 10 Hz, Page Up and Page Down by 250 Hz, and Home and End jump to 100 and 3900 Hz. At 1000, 500 and 2000 Hz the caption is the clip’s own; elsewhere it reads like “Cutoff 3000 Hz: a = −0.7071.” The position is kept in the link, as tune.f.

Notice where the real pole goes at 2 kHz. There a=1−2=−0.4142a=1-\sqrt2=-0.4142 and the old real pole is 2−1=0.4142\sqrt2-1=0.4142, so r+a=0r+a=0: the pole sits at the centre of the circle.

After the clip, drag the ring at the −3 dB point along the curve, or use the arrow keys, to retune the cutoff yourself. Try 100 Hz: aa climbs to 0.8267 and all three poles crowd near z=1z=1. Then try 3900 Hz, where a=−0.9680a=-0.9680 and the poles crowd near z=−1z=-1.

The same Butterworth either way

Is the retuned filter a real Butterworth, or only an imitation? Here it is the real thing. The all-pass multiplies every pre-warped frequency tan⁡(Ω/2)\tan(\Omega/2) by the same number, tan⁡(Ωc/2)/tan⁡(Ωnew/2)\tan(\Omega_c/2)/\tan(\Omega_\text{new}/2), which is the analog step s→s/ωcs\to s/\omega_c in disguise.

A Butterworth’s gain depends only on ω/ωc\omega/\omega_c. So the analog route and the digital route give the same filter: SciPy’s butter(3, f, fs=8000) at the new cutoff. This holds for every low-pass made by the bilinear map, which is why the reference card says “exact for bilinear designs”.

The maths behind it · changes of scale

Changing a random variable’s scale, such as putting a skewed quantity on a log scale, warps the axis and keeps the probabilities. The all-pass does the same to a filter: it keeps the gain’s values and only moves the frequencies they sit at.

Worked example

Let’s redo the page’s numbers. All three designs are order-3 Butterworths at fs=8f_s=8 kHz, so ωpw=2fstan⁡(Ω/2)=16 000tan⁡(Ω/2)\omega_\text{pw}=2f_s\tan(\Omega/2)=16\,000\tan(\Omega/2) rad/s.

1. High-pass from low-pass, 1 kHz. butter(3, 1000, fs=8000) has poles 0.6911∠±40.89°0.6911\angle{\pm40.89°}, that is ±0.7137\pm0.7137 rad, and 0.41420.4142. Its three zeros sit at −1-1. The high-pass has the same poles, and its zeros move to 11.

What changes besides the zeros is the gain constant KK of 16.3’s factored form. It is set so that the pass band has gain 1. For the low-pass, at z=1z=1, K⋅23/∏(1−pk)=1K\cdot2^3/\prod(1-p_k)=1 gives K=0.2535/8=0.031689K=0.2535/8=0.031689. For the high-pass, at z=−1z=-1, K=∏(1+pk)/8=3.5672/8=0.445903K=\prod(1+p_k)/8=3.5672/8=0.445903.

2. Band-pass, 1 to 2 kHz. The edges are Ω1=2π⋅1000/8000=π/4\Omega_1=2\pi\cdot1000/8000=\pi/4 and Ω2=π/2\Omega_2=\pi/2. Pre-warped, they become ω1=16 000tan⁡(π/8)=6627.4\omega_1=16\,000\tan(\pi/8)=6627.4 rad/s and ω2=16 000tan⁡(π/4)=16 000.0\omega_2=16\,000\tan(\pi/4)=16\,000.0 rad/s.

So the centre is ω0=6627.4⋅16 000=10 297.5\omega_0=\sqrt{6627.4\cdot16\,000}=10\,297.5 rad/s, and the width is BW=9372.6\mathrm{BW}=9372.6 rad/s. The map sends the centre to Ω0=2arctan⁡(10 297.5/16 000)=1.1437\Omega_0=2\arctan(10\,297.5/16\,000)=1.1437 rad, which is 65.53°65.53° or 1456.2 Hz.

The six poles are 0.8560∠±46.31°0.8560\angle{\pm46.31°}, 0.8073∠±87.21°0.8073\angle{\pm87.21°} and 0.6436∠±62.93°0.6436\angle{\pm62.93°}. The prototype’s real pole −1-1 gives the last pair. The band-stop has the same poles, and its zeros are e±j65.53°e^{\pm j65.53°}, three each. Its gain is −65.7 dB at 1000⋅2000=1414.2\sqrt{1000\cdot2000}=1414.2 Hz, and the gain itself is zero at 1456.2 Hz.

3. The tuning table. For 500 Hz, Ωc=π/4\Omega_c=\pi/4 and Ωnew=π/8\Omega_\text{new}=\pi/8, so a=sin⁡(π/16)/sin⁡(3π/16)=0.19509/0.55557=0.3512a=\sin(\pi/16)/\sin(3\pi/16)=0.19509/0.55557=0.3512. The table gives aa for eight cutoffs.

New cutoff (Hz)Tuning constant aa
1000.8267
2500.6158
5000.3512
10000
1500−0.2346
2000−0.4142
3000−0.7071
3900−0.9680

At 3000 Hz the poles are 0.6911∠±139.11°0.6911\angle{\pm139.11°} and −0.4142-0.4142. These are the 1 kHz poles reflected across the imaginary axis: 180°−40.89°=139.11°180°-40.89°=139.11°, and 0.41420.4142 becomes −0.4142-0.4142.

Where you’ll meet this

A tunable filter has to follow a knob quickly: the cutoff of a synthesiser’s filter, or a band of a tunable equaliser. With the all-pass substitution the knob sets one number, aa, and the new coefficients follow from it without a new design. Audio equalisers and biquads (20.5) builds the equaliser shapes from second-order filters.

In SciPy the analog route sits behind the btype argument. butter(3, [1000, 2000], btype='bandpass', fs=8000) pre-warps the edges, substitutes into the prototype and applies the bilinear map, as above. Band-pass filters of this kind split a signal into bands in Filter banks (23.1).

Reference card

TransformationAnalog substitutionResult
Low-pass, new cutoffs→s/ωcs\to s/\omega_csame order
High-passs→ωc/ss\to\omega_c/szeros at 0 (z = 1)
Band-passs→s2+ω02s BWs\to\dfrac{s^2+\omega_0^2}{s\,\mathrm{BW}}, ω0=ω1ω2\omega_0=\sqrt{\omega_1\omega_2}twice the order
Band-stops→s BWs2+ω02s\to\dfrac{s\,\mathrm{BW}}{s^2+\omega_0^2}zeros at ±jω0\pm j\omega_0
Digital retunez−1→z−1−a1−az−1z^{-1}\to\dfrac{z^{-1}-a}{1-az^{-1}}, a=sin⁡((Ωc−Ωnew)/2)sin⁡((Ωc+Ωnew)/2)a=\dfrac{\sin((\Omega_c-\Omega_\text{new})/2)}{\sin((\Omega_c+\Omega_\text{new})/2)}exact for bilinear designs
Roots under the retuner→r+a1+arr\to\dfrac{r+a}{1+ar}a zero at −1-1 stays

End of lesson 20.4

Where to go next.

Phasorium
LibraryEvery lesson, in order

Parts

About Phasorium
Look