Filters are the scissors of signal processing — they cut unwanted frequencies with surgical precision. Learn to design FIR and IIR filters, read Bode plots, and choose the right tool for any application.
Intuition
Every real-world signal arrives contaminated — power-line hum, sensor noise, out-of-band interference. This section defines the general difference equation that unifies FIR and IIR filters, maps the four fundamental filter types (LP/HP/BP/BS), and explains why frequency-selective processing is indispensable before any signal reaches a model or algorithm.
Imagine trying to hear a whispered conversation across a noisy café. Your brain automatically filters out background chatter and focuses on the voice in front of you. Now imagine doing the same thing for an ECG signal buried in 60 Hz power-line hum — that's exactly what a digital filter does, one sample at a time.
A digital filter is like a coffee filter: you pour in a mixture (signal + noise), and it lets exactly the good stuff pass through while blocking what you don't want. The filter shape (LP/HP/BP/BS) is the mesh size — you choose how fine or coarse to make it. Just as a finer mesh catches smaller grounds, a steeper filter cuts closer to the signal of interest.
A digital filter is a discrete-time system that shapes the frequency content of a signal. Given input $x[n]$, it produces output $y[n]$ by computing a weighted sum of past inputs and — optionally — past outputs.
Every digital filter — no matter how complex — fits one equation:
$$y[n] = \sum_{k=0}^{M} b_k\,x[n-k] \;-\; \sum_{k=1}^{N} a_k\,y[n-k]$$
Big picture first. The difference equation is a recipe: to compute today's output, average recent inputs ($b_k$ terms) and optionally mix in recent outputs ($a_k$ feedback). A 3-sample average is already a working lowpass filter — and it fits this equation exactly.
Problem: FIR: $b_0=b_1=b_2=\tfrac{1}{3}$, all $a_k=0$, input $x=[1,2,4,1,0,\ldots]$. Compute $y[0]$, $y[1]$, $y[2]$. Then contrast with IIR: $b_0=0.1$, $a_1=-0.9$, input $x=[1,0,0,\ldots]$ (impulse).
For the same FIR filter ($b_0=b_1=b_2=\tfrac{1}{3}$), what is $y[3]$ if $x=[1,2,4,1,0,\ldots]$?
FIR (top): feedforward only — output depends only on current and past inputs. IIR (bottom): recursive — output feeds back, creating infinite impulse response.
| Property | FIR | IIR |
|---|---|---|
| Impulse response | Finite (M+1 samples) | Infinite (decays forever) |
| Feedback | None ($a_k=0$) | Yes ($a_k \neq 0$) |
| Phase | Linear (symmetric $b_k$) | Nonlinear (variable delay) |
| Stability | Always stable | Depends on pole locations |
| Efficiency | High order for sharp cutoff | Low order → efficient |
Below is a composite signal: a 50 Hz tone you want to keep, plus a 350 Hz tone you want to remove. Before adjusting the lowpass cutoff — what frequency should the cutoff be set to in order to pass only 50 Hz?
Hint: the cutoff should be somewhere between 50 Hz and 350 Hz, closer to the lower tone.
A digital filter is fully described by one equation: $y[n]=\sum b_k x[n-k]-\sum a_k y[n-k]$ — when all $a_k=0$ you get FIR (stable, linear phase); when $a_k\neq0$ you get IIR (efficient, nonlinear phase).
Active Noise Cancellation (ANC) earbuds use a real-time digital filter to cancel ambient noise. A microphone captures the environment; a DSP chip runs a filter that produces an anti-noise signal $180°$ out of phase with the interference — cancelling it at the ear. The system must filter and respond within $\approx 10\ \text{ms}$ to stay phase-aligned; beyond that, the anti-noise arrives late and makes things worse. This tight latency constraint makes efficient IIR design (low order, low computational cost) essential for battery-powered devices.
Q1 A filter has $b_0=0.5$, $b_1=0.5$, and all $a_k=0$. Is it FIR or IIR? What is its impulse response?
Q2 You need a filter that removes a constant 0 Hz DC offset from a vibration signal while keeping all frequencies above 1 Hz. Which filter type (LP/HP/BP/BS) should you use?
Q3 A 3rd-order FIR filter processes 1000 samples per second. How many multiply-accumulate operations per second does it require?
Mechanics
FIR (Finite Impulse Response) filters have no feedback. Their impulse response has exactly $M+1$ non-zero samples. Symmetric coefficients guarantee linear phase — a critical property for audio, biomedical, and communication signal processing. This section covers the windowed-sinc design method and explains how the window function governs the trade-off between transition-band width and stopband attenuation.
Have you ever wondered why an EEG recording used to diagnose epilepsy can't just use any filter? The answer is phase. If different brain-wave frequencies arrive at the classifier with different time delays, the relative timing of ERP peaks shifts — and the diagnosis changes. FIR filters guarantee that every frequency is delayed by the exact same number of samples: no distortion, no diagnostic error.
The windowed-sinc method is like cutting a very long roll of fabric to a fixed length — the fabric is the infinite sinc function (ideal filter), the scissors are the window, and you choose how cleanly to cut based on how much fraying (sidelobe ripple) you can tolerate. A sharper cut (Rectangular window) frays more; a softer trim (Blackman window) frays less but uses more fabric (wider transition band).
The ideal lowpass filter has an infinite sinc impulse response. Multiplying by a window $w[n]$ truncates it to $M+1$ coefficients while controlling sidelobe behaviour.
$$h[n] = 2f_c \cdot \operatorname{sinc}\!\bigl(2f_c(n-M/2)\bigr) \cdot w[n], \quad n=0,\ldots,M$$
Where does this formula come from? The ideal LP filter passes all frequencies below $f_c$ with gain 1. Its impulse response is the inverse DTFT of a rectangular spectrum — a sinc function. Since sinc extends to infinity, we multiply by a window $w[n]$ to truncate it gracefully. The window shape determines the sidelobe level.
Problem: $M=8$, $f_c=0.25$ (quarter the sample rate). Use Hamming window: $w[n]=0.54-0.46\cos(2\pi n/M)$.
For the same filter ($M=8$, $f_c=0.25$, Hamming), what is $h[8]$ (the last tap)?
Rectangular: sharpest transition but −21 dB sidelobes (Gibbs ringing). Hamming: −53 dB — best for most audio. Blackman: −74 dB sidelobes but widest transition band. Sharper cutoff always costs higher order (more taps).
Symmetric windowed-sinc coefficients about $n=M/2$. Every frequency is delayed identically by $M/2$ samples — this is linear phase.
| Window | Sidelobe | Trans. Width |
|---|---|---|
| Rectangular | −21 dB | Narrowest (sharpest) |
| Hann | −44 dB | Wider |
| Hamming | −53 dB | Moderate — best all-round |
| Blackman | −74 dB | Widest (gentlest) |
If you switch from the Rectangular window to the Blackman window (with the same filter order M), the stopband attenuation will increase dramatically — but what do you predict will happen to the transition band width?
Hint: there is always a trade-off between how sharp the cutoff is and how low the sidelobes are.
FIR filters are designed by multiplying the infinite sinc function by a window: the window choice trades sidelobe attenuation (stopband suppression) against transition-band width — Hamming gives −53 dB attenuation and is the best all-round choice for most applications.
High-end studio monitor speakers use FIR-based linear-phase digital crossover filters to split the audio signal into bass, mid, and treble bands before routing each band to the appropriate driver (woofer, midrange, tweeter). The linear phase property guarantees perfect time-alignment: summing the three bands reconstructs the original signal without phase-induced comb filtering. Analog IIR crossovers introduce frequency-dependent delays at the crossover region — a colouration that trained ears can detect and that shifts the perceived stereo image. Recording engineers routinely verify linear phase with swept-sine group delay measurements before signing off on a monitor calibration.
Q1 An FIR filter has order $M=10$. What is the group delay in samples, and why is it constant?
Q2 You need a filter to remove 50 Hz ECG muscle artifacts, preserving 0.5–45 Hz with ≥ 60 dB stopband attenuation. Which window should you use?
Q3 For $M=8$, $f_c=0.25$ (normalized), what is the center tap value $h[4]$ (Hamming window)?
Application
IIR filters use feedback to achieve steep roll-off with far fewer coefficients than FIR. This section covers the Butterworth maximally-flat design, pole-zero placement in the $z$-plane, why second-order sections (SOS) are mandatory for numerical safety, and how to read the three-panel Bode plot (magnitude, phase, group delay) that characterizes any LTI filter.
Imagine you need to separate a 100 Hz heartbeat from 60 Hz power-line interference using a chip running on a hearing-aid battery. Every multiply-accumulate operation costs energy. A 4th-order IIR Butterworth achieving −40 dB at twice the cutoff needs only 8 operations per sample. An FIR doing the same job needs 80+ taps — 10 times more. That energy difference can mean hours of battery life.
Poles and zeros in the $z$-plane are like magnets arranged around a circular track (the unit circle). A pole close to the track creates a strong resonance — it amplifies nearby frequencies. A zero on the track kills a specific frequency completely. As long as all poles stay inside the circle, the filter is stable; push a pole outside and the output grows without bound.
The Butterworth filter has a maximally flat magnitude response — no ripple in the passband or stopband. It is the standard starting point for IIR design.
The magnitude-squared response of an N-th order Butterworth filter is:
$$|H(j\Omega)|^2 = \frac{1}{1 + \left(\dfrac{\Omega}{\Omega_c}\right)^{2N}}$$
Digital design uses the bilinear transform with prewarping: $\Omega_c = \tan(\pi f_c/f_s)$ to map analog to digital exactly at $f_c$.
Why prewarp? The bilinear transform compresses the frequency axis nonlinearly. Prewarping guarantees the digital filter's −3 dB point lands exactly at the desired $f_c$.
Problem: 4th-order Butterworth LP, $f_c=150$ Hz, $f_s=1000$ Hz. Evaluate $|H(f)|$ in dB at (a) $f=150$ Hz and (b) $f=300$ Hz.
For the same N=4 Butterworth LP ($f_c=150$ Hz, $f_s=1000$ Hz), at $f=150$ Hz the gain is −3 dB. What is the gain in dB at $f=0$ Hz (DC)?
Never use scipy.signal.lfilter(b, a, x) for IIR filters of order > 5. Direct-form coefficients become numerically unstable due to floating-point cancellation. Always specify output='sos' and use sosfilt(). Second-order sections (SOS) cascade biquad sections — the industry-standard approach.
All four poles inside the unit circle → the filter is stable. Zeros at $z=-1$ create infinite attenuation at $f=f_s/2$ (Nyquist). The further a pole is from the unit circle, the faster the impulse response decays.
$$H(e^{j\omega}) = \sum_{n} h[n]\,e^{-j\omega n} = |H(e^{j\omega})|\,e^{\,j\angle H(e^{j\omega})}$$
Evaluate the $z$-transform on the unit circle ($z=e^{j\omega}$). Three key derived quantities:
Problem: 3-tap MA: $h=[\tfrac{1}{3},\tfrac{1}{3},\tfrac{1}{3}]$. Derive $H(e^{j\omega})$ and compute group delay.
At $\omega=2\pi/3$ ($f=f_s/3$), what is $|H(e^{j\omega})|$ for the 3-tap MA?
Below you can sweep the Butterworth filter order N from 1 to 10. Before you try it — at N=1 the roll-off is 20 dB/decade. What roll-off (in dB/decade) do you predict for N=4?
Hint: the roll-off rate formula is 20N dB/decade — you can compute this directly.
IIR Butterworth filters deliver $20N$ dB/decade roll-off with a maximally flat passband; always use output='sos' and sosfilt() to avoid numerical instability — direct $(b,a)$ form breaks for N>5 due to floating-point pole sensitivity near the unit circle.
Wearable ECG patches (Holter monitors, Apple Watch ECG) suffer from baseline wander — a slow drift below 0.5 Hz caused by patient movement and electrode impedance changes. A high-pass Butterworth IIR filter with $f_c=0.5$ Hz removes this drift while preserving the P-wave, QRS complex, and T-wave (0.5–40 Hz). The group delay of the IIR filter must be accounted for when measuring PR and QT intervals for arrhythmia detection — clinical software applies phase compensation to align the filtered signal with the original recording timeline.
Q1 A 2nd-order IIR filter has poles at $z=0.85\pm0.3j$. Is this filter stable?
Q2 Why should you always use output='sos' instead of output='ba' when designing IIR filters in SciPy?
Q3 A 6th-order Butterworth LP filter has $f_c=200$ Hz. Estimate the attenuation in dB at $f=600$ Hz (one decade above $f_c$).
Interactive Lab
Explore how filter type (LP/HP/BP/BS), filter family (Butterworth vs FIR), and order $N$ interact to shape the frequency response. The Bode plot shows magnitude (dB) and phase simultaneously so you can see both the amplitude roll-off and the phase distortion that comes with higher-order IIR designs.
Summary
If you forget everything else, remember these four ideas. Each one is directly testable on the midterm.
FIR: no feedback, always stable, linear phase, high order. IIR: feedback, efficient (low order), nonlinear phase, must check stability. Choose FIR when phase matters (EEG, audio); choose IIR when efficiency matters (real-time embedded).
$h[n]=2f_c\cdot\text{sinc}(2f_c(n-M/2))\cdot w[n]$. Hamming window gives −53 dB sidelobe attenuation and is the best all-round choice. Center tap always equals $2f_c$. Symmetric coefficients → linear phase → group delay = $M/2$ samples.
$|H|^2=1/(1+(\Omega/\Omega_c)^{2N})$. Roll-off = 20N dB/decade. At $f_c$: exactly −3 dB. To prewarp: $\Omega_c=\tan(\pi f_c/f_s)$. Always use output='sos' + sosfilt() for numerical safety.
An IIR filter is stable iff all poles satisfy $|p_k|<1$ (strictly inside the unit circle). Direct $(b,a)$ form breaks for N>5. SOS (second-order sections) decomposes the filter into biquad stages — numerically stable at any order.
The Fourier Transform gives global frequency content. But when does a 440 Hz note appear in a recording? The Short-Time Fourier Transform (STFT) answers by applying a sliding window: you trade time resolution for frequency resolution. Week 9 explores the STFT, the spectrogram, and the Heisenberg uncertainty principle that governs that trade-off. (Week 8 = Midterm Exam.)
Further Reading
Curated resources for students who want to build deeper intuition. Each resource is worth the time — no filler.
Exceptionally clear walkthrough of the z-transform, poles, zeros, and what they mean for filter behavior. The most approachable video on this topic available online.
→ youtube.com/BrianDouglas InteractiveReal-time interactive Bode plots: drag poles and zeros in the z-plane and watch the frequency response update instantly. Builds visceral intuition for pole-zero design that no textbook can match.
→ falstad.com/dfilter Textbook · Ch. 16The Scientist and Engineer's Guide to DSP Chapter 16 covers windowed-sinc design with worked examples, window trade-off tables, and SciPy code. Free online at dspguide.com.
→ dspguide.com/ch16.htm DocsThe definitive reference for butter(), firwin(), sosfilt(), sosfreqz(), and group_delay(). Includes worked examples and comparison of filter design functions.
Exercises
8 questions (3 Theory · 3 Code · 2 Synthesis) covering all three topics. Numerical values on exams may differ but the method will always mirror these problems exactly.
A filter is defined by: $b_0=0.25,\, b_1=0.5,\, b_2=0.25$, and all $a_k=0$. (a) Is this FIR or IIR? (b) Write out the difference equation. (c) Compute $y[0]$ and $y[1]$ for input $x=[4,2,0,0,\ldots]$ (zero initial conditions). (d) What type of filter (LP/HP/BP/BS) is this likely to be, and why?
Using scipy.signal.butter and sosfilt: (a) Design a 4th-order Butterworth LP filter with $f_c=200$ Hz and $f_s=1000$ Hz using output='sos'. (b) Generate a test signal: 50 Hz + 350 Hz sine, 1 second at $f_s=1000$ Hz. (c) Filter the signal and plot both the original and filtered signal overlaid. (d) Verify in the plot that the 350 Hz component is attenuated.
butter(N, Wn, btype, fs, output), sosfilt(sos, x)
sos = butter(4, 200, 'low', fs=1000, output='sos'). To generate the signal: t = np.linspace(0, 1, 1000, endpoint=False), then add two sines. Filter with sosfilt(sos, x).Design an FIR lowpass filter with $M=6$ and normalized cutoff $f_c=0.2$. Use a Rectangular window ($w[n]=1$ for all $n$). (a) Write the general formula for $h[n]$. (b) Compute $h[3]$ (center tap). (c) Compute $h[4]$. (d) Verify that $h[3]=h[M-3]$ (symmetry check). (e) What is the group delay in samples?
Recall: $\text{sinc}(x)=\sin(\pi x)/(\pi x)$ and $\text{sinc}(0)=1$.
Using scipy.signal.firwin and freqz: (a) Design three FIR LP filters ($f_c=150$ Hz, $f_s=1000$ Hz, $M=64$) using Rectangular, Hamming, and Blackman windows. (b) Compute and plot all three magnitude responses in dB on the same axes (−80 to 5 dB range). (c) Add a vertical dashed line at $f_c$. (d) Annotate the sidelobe level for each curve. Which window gives the best stopband attenuation?
firwin(65, 150, window='hamming', fs=1000). For frequency response: w, H = freqz(h, worN=2048, fs=1000). Convert to dB: 20*np.log10(np.abs(H)+1e-12). Blackman gives ≈ −74 dB sidelobe attenuation.A 6th-order Butterworth LP filter has $f_c=100$ Hz, $f_s=1000$ Hz. (a) Compute the prewarped cutoff $\Omega_c=\tan(\pi f_c/f_s)$. (b) Evaluate $|H(f)|^2$ at $f=200$ Hz using the prewarped ratio $\Omega_{200}/\Omega_c$. (c) Convert to dB. (d) What is the theoretical roll-off rate in dB/decade? (e) Is this filter stable? What condition must all poles satisfy?
Using scipy.signal: (a) Design three N=4 LP filters ($f_c=150$ Hz, $f_s=1000$ Hz): Butterworth, Chebyshev I (1 dB passband ripple), and Elliptic (1 dB/60 dB). All using output='sos'. (b) Plot all three magnitude responses in dB on the same axes. (c) Add markers at $f_c$ (−3 dB) and $2f_c$ (expected attenuation). (d) Which filter has the sharpest roll-off at $f=2f_c$?
butter(4, 150, 'low', fs=1000, output='sos'), cheby1(4, 1, 150, 'low', fs=1000, output='sos'), ellip(4, 1, 60, 150, 'low', fs=1000, output='sos'). Elliptic will have the sharpest transition at the cost of ripple in both passbands.A wearable ECG patch samples at $f_s=500$ Hz. The QRS complex occupies 5–40 Hz; baseline wander is below 0.5 Hz; muscle noise is above 100 Hz. (a) Specify the bandpass cutoff frequencies $f_{c1}$ and $f_{c2}$ to isolate the QRS complex. (b) Design a 4th-order Butterworth bandpass filter using butter(N, [fc1,fc2], 'bandpass', fs=500, output='sos'). (c) Plot the magnitude response. (d) What is the filter's roll-off below $f_{c1}$ in dB/decade? Why is linear phase (FIR) important for ECG interval measurements?
Power-line interference at 60 Hz contaminates a physiological recording at $f_s=1000$ Hz. (a) Design a notch (band-stop) filter using iirnotch(60, 30, fs=1000) — the second argument is the quality factor Q. (b) Apply the filter to a composite signal: 10 Hz + 60 Hz + 200 Hz sines. (c) Plot the frequency spectrum before and after filtering. (d) Verify the 60 Hz component is attenuated and the 10 Hz and 200 Hz components are preserved. (e) Explain in one sentence why a high Q value creates a narrower notch.
from scipy.signal import iirnotch. The notch width is $f_0/Q$: for Q=30, width = 60/30 = 2 Hz. Higher Q → narrower band rejected → more selectivity. Apply with sosfilt(np.array([b,a]).reshape(1,-1), x) or simply lfilter(b, a, x) since iirnotch is only 2nd order. Plot spectrum with np.fft.rfft.