Visual walkthrough — NumPy FFT — np.fft module
We will answer three questions per step: WHAT we just did, WHY we did it, and WHAT IT LOOKS LIKE (the figure).
Step 1 — What is a "signal"? Just a list of heights.
WHAT. A signal is nothing mysterious: it is a list of numbers measured one after another in time. We call the list .
- ::: the height of the wiggle at the -th measurement.
- ::: which measurement (an integer counter: ).
- ::: how many measurements we took in total.
WHY. A microphone doesn't hand you "a 50 Hz tone." It hands you a dotted curve — heights sampled at regular clicks of a clock. Everything Fourier does starts from this raw list of dots.
WHAT IT LOOKS LIKE. Below, dots. The dot at position has height . That's all a signal is.

Step 2 — A pure frequency is a spinning clock hand.
WHAT. Instead of thinking of a wave as an up-and-down squiggle, think of a hand spinning on a clock face. The tip of the hand traces a circle of radius 1 (the unit circle). Its shadow on the horizontal axis is a cosine; its shadow on the vertical axis is a sine.
To write "a point on the unit circle at angle " in one symbol, we use Euler's formula:
- ::: a point on the unit circle, sitting at angle .
- ::: the angle of the clock hand, measured from the 3-o'clock direction, counter-clockwise.
- ::: the "turn 90°" number; it points straight up. Multiplying by rotates a quarter turn.
WHY use and not just and separately? Because tracking two shadows is bookkeeping pain. One spinning point carries both the cosine and the sine at once. All the algebra collapses into "hands spinning," which multiply beautifully: (spinning by then by = spinning by their sum).
WHAT IT LOOKS LIKE. The hand at angle , its two shadows, and pointing up.

Step 3 — The probe wave: a hand that spins full turns.
WHAT. Now we build a test signal — a pure frequency we will hold up against our data to see if it matches. Over our samples, we want a hand that makes exactly complete turns. At sample its angle is
- ::: one full turn, in radians.
- ::: how many full turns the hand makes across the whole window. is a hand that never moves; spins once; spins twice.
- ::: what fraction of the way through the samples we are. At the fraction is , so the angle is — exactly whole turns. Perfect closure.
- ::: the position of probe-'s hand at sample .
WHY this exact form? We need a family of test waves that (a) all fit whole numbers of cycles into the window (so they line up cleanly) and (b) are indexed by a simple integer . The formula is the unique clean way to say "spin times across steps."
WHAT IT LOOKS LIKE. Below, probe visits its angles — the dots march twice around the circle.

Step 4 — "How much of probe is inside ?" = correlation.
WHAT. To measure the overlap between our data and probe , we multiply them sample-by-sample and add up the results. But there's a twist: we multiply by the conjugate of the probe, (the hand spinning the other way):
This is the DFT — and we just derived it.
- ::: add up over every sample.
- ::: our measured height.
- ::: the conjugate probe (minus sign = spins clockwise).
- ::: a single complex number — the total "match score" for frequency .
WHY the minus sign / conjugate? Multiplying a spinning hand by the opposite spin cancels the rotation when they match, freezing the matching part into a steady value that piles up instead of averaging away. If the frequencies don't match, the leftover spin keeps rotating and the sum cancels to zero (Step 5 proves this). So the minus sign is what makes matching frequencies "ring" and mismatched ones stay silent.
WHAT IT LOOKS LIKE. Left: probe matches the data — the products all point the same way and stack into a big sum. Right: probe mismatches — the products point every which way and cancel.

Step 5 — Why mismatches vanish: roots of unity cancel.
WHAT. Take a probe and a probe with . Their combined correlation is a sum of spinning points:
WHY it's zero. Write . Then each term is , and the sum is a geometric series:
- because is a whole number of turns → the top is .
- when → the bottom is nonzero.
- Zero over nonzero . Every mismatched frequency cancels perfectly.
When , , every term is , and the sum is .
WHAT IT LOOKS LIKE. The arrows are spread evenly around the circle (like hours on a clock). Add head-to-tail and they close into a loop back to the start — a resultant of zero. This is the geometric heart of the whole transform.

Step 6 — Undoing it: the Inverse DFT.
WHAT. Because matching gives and mismatching gives , we can rebuild the original samples by adding all probes back, each weighted by its score , and dividing by :
- ::: how much of frequency to add back.
- ::: the forward-spinning probe (plus sign — we're building, not measuring).
- ::: undoes the factor of that Step 5 produced for the matching term.
WHY it works. Plug the definition of in and swap the order of the two sums; the inner sum is exactly the orthogonality result from Step 5. Everything cancels except the term you wanted — you get back exactly. In NumPy this is np.fft.ifft, and ifft(fft(x)) == x up to float dust.
WHAT IT LOOKS LIKE. Three probes (), each scaled by its , stacked on top of each other, rebuild the wiggly original — a chord reassembled from its notes.

Step 7 — Edge cases you must never trip on.
WHAT. Three degenerate inputs that break naive intuition:
- Constant signal (all samples equal, ). Only the ("DC") probe — the hand that never moves — matches. So and every other bin is exactly 0.
- The Nyquist bin (, when is even). This probe flips sign every sample: . It's the fastest wiggle your sampling can even represent. Anything faster is invisible (see Sampling and Nyquist Theorem).
- Real input symmetry. For real data, — the top half of the spectrum is the mirror-conjugate of the bottom half. This redundancy is why
np.fft.rfftkeeps only bins.
WHY show these. These are exactly where beginners misread the output — a huge that isn't "50 Hz," a mysterious mirrored second half, a spike at the very last bin. Knowing them means the spectrum never surprises you.
WHAT IT LOOKS LIKE. Left: constant signal → one lone DC spike. Middle: the Nyquist zig-zag. Right: conjugate mirror symmetry of a real signal's spectrum.

The one-picture summary
Everything above in a single flow: time samples → correlate against each spinning probe → orthogonality keeps only matches → spectrum → (add back ÷N) → time samples.

Recall Feynman retelling — the whole walkthrough in plain words
You have a list of heights measured over time — that's your signal (Step 1). A pure musical note is like a hand spinning on a clock, and one tidy symbol tracks both its shadows at once (Step 2). We build test-notes, "probes," each spinning a whole number of times across the window (Step 3). To ask "is this note hiding in my data?", we multiply the data by the probe spinning backwards and add it all up — when they match, the spins freeze and stack into a big number; when they don't, they smear around and add to nothing (Step 4). That cancellation is guaranteed because evenly-spaced arrows around a circle always close into a loop of zero (Step 5). Since matching gives and mismatching gives , we can also run the movie backwards: scale each probe by its score, add them up, divide by , and the original wiggle reappears (Step 6). Finally, watch the weird cases — a flat signal is pure DC, the fastest visible wiggle is the Nyquist bin, and real signals produce a mirror-image second half you can throw away (Step 7). That mirror is why rfft exists, and the whole loop is one picture (Step 8).