Preptide

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 A=[a0,a1,,an1]A = [a_0, a_1, \dots, a_{n-1}], the DFT is a sequence Y=[y0,y1,,yn1]Y = [y_0, y_1, \dots, y_{n-1}]:

yk=j=0n1ajωnjky_k = \sum_{j=0}^{n-1} a_j \omega_n^{jk}

where ωn=e2πi/n\omega_n = e^{2\pi i / n} is the nn-th complex root of unity. Complexity: Naive matrix vector multiplication is O(n2)O(n^2).

Fast Fourier Transform (FFT)

An algorithm to compute DFT in O(nlogn)O(n \log n). Key Idea: Divide and Conquer. Split polynomial A(x)=a0+a1x++an1xn1A(x) = a_0 + a_1 x + \dots + a_{n-1}x^{n-1} into even and odd coefficients: A(x)=Aeven(x2)+xAodd(x2)A(x) = A_{even}(x^2) + x A_{odd}(x^2) Evaluate at roots of unity ωnk\omega_n^k. Symmetry property: ωnk+n/2=ωnk\omega_n^{k + n/2} = -\omega_n^k. We can compute A(ωnk)A(\omega_n^k) and A(ωnk+n/2)A(\omega_n^{k+n/2}) using one evaluation of AevenA_{even} and AoddA_{odd}.

Implementation

Recursive FFT (Cooley-Tukey)

Assumes nn 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 y

Inverse FFT

Recover coefficients from point-values. Formula: Same as FFT but use ωn1\omega_n^{-1} (conjugate) and divide by nn.

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 nn takes O(n2)O(n^2) naively. FFT Approach:

  1. Point-Value Form: Evaluate A(x)A(x) and B(x)B(x) at 2n2n points using FFT. (O(nlogn)O(n \log n)).
  2. Pointwise Mult: C(xk)=A(xk)B(xk)C(x_k) = A(x_k) \cdot B(x_k). (O(n)O(n)).
  3. Interpolation: Convert CC back to coefficients using Inverse FFT. (O(nlogn)O(n \log n)).

Total: O(nlogn)O(n \log n).

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 Zp\mathbb{Z}_p instead of Complex numbers. Why?: Avoids floating point precision errors. Exact integer arithmetic. Requirement: Modulo pp must be of form c2k+1c \cdot 2^k + 1 (e.g., 998244353998244353). Root of Unity: Primitive root gg modulo pp. ωng(p1)/n(modp)\omega_n \equiv g^{(p-1)/n} \pmod p.

2. Iterative FFT

Recursive FFT has overhead. Iterative version uses Bit-Reversal Permutation. Swaps element at index ii with element at bit-reversed ii. Process layers bottom-up.

Interview Problem Types

Type 1: Polynomial Operations

GivenFindApproach
Two PolynomialsProductFFT convolution.
Large IntegersProductConvert to digit lists -> FFT -> Carry handling.

Type 2: Signal Processing (Rare)

GivenFindApproach
Time seriesFrequency componentsFFT.

Type 3: Convolutional Problems

GivenFindApproach
Arrays A, BArray C where C[k]=A[i]B[ki]C[k] = \sum A[i]B[k-i]This is definition of convolution. Use FFT.

Common Pitfalls

Pitfall 1: Array Size Padding

Wrong: Computing FFT of size nn for product of two degree nn polynomials. Correct: Product has degree 2n2n. Must pad arrays with zeros to size nearest power of 2 2n\ge 2n.

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 NN. Correct: Use Iterative FFT for performance.

Quick Reference

  • DFT: O(N2)O(N^2).
  • FFT: O(NlogN)O(N \log N).
  • Convolution: AB    IFFT(FFT(A)FFT(B))A * B \iff \text{IFFT}(\text{FFT}(A) \cdot \text{FFT}(B)).
  • Roots of Unity: e2πik/ne^{2\pi i k / n}.
  • Bit Reversal: Permutation needed for iterative FFT.

Practice Problem Categories

  • Multiply Strings: LeetCode (usually solved with naive O(N2)O(N^2) or Karatsuba, but FFT works).
  • Codeforces: Many hard Combinatorics problems rely on NTT (generating functions).