FFT and Numerical Algorithms
In-depth guide to FFT, DFT, Polynomial Multiplication, and Number Theoretic Transform
Fundamental Concepts
Discrete Fourier Transform (DFT)
Transforms a sequence of time-domain values to frequency-domain components. Given sequence , the DFT is a sequence :
where is the -th complex root of unity. Complexity: Naive matrix vector multiplication is .
Fast Fourier Transform (FFT)
An algorithm to compute DFT in . Key Idea: Divide and Conquer. Split polynomial into even and odd coefficients: Evaluate at roots of unity . Symmetry property: . We can compute and using one evaluation of and .
Implementation
Recursive FFT (Cooley-Tukey)
Assumes is a power of 2.
import cmath
def fft(a):
n = len(a)
if n == 1: return a
a_even = a[0::2]
a_odd = a[1::2]
y_even = fft(a_even)
y_odd = fft(a_odd)
y = [0] * n
w_n = cmath.exp(2j * cmath.pi / n)
w = 1
for k in range(n // 2):
y[k] = y_even[k] + w * y_odd[k]
y[k + n // 2] = y_even[k] - w * y_odd[k]
w *= w_n
return yInverse FFT
Recover coefficients from point-values. Formula: Same as FFT but use (conjugate) and divide by .
def ifft(y):
n = len(y)
# Compute FFT using conjugate values
y_conj = [val.conjugate() for val in y]
result = fft(y_conj)
# Scale by n and take conjugate
return [val.conjugate() / n for val in result]Applications
1. Polynomial Multiplication
Multiplying two polynomials of degree takes naively. FFT Approach:
- Point-Value Form: Evaluate and at points using FFT. ().
- Pointwise Mult: . ().
- Interpolation: Convert back to coefficients using Inverse FFT. ().
Total: .
2. Big Integer Multiplication
Large integers can be treated as polynomials (coefficients are digits). Use FFT to multiply numbers with millions of digits (Schönhage-Strassen algorithm).
3. String Matching w/ Wildcards
Can be solved using FFT by encoding characters as numbers and formulating a convolution.
Advanced Concepts
1. Number Theoretic Transform (NTT)
FFT over Finite Fields instead of Complex numbers. Why?: Avoids floating point precision errors. Exact integer arithmetic. Requirement: Modulo must be of form (e.g., ). Root of Unity: Primitive root modulo . .
2. Iterative FFT
Recursive FFT has overhead. Iterative version uses Bit-Reversal Permutation. Swaps element at index with element at bit-reversed . Process layers bottom-up.
Interview Problem Types
Type 1: Polynomial Operations
| Given | Find | Approach |
|---|---|---|
| Two Polynomials | Product | FFT convolution. |
| Large Integers | Product | Convert to digit lists -> FFT -> Carry handling. |
Type 2: Signal Processing (Rare)
| Given | Find | Approach |
|---|---|---|
| Time series | Frequency components | FFT. |
Type 3: Convolutional Problems
| Given | Find | Approach |
|---|---|---|
| Arrays A, B | Array C where | This is definition of convolution. Use FFT. |
Common Pitfalls
Pitfall 1: Array Size Padding
Wrong: Computing FFT of size for product of two degree polynomials. Correct: Product has degree . Must pad arrays with zeros to size nearest power of 2 .
Pitfall 2: Precision Errors
Wrong: Using float for exact integer problems.
Correct: Use NTT or be careful with round() after Inverse FFT.
Pitfall 3: Recursion Depth
Wrong: Deep recursion for large . Correct: Use Iterative FFT for performance.
Quick Reference
- DFT: .
- FFT: .
- Convolution: .
- Roots of Unity: .
- Bit Reversal: Permutation needed for iterative FFT.
Practice Problem Categories
- Multiply Strings: LeetCode (usually solved with naive or Karatsuba, but FFT works).
- Codeforces: Many hard Combinatorics problems rely on NTT (generating functions).