5.4.12Scientific Computing (Python)

scipy.signal — filtering, convolution, FFT-based analysis

1,812 words8 min readdifficulty · medium1 backlinks

1. Convolution — WHAT, WHY, HOW

WHY this formula? A linear time-invariant (LTI) system is fully described by how it responds to a single spike δ[n]\delta[n] — call that response h[n]h[n] (the impulse response). Any input is a sum of scaled, shifted spikes: x[n]=kx[k]δ[nk]x[n]=\sum_k x[k]\,\delta[n-k]. By linearity the output is the same sum of scaled, shifted responses → exactly the convolution sum. So convolution isn't arbitrary: it is forced by linearity + time-invariance.

HOW (the flip-and-slide): flip hh, slide it across xx, multiply overlapping samples, sum. Output length =len(x)+len(h)1= \text{len}(x)+\text{len}(h)-1.

from scipy.signal import convolve, correlate, fftconvolve
convolve([1,2,3],[1,1])            # -> [1,3,5,3], 'full' by default
convolve(x, h, mode='same')        # output same length as x (centered)
fftconvolve(x, h)                   # SAME result, O(N log N) via FFT — fast for big arrays

2. FFT — frequency content

WHY: ei2πkn/Ne^{-i2\pi kn/N} is a probe wave; the sum is an inner product, so X[k]|X[k]| is large when xx resembles that wave. The FFT just computes all X[k]X[k] in O(NlogN)O(N\log N) instead of O(N2)O(N^2).

import numpy as np
fs = 1000                      # Hz sampling rate
t  = np.arange(0, 1, 1/fs)     # 1 s
x  = np.sin(2*np.pi*50*t) + 0.5*np.sin(2*np.pi*120*t)
X  = np.fft.rfft(x)
f  = np.fft.rfftfreq(len(x), d=1/fs)   # frequency in Hz
mag = np.abs(X)/len(x)*2               # *2 for one-sided amplitude
# peaks appear at 50 Hz and 120 Hz
Figure — scipy.signal — filtering, convolution, FFT-based analysis

3. Filtering — removing unwanted frequencies

FIR vs IIR

from scipy.signal import butter, firwin, filtfilt, lfilter, freqz
 
# 4th-order Butterworth low-pass, cutoff 80 Hz, fs=1000
b, a = butter(4, 80, btype='low', fs=fs)
y_zerophase = filtfilt(b, a, x)   # forward+backward -> ZERO phase distortion
y_causal    = lfilter(b, a, x)    # real-time, but introduces phase delay

4. The unifying theorem


Common mistakes


Discrete convolution formula?
(xh)[n]=kx[k]h[nk](x*h)[n]=\sum_k x[k]\,h[n-k] (flip, slide, multiply, sum)
Why is an LTI system fully described by its impulse response?
Any input = sum of scaled/shifted spikes; by linearity output = same sum of scaled/shifted impulse responses = convolution.
Output length of full convolution of len-M and len-N arrays?
M+N1M+N-1
Difference between convolution and correlation?
Correlation does NOT flip the kernel; used for template matching / alignment.
Nyquist frequency?
fs/2f_s/2 — highest frequency representable without aliasing.
FFT frequency bin spacing?
Δf=fs/N\Delta f = f_s/N
Convolution theorem?
xhXHx*h \leftrightarrow X\cdot H — time convolution = frequency multiplication.
FIR vs IIR?
FIR: output from past inputs only, always stable, linear phase. IIR: feedback from past outputs, cheaper but can be unstable.
filtfilt vs lfilter?
filtfilt = forward+backward → zero phase; lfilter = causal but adds phase delay.
Normalised cutoff Wn for 80 Hz, fs=1000?
80/(1000/2)=0.1680/(1000/2)=0.16
Why does fftconvolve beat convolve for large arrays?
Uses convolution theorem: O(N log N) FFTs + pointwise multiply vs O(N²) direct sum.
To resolve two close frequency peaks, what do you change?
Record longer (larger N) → smaller Δf. Sampling faster doesn't help resolution.
Recall Feynman: explain to a 12-year-old

Imagine sliding a little stamp (the kernel) along a long strip of stickers (the signal), and at each spot you add up how well they overlap — that's convolution, and it's how we blur or smooth things. A filter is choosing a stamp that erases the jiggly fast bits but keeps the slow shape. The FFT is like a magic prism: shine your wiggly signal through it and it splits into pure musical notes (frequencies) so you can see "ah, there's a loud 50 Hz hum in here," and then zero that note out.

Connections

  • Fourier Transform — math foundation of FFT.
  • Aliasing and Sampling Theorem — why Nyquist matters.
  • Linear Time-Invariant Systems — source of the convolution sum.
  • numpy.fft — lower-level FFT that scipy builds on.
  • Digital Filter Design — Butterworth/Chebyshev tradeoffs.
  • Cross-correlation and Template Matching

Concept Map

described by

linearity + time-invariance forces

without flipping h

peak marks

multiply spectra equals

computes

O N logN speeds up

same result via

bin spacing f_s/N

real signal symmetric use

time-domain method for

LTI system

Impulse response h n

Convolution x*h

Correlation

FFT / DFT

fftconvolve

Frequency spectrum X k

Nyquist f_s/2

rfft for real signals

Filtering / cleaning

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, ek signal matlab time ke saath numbers ki list — jaise mic se aayi awaaz ya sensor ka data. scipy.signal teen kaam karta hai: signal ko saaf karna (filtering), do signals ko mix ya match karna (convolution/correlation), aur uske andar kaun-kaun si frequency hai dekhna (FFT).

Convolution ka idea simple hai: ek chhota stamp (kernel) ko poore signal pe slide karo, har jagah overlap ka product add karo. Jab tum kisi LTI system ko ek spike do to jo response aata hai usko impulse response hh bolte hain — aur kyunki system linear hai, koi bhi input uske scaled-shifted spikes ka sum hota hai, isliye output automatically convolution ban jaata hai. Yeh formula randomly nahi aaya, linearity se forced hai.

FFT ek prism jaisa hai: wiggly signal ko pure notes (frequencies) mein tod deta hai. Yaad rakho — sabse badi frequency jo tum dekh sakte ho woh Nyquist fs/2f_s/2 hai, aur do nazdeek frequencies alag dekhni hain to recording lambi karo (zyada N → chhota Δf\Delta f), sirf zyada samples se kaam nahi banega agar fast nahi sample kar rahe.

Sabse bada (80/20) point: Convolution Theorem — time mein convolve karna = frequency mein simple multiply karna. Isi wajah se fftconvolve fast hai, aur isi wajah se ek filter (frequency mein HH se multiply) actually time mein ek kernel hh se convolution ke barabar hai. Aur offline kaam mein filtfilt use karo lfilter ke jagah, taaki phase shift na ho aur peaks apni jagah rahein.

Go deeper — visual, from zero

Test yourself — Scientific Computing (Python)

Connections