5.4.12 · D4Scientific Computing (Python)

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

2,996 words14 min readBack to topic

Before we start, one picture to anchor every term we will lean on. Convolution is flip-and-slide: flip the kernel, slide it over the signal, at each position multiply the overlapping samples and sum them.

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

Read the figure by colour and label. The blue stems (upward) are the signal , one stem per sample index along the bottom axis. The pink stems (downward) are the already-flipped kernel , parked at one slide position — flipped means its last tap now leads. Wherever blue and pink line up, a yellow double-arrow marks an overlapping pair, and the yellow label on it is that pair's product . The yellow line at the top adds those products into one output number . Slide the pink stems one step right and repeat to get the next . That is the entire mechanic — hold it in your head for L1.


L1 · Recognition

These check that you can read the definitions without computing much.

Problem 1.1

and . Without a computer, what is the length of the full convolution ?

Recall Solution 1.1

WHAT we use: the output-length rule . WHY: the flipped kernel first touches the signal at one overlapping sample and leaves with one overlapping sample; counting all slide positions gives that count. Here , , so length .

Problem 1.2

You call numpy.fft.rfft on a real signal of samples taken at Hz. (a) What is the frequency-bin spacing ? (b) What is the highest frequency the spectrum can represent (Nyquist)?

Recall Solution 1.2

(a) . Why this formula: the DFT places its probe waves at multiples of , so neighbouring bins sit apart. (b) Nyquist . Why: above half the sampling rate, a wave is indistinguishable from a slower one (see Aliasing and Sampling Theorem).

Problem 1.3

For each pair, name the operation: (a) "find where this heartbeat template best matches the ECG," (b) "smooth a noisy signal by averaging neighbours." Convolution or correlation?

Recall Solution 1.3

(a) Correlation — matching a template means you slide the template as-is, without flipping it, and look for the peak overlap (see Cross-correlation and Template Matching). (b) Convolution — averaging neighbours is applying an LTI smoothing kernel; the kernel here is symmetric so flipping changes nothing, but conceptually it is convolution. Precise distinction (which one flips): convolution flips the kernel before sliding; correlation does not flip it. That is the only difference. Concretely, equals where is reversed — i.e. correlation's non-flip and convolution's flip cancel, so you feed convolution the pre-reversed kernel to reproduce correlation.


L2 · Application

Now you actually compute.

Problem 2.1

Convolve with by hand in full mode (keep every output sample). Predict the result before summing, then verify.

Recall Solution 2.1

WHAT we use: two facts — (i) the output-length rule from L1, and (ii) the shifting property: convolving with a shifted impulse just shifts the signal by .

WHY the prediction holds: has its lone at index , so it is . Because convolution with a shifted spike only re-plants each sample further along (no reshaping), the signal comes back shifted right by one. The length-rule then fixes the output at samples, so we pad with the required zeros: predicted .

Flip-and-slide check. Flip : (symmetric here). Sliding:

✓ — exactly the shifted signal, as predicted, and samples long because we kept the full output.

Problem 2.2

A signal sampled at Hz must be low-pass filtered with a cutoff of Hz using the old butter(4, Wn) API (no fs=). Compute the normalised cutoff .

Recall Solution 2.2

WHAT: the old API wants cutoff as a fraction of Nyquist. WHY: the digital filter only knows frequencies relative to the highest one it can represent, . This is a legal value because .

Problem 2.3

You build the continuous signal and sample it at Hz for exactly s, so the stored discrete array is with (that is samples). At which bin index does the FFT peak appear?

Recall Solution 2.3

WHAT: after sampling, the FFT of the discrete list places bin at frequency . Here Hz, so Hz. WHY the peak sits exactly on a bin: the underlying Hz tone is an integer multiple of , so the sampled sinusoid lands cleanly on one probe wave (no spectral leakage). Setting : .


L3 · Analysis

Here you reason about why results come out as they do.

Problem 3.1

Two experimenters record the same Hz and Hz tones. Alice records for s at Hz; Bob records for s at Hz. Only one of them can separate the two peaks in the FFT. Who, and why?

Recall Solution 3.1

WHAT decides separability: bin spacing , and where is the record length. So — spacing depends only on record length , not on .

  • Alice: Hz. The peaks are Hz apart — only about one and a half bins; they smear together.
  • Bob: Hz. Now Hz bins of separation — cleanly resolved. Answer: Bob, because recording longer shrinks and resolves close peaks. Sampling faster would not have helped resolution at all.

Problem 3.2

You apply a causal filter with lfilter and notice a sharp peak in your signal has moved samples later. At Hz, how many milliseconds of delay is that, and how would you get zero delay?

Recall Solution 3.2

WHAT: a delay of samples at Hz means each sample is ms apart, so delay . WHY it happens: a causal filter can only use present and past inputs, so its impulse response is centred late → the output lags (phase shift). Fix: use filtfilt, which runs the filter forward, then backward. The backward pass introduces an equal-and-opposite delay, so the two cancel → zero phase, peak stays put (see Digital Filter Design).

Problem 3.3

For a real signal of length , numpy.fft.rfft returns how many complex numbers, and why not ?

Recall Solution 3.3

WHAT: rfft returns values. WHY: for a real signal the spectrum is conjugate-symmetric — the negative-frequency half is just the mirror-conjugate of the positive half, carrying no new information. rfft therefore keeps only DC (bin 0), bins , and Nyquist (bin ): that is numbers. Keeping the redundant mirror (full fft) would give .


L4 · Synthesis

Combine several ideas into one answer.

Problem 4.1

You want to convolve two arrays of length each. Direct convolution costs multiply-adds; fftconvolve costs . Estimate the speed-up factor (ratio of the two costs).

Recall Solution 4.1

WHAT: speed-up . WHY fftconvolve is faster: by the convolution theorem, time-domain convolution equals frequency-domain multiplication, and the FFT computes all spectra in ; the pointwise multiply is . Plug in : , so (Order-of-magnitude: a few thousand times faster — exactly why fftconvolve exists.)

Problem 4.2

A continuous tone is sampled at Hz to give with samples. You compute mag = np.abs(np.fft.rfft(x)) / N * 2. What magnitude value appears at the Hz bin, and why the factor /N*2 (and where is that *2 not allowed)?

Recall Solution 4.2

WHY the scaling (WHAT each factor does):

  • /N — the raw DFT sum accumulates terms, inflating magnitudes by ; dividing removes that.
  • *2rfft throws away the negative-frequency mirror, which held half the sinusoid's energy; multiplying by restores the true one-sided amplitude. After correct scaling, a pure sine of amplitude reads back as . Here , so the Hz bin (an interior bin) shows magnitude (up to tiny floating-point error). Where the *2 is wrong: the DC bin (bin 0) and, since is even, the Nyquist bin (last bin, Hz) have no mirror partner, so those two must keep the /N scaling only — doubling them would double-count energy.

Problem 4.3

Design intent: keep frequencies below Hz, kill everything above, on data sampled at Hz — but you accidentally ask for a cutoff of Hz. What goes wrong, and what is the maximum legal cutoff?

Recall Solution 4.3

WHAT is illegal: any cutoff at or above Nyquist Hz has no meaning — there are no frequencies above Hz in the sampled data to filter. WHY: the sampled signal literally cannot represent anything above Nyquist, so a " Hz cutoff" points at a frequency that does not exist; butter rejects it (normalised ). Answer: maximum legal cutoff is just under ; your intended Hz is fine since .


L5 · Mastery

One problem that ties the whole module together.

Problem 5.1

You must smooth a signal with a length- moving-average kernel and you want it done by multiplication in the frequency domain (to prove the convolution theorem to yourself). Work entirely with the discrete arrays. (a) Write the normalised kernel . (b) Convolve the discrete signal with it by hand in full mode. (c) State what the sum of all output samples must equal, and why, as a sanity check on the theorem.

Recall Solution 5.1

(a) A length- moving average weights each of neighbours equally and must sum to (so DC gain is — it neither amplifies nor attenuates a constant):

(b) Full length . Kernel is symmetric so flipping is a no-op. Slide:

.

(c) The sanity check (WHY it must hold): the convolution theorem says . At zero frequency (DC, ), and . So . Add the values: ✓. The total is conserved precisely because the kernel's DC gain is — a direct, checkable consequence of the theorem (foundations in Fourier Transform and Linear Time-Invariant Systems).


Connections

  • Linear Time-Invariant Systems — why convolution is forced on us.
  • Fourier Transform — the theorem behind fftconvolve and FFT scaling.
  • Aliasing and Sampling Theorem — the Nyquist limits used in L1/L4.
  • Digital Filter Designbutter, cutoff normalisation, filtfilt vs lfilter.
  • Cross-correlation and Template Matching — the "no-flip" cousin from L1.
  • numpy.fftrfft/rfftfreq behaviour probed in L3.

Skill Ladder

L1 Recognition

L2 Application

L3 Analysis

L4 Synthesis

L5 Mastery

read definitions

compute by hand

explain why

combine ideas

prove theorem