|
206 | 206 | ;; You could represent rotations as 2D vectors $(x, y)$, but then **multiplication has no |
207 | 207 | ;; geometric meaning**. What does $(x_1, y_1) \times (x_2, y_2)$ mean? |
208 | 208 | ;; |
209 | | -;; Complex multiplication is **rotation and scaling**: |
| 209 | +;; Complex multiplication is **rotation and scaling**. To see why, remember that any point |
| 210 | +;; can be described two ways: |
| 211 | +;; - **Cartesian**: (x, y) — how far right, how far up |
| 212 | +;; - **Polar**: (r, θ) — how far from origin, what angle |
| 213 | +;; |
| 214 | +;; In polar form, multiplication is simple: **(r₁, θ₁) × (r₂, θ₂) = (r₁×r₂, θ₁+θ₂)** |
| 215 | +;; — multiply distances, add angles. That's rotation! |
| 216 | +;; |
| 217 | +;; The formula we'll use converts this polar rule into Cartesian coordinates. |
| 218 | +;; It looks complicated because we're translating between two coordinate systems, |
| 219 | +;; but it's doing something simple: adding angles when you multiply. |
210 | 220 |
|
211 | 221 | ;; Multiply two complex numbers |
212 | 222 | (defn complex-mult [z1 z2] |
@@ -271,7 +281,8 @@ z-rotated |
271 | 281 | :effect "Rotate by θ" |
272 | 282 | :example (str "(" (format "%.1f" (:real z-rotated)) ", " (format "%.1f" (:imag z-rotated)) ")")}]) |
273 | 283 |
|
274 | | -;; **Key insight:** Any number on the unit circle (magnitude 1) performs a pure rotation. |
| 284 | +;; **Key insight:** Multiplying by a number on the unit circle (magnitude 1) performs a pure rotation |
| 285 | +;; (no scaling—just rotation). |
275 | 286 | ;; |
276 | 287 | ;; **Why this matters for Fourier transforms:** |
277 | 288 | ;; - Addition = superposition of rotations |
@@ -346,6 +357,17 @@ z-rotated |
346 | 357 | ;; Here's the remarkable fact: **any** periodic pattern can be created by adding up |
347 | 358 | ;; rotations at these specific speeds. |
348 | 359 | ;; |
| 360 | +;; **Why these N frequencies?** Think of it like mixing colors. To make any color on a screen, |
| 361 | +;; you need exactly 3 independent values (red, green, blue). More than 3 is redundant, less than 3 |
| 362 | +;; can't make all colors. It's a **3-dimensional** space. |
| 363 | +;; |
| 364 | +;; Similarly: |
| 365 | +;; - Eight temperature readings = 8 independent numbers |
| 366 | +;; - You need exactly 8 independent "ingredients" to reconstruct any pattern |
| 367 | +;; - These 8 rotation frequencies (k=0,1,2,...,7) are those ingredients |
| 368 | +;; - They're **independent** (orthogonal—we'll explain this shortly) - each contributes something unique |
| 369 | +;; - Together they can build any possible 8-sample pattern |
| 370 | +;; |
349 | 371 | ;; Our eight temperatures? They're the sum of (at most) eight rotating points, each |
350 | 372 | ;; going at a different speed (k = 0, 1, 2, ..., 7). |
351 | 373 |
|
@@ -723,13 +745,65 @@ z-rotated |
723 | 745 | ;; |
724 | 746 | ;; **Key insight**: The magnitude of the inner product tells you how strongly the patterns align. |
725 | 747 | ;; Large absolute value = strong relationship, small value = unrelated patterns. |
| 748 | +;; |
| 749 | +;; **A clever trick we'll use:** To measure if your signal contains rotation at frequency k, |
| 750 | +;; we'll multiply by the **opposite rotation** (backward/clockwise). This counter-rotation |
| 751 | +;; makes the matching frequency "stand still," turning it into something easy to measure—like |
| 752 | +;; running on a backwards treadmill to check your speed. |
| 753 | + |
| 754 | +;; ### Why N Specific Frequencies? |
| 755 | + |
| 756 | +;; Here's the key mathematical fact: the N rotation speeds we use **don't interfere with each other**. |
| 757 | +;; They're like independent directions—mathematicians call this "orthogonal." |
| 758 | +;; |
| 759 | +;; Let's see this concretely. Create two rotations at different frequencies and compute their inner product: |
| 760 | + |
| 761 | +(def freq-1-rotation (dfn/cos (dfn/* 2.0 Math/PI 1.0 (dfn// (range 8) 8.0)))) |
| 762 | +(def freq-2-rotation (dfn/cos (dfn/* 2.0 Math/PI 2.0 (dfn// (range 8) 8.0)))) |
| 763 | +(def inner-product-diff-freq (dfn/sum (dfn/* freq-1-rotation freq-2-rotation))) |
| 764 | + |
| 765 | +inner-product-diff-freq |
| 766 | + |
| 767 | +;; The result is zero (or very close)! They're **perpendicular** in the same sense |
| 768 | +;; that the x-axis and y-axis are perpendicular. They don't overlap, don't interfere. |
| 769 | +;; |
| 770 | +;; **This is why the DFT works:** |
| 771 | +;; - You have N samples → N independent values to specify |
| 772 | +;; - You need N independent "building blocks" (like needing 3 colors - red, green, blue - to make any color) |
| 773 | +;; - These N rotation frequencies are your building blocks |
| 774 | +;; - They're independent (orthogonal) so measuring one doesn't affect the others |
| 775 | +;; - The inner product cleanly separates them: "How much of frequency k is present?" |
| 776 | +;; |
| 777 | +;; This orthogonality guarantees that: |
| 778 | +;; 1. Any N-sample signal can be built from these N frequencies (completeness) |
| 779 | +;; 2. The decomposition is unique (each frequency component is independent) |
| 780 | +;; 3. Reconstruction works perfectly (no information lost) |
726 | 781 |
|
727 | 782 | ;; ## The DFT Formula: Measuring Alignment with Rotations |
728 | 783 |
|
729 | 784 | ;; Now we can understand what the DFT does. The formula is: |
730 | 785 | ;; |
731 | 786 | ;; **$\text{DFT}[k] = \sum_{n=0}^{N-1} x[n] \cdot e^{-i2\pi kn/N}$** |
732 | 787 | ;; |
| 788 | +;; Notice the **negative** sign in the exponent. This is the key to the "treadmill test." |
| 789 | +;; |
| 790 | +;; **The Treadmill Analogy:** Imagine you want to know if someone is running at exactly 5 mph. |
| 791 | +;; You put them on a treadmill running **backwards** at 5 mph: |
| 792 | +;; - If they're running at exactly 5 mph: they stay in one place (perfect match!) |
| 793 | +;; - If they're running at 4 mph: they drift backwards |
| 794 | +;; - If they're running at 6 mph: they drift forwards |
| 795 | +;; |
| 796 | +;; **The DFT does the same thing:** |
| 797 | +;; - Your signal might be "rotating" at various speeds |
| 798 | +;; - To measure frequency k, you rotate **backwards** (clockwise) at speed k using $e^{-i2\pi kn/N}$ |
| 799 | +;; - If the signal contains that frequency, the counter-rotation makes it "stand still" (becomes constant) |
| 800 | +;; - A constant pattern has large inner product (all values add constructively) |
| 801 | +;; - The magnitude tells you how strong that frequency was |
| 802 | +;; |
| 803 | +;; **The negative sign = "de-rotation"**: We're spinning the coordinate system backwards to see |
| 804 | +;; which frequency appears stationary. This transforms the detection problem into something simple: |
| 805 | +;; measuring a constant (non-rotating) component. |
| 806 | +;; |
733 | 807 | ;; This is an **inner product** between your signal $x[n]$ and rotation $e^{-i2\pi kn/N}$ at frequency $k$. |
734 | 808 | ;; |
735 | 809 | ;; **What it's measuring**: "How much does my signal align with rotation at frequency k?" |
@@ -1049,6 +1123,11 @@ z-rotated |
1049 | 1123 | ;; The reconstruction is perfect (within numerical precision). We've taken eight numbers, |
1050 | 1124 | ;; decomposed them into rotations, and reassembled them—no information lost. |
1051 | 1125 | ;; |
| 1126 | +;; In fact, not only is the signal preserved, but **energy is preserved** too. |
| 1127 | +;; The "energy" (sum of squared values) in the time domain equals the energy in the |
| 1128 | +;; frequency domain (up to a scaling factor). This is called **Parseval's theorem**: |
| 1129 | +;; another consequence of the orthogonality of the DFT basis functions. |
| 1130 | +;; |
1052 | 1131 | ;; This is the power of the Fourier perspective: **different representation, same information, |
1053 | 1132 | ;; new insights**. |
1054 | 1133 |
|
|
0 commit comments