@@ -653,7 +653,7 @@ z-rotated
653653; ; assumption of periodicity, so it requires multiple basis frequencies to approximate.
654654; ;
655655; ; **Solutions**:
656- ; ; 1. **Windowing**: Apply Hann/Hamming window to reduce sidelobes
656+ ; ; 1. **Windowing**: Apply Hann/Hamming window to reduce sidelobes (we'll explore this technique later)
657657; ; 2. **Zero-padding**: Increase FFT size to create finer frequency bins
658658; ; 3. **Interpolation**: Use parabolic interpolation to estimate true peak location
659659; ;
@@ -664,11 +664,19 @@ z-rotated
664664; ; Before we see how the DFT computes its coefficients, we need one key mathematical idea:
665665; ; **How do we measure if two patterns "align"**?
666666; ;
667- ; ; The answer is the **inner product** (also called dot product):
667+ ; ; The answer is the **inner product** (also called dot product). For complex numbers,
668+ ; ; we use the **conjugate** of the first pattern:
668669; ;
669- ; ; **$\langle a, b \rangle = \sum_{n} a_n \cdot b_n$**
670+ ; ; **$\langle a, b \rangle = \sum_{n} \overline{ a_n} \cdot b_n$**
670671; ;
671- ; ; Multiply corresponding elements and add them up. This simple operation has deep geometric meaning:
672+ ; ; The bar over $a_n$ means complex conjugate: flip the sign of the imaginary part.
673+ ; ;
674+ ; ; For real numbers, the conjugate does nothing, so this reduces to ordinary multiplication.
675+ ; ; For complex numbers (rotations), conjugating reverses the rotation direction—this
676+ ; ; "counter-rotation" makes matching frequencies "stand still," turning them into
677+ ; ; something easy to measure.
678+ ; ;
679+ ; ; This operation has deep geometric meaning:
672680; ;
673681; ; - **Aligned patterns** (move together): large positive sum
674682; ; - **Perpendicular patterns** (unrelated): sum ≈ 0
@@ -704,22 +712,19 @@ z-rotated
704712 :inner-product (format " %.2f" inner-opposite)
705713 :meaning " Patterns move inversely" }])
706714
707- ; ; **This is exactly correlation**: measuring whether two sequences "march together."
715+ ; ; **This is similar to correlation**: measuring whether two sequences "march together."
716+ ; ; (Correlation also involves standardization, but the core idea is the same.)
708717; ;
709718; ; **Key insight**: The magnitude of the inner product tells you how strongly the patterns align.
710719; ; Large absolute value = strong relationship, small value = unrelated patterns.
711- ; ;
712- ; ; **A clever trick we'll use:** To measure if your signal contains rotation at frequency k,
713- ; ; we'll multiply by the **opposite rotation** (backward/clockwise). This counter-rotation
714- ; ; makes the matching frequency "stand still," turning it into something easy to measure—like
715- ; ; running on a backwards treadmill to check your speed.
716720
717721; ; ### Why N Specific Frequencies?
718722
719723; ; Here's the key mathematical fact: the N rotation speeds we use **don't interfere with each other**.
720724; ; They're like independent directions—mathematicians call this "orthogonal."
721725; ;
722- ; ; Let's see this concretely. Create two rotations at different frequencies and compute their inner product:
726+ ; ; Let's see this concretely. Take the real parts (cosine components) of two rotations
727+ ; ; at different frequencies and compute their inner product:
723728
724729(def freq-1-rotation (dfn/cos (dfn/* 2.0 Math/PI 1.0 (dfn// (range 8 ) 8.0 ))))
725730(def freq-2-rotation (dfn/cos (dfn/* 2.0 Math/PI 2.0 (dfn// (range 8 ) 8.0 ))))
@@ -799,16 +804,17 @@ inner-product-diff-freq
799804
800805(def manual-k1 (manual-dft-component temperatures 1 ))
801806
802- (kind/hiccup
803- [:div
804- [:p [:strong " Manual computation of DFT[1]:" ]]
805- [:ul
806- [:li (str " Real part: " (format " %.4f" (:real manual-k1)))]
807- [:li (str " Imaginary part: " (format " %.4f" (:imag manual-k1)))]
808- [:li (str " Magnitude: " (format " %.4f"
809- (Math/sqrt (+ (* (:real manual-k1) (:real manual-k1))
810- (* (:imag manual-k1) (:imag manual-k1))))))]]
811- [:p " Compare with library result: " (format " %.4f" (:magnitude (nth temp-analysis 1 )))]])
807+ (kind/table
808+ [{:component " Real part"
809+ :value (format " %.4f" (:real manual-k1))}
810+ {:component " Imaginary part"
811+ :value (format " %.4f" (:imag manual-k1))}
812+ {:component " Magnitude"
813+ :value (format " %.4f"
814+ (Math/sqrt (+ (* (:real manual-k1) (:real manual-k1))
815+ (* (:imag manual-k1) (:imag manual-k1)))))}
816+ {:component " Library result (for comparison)"
817+ :value (format " %.4f" (:magnitude (nth temp-analysis 1 )))}])
812818
813819; ; The formula is doing exactly what we said: measuring how well the signal matches each rotation.
814820; ; ## Windowing and Edge Effects: The Implicit Assumption
0 commit comments