5.4.7 · D5Scientific Computing (Python)
Question bank — NumPy FFT — np.fft module
Vocabulary refresher (every symbol used below is defined here first):
- ::: the number of samples you fed in — the length of your input array.
- ::: the sampling rate in Hz, i.e. how many samples per second; equivalently where is the time gap between neighbouring samples.
- ::: the total record length in seconds, .
- bin ::: the -th output slot of the FFT; it reports how much of frequency is present.
- DC bin ::: bin , standing for "zero frequency" = the constant / average level of the signal.
True or false — justify
The FFT computes something different from the DFT.
False. The FFT computes the exact same numbers as the Discrete Fourier Transform; "Fast" refers only to the algorithm, not to a different result.
A longer recording gives you finer frequency resolution.
True. Resolution is , so doubling (more samples at the same rate) halves the spacing between neighbouring frequency bins.
Increasing the sampling rate (with fixed) improves frequency resolution.
False. With fixed, raising shortens , so actually gets worse; you gain access to higher frequencies (higher Nyquist) but coarser resolution.
For real input, the FFT output is half redundant.
True. Real signals satisfy , so the upper half is the conjugate mirror of the lower half — which is exactly why
rfft returns only bins.np.fft.ifft(np.fft.fft(x)) returns x exactly.
Mostly true. It returns
x up to tiny floating-point error, because NumPy's factor and sign conventions are matched; use np.allclose, not ==, to compare.The DC bin (bin 0) can be negative.
True. Bin 0 equals , the sum of the samples; if the signal's average is negative, the sum is negative.
The magnitude directly gives the amplitude of a sine.
False. For a real sine of amplitude , energy splits between and , so is scaled by ; you must multiply by to recover .
fftfreq and rfftfreq return the same array.
False.
fftfreq includes negative frequencies (wrap-around layout), while rfftfreq returns only the non-negative frequencies matching rfft's output.Two different pure frequencies contribute to the same FFT bin.
False. Distinct pure waves over a full window are orthogonal (their correlation sums to zero), so each falls cleanly into its own bin — the whole point of the transform.
Spot the error
f = np.arange(N); plt.plot(f, np.abs(np.fft.fft(x))) — what's wrong?
The x-axis should be actual frequencies from
fftfreq(N, d), not raw indices; also the upper half are negative frequencies, so you need fftshift for a symmetric plot.amp = np.abs(np.fft.rfft(x)); A = amp.max() — why is A wrong?
Raw magnitude is scaled by for a real sine; the physical amplitude is
amp.max() * 2 / N, and the DC bin needs 1/N instead of 2/N."Bin 50 holds the 50 Hz tone, so bin always means Hz." Where's the flaw?
That equality only held because (a one-second window); in general , so the bin index equals Hz only by coincidence.
X = np.fft.rfft(x); xr = np.fft.ifft(X) — why is the round-trip broken?
rfft's output must be inverted with irfft, not ifft; ifft expects the full length- complex spectrum, not the truncated half from rfft.Someone divides every bin by to get amplitudes, including bin 0. What breaks?
The DC bin is not split into two halves — it has no negative-frequency twin — so it must be divided by , not ; the scaling rule is amplitude-specific.
Plotting np.abs(X) against rfftfreq but noticing energy "leaking" into neighbouring bins from a clean sine. What causes it?
The sine's frequency doesn't complete a whole number of cycles in the window, so it isn't periodic there — this is spectral leakage, fixed by windowing, not a bug in
fft.Why questions
Why is there a minus sign in of the forward DFT?
You correlate the signal against a probe wave , and correlation uses the complex conjugate of the probe — conjugating flips the sign of the exponent.
Why does correlating with a probe wave isolate a single frequency?
Because distinct pure waves are orthogonal: their term-by-term product sums to zero over the window, so every frequency except the matching one cancels away.
Why can the FFT be done in instead of ?
It recursively reuses shared sub-sums (the divide-and-conquer symmetry of the roots of unity), so work done for even/odd index halves is not repeated.
Why does a constant signal produce a spike only at bin 0?
A constant never oscillates, so it contains only zero frequency; bin 0 collects the sum while every oscillating probe correlates to zero against a flat line.
Why do real inputs give a conjugate-symmetric spectrum?
Because is real, the probe and probe produce complex-conjugate results — see Complex Numbers and Euler's Formula — forcing .
Why is the highest resolvable frequency limited to ?
The Sampling and Nyquist Theorem: with samples per second you cannot distinguish oscillations faster than half that rate — they alias down and masquerade as lower frequencies.
Why does fftshift exist if the numbers don't change?
The default FFT layout puts negative frequencies at the end of the array;
fftshift re-centres zero frequency so a plot reads left-to-right from to .Edge cases
What does np.fft.fft(x) return when x is all zeros?
An all-zero spectrum — no frequency, including DC, is present because and there is nothing to correlate against.
For a single-sample input x = [c] (), what is the FFT?
Just
[c]: with the only bin is DC (bin 0), whose value is the sum of the one sample, so the transform is the identity.What lands in the Nyquist bin (bin ) when is even?
The frequency exactly at ; it is its own conjugate mirror (real-valued), so it is not doubled like other bins when recovering amplitude.
If is odd, is there a Nyquist bin?
No. With odd there is no bin sitting exactly at ; the positive and negative halves pair up completely, and
rfft returns bins.A pure sine sits exactly between two bin frequencies — what happens?
Its energy smears across both neighbouring bins (leakage) rather than forming one clean spike, because it isn't periodic within the window; windowing tames the smear.
What does the FFT of a signal that's just a single DC offset plus one sine look like?
A spike at bin 0 (the offset, scaled by ) plus a symmetric pair at (the sine, each half-height); the two contributions never interfere because they sit in different bins.
Connections
- NumPy FFT — np.fft module — the parent note these traps drill
- Discrete Fourier Transform — the identical math the FFT accelerates
- Sampling and Nyquist Theorem — the limit behind several edge cases
- Spectral Leakage and Windowing — the cause of "leaking" bins
- Complex Numbers and Euler's Formula — why conjugate symmetry holds