Skip to main content
© 2026 ePowerAI. All rights reserved.
CoursesContact
eAI
CoursesContact
Week 14: The Fourier Matrix, FFT, and PCA
Linear Algebra
01Week 1: Vectors and Linear Combinations
02Week 2: Linear Transformations and Matrices
03Week 3: Elimination and LU Factorization
04Week 4: Determinants
05Week 5: Vector Spaces, Independence, and Basis
06Week 6: The Four Fundamental Subspaces
07Week 7: Orthogonality and Projections
08Week 8: Least Squares and QR
09Week 9: Eigenvalues and Eigenvectors
10Week 10: Diagonalization and Markov Matrices
11Week 11: Differential Equations
12Week 12: Symmetric and Positive Definite Matrices
13Week 13: The SVD and Complex Matrices
14Week 14: The Fourier Matrix, FFT, and PCA
Week 14· Linear Algebra22 min read

Week 14: The Fourier Matrix, FFT, and PCA

✦Learning Outcomes
  • Construct the Fourier matrix and explain its role in the discrete Fourier transform
  • Explain how the FFT computes the DFT in O(nlog⁡n)O(n\log n)O(nlogn) instead of O(n2)O(n^2)O(n2)
  • Perform PCA on a dataset using the SVD
  • Interpret principal components as directions of maximum variance
◆Prerequisites

Background knowledge assumed:

  • The singular value decomposition
  • Complex/unitary matrices

Recommended: Review Week 13: The SVD and Complex Matrices before starting.

The Fourier Matrix#

Week 13 closed with unitary matrices — complex analogues of orthogonal matrices that preserve length via UHU=IU^H U = IUHU=I. This week opens with the most important unitary family in signal processing and numerical linear algebra: the Fourier matrix.

Fix an integer n≥1n \ge 1n≥1 and let

ω=e2πi/n\omega = e^{2\pi i / n}ω=e2πi/n

be a primitive nnn-th root of unity (so ωn=1\omega^n = 1ωn=1 and ωk≠1\omega^k \neq 1ωk=1 for 0<k<n0 < k < n0<k<n). The Fourier matrix F∈Cn×nF \in \mathbb{C}^{n \times n}F∈Cn×n has entries

Fjk=ωjk,j,k=0,1,…,n−1F_{jk} = \omega^{jk}, \qquad j,k = 0,1,\ldots,n-1Fjk​=ωjk,j,k=0,1,…,n−1

(using 000-based indexing). Explicitly, row jjj and column kkk hold the power ωjk\omega^{jk}ωjk:

F=(111⋯11ωω2⋯ωn−11ω2ω4⋯ω2(n−1)⋮⋮⋮⋱⋮1ωn−1ω2(n−1)⋯ω(n−1)2).F = \begin{pmatrix} 1 & 1 & 1 & \cdots & 1 \\ 1 & \omega & \omega^2 & \cdots & \omega^{n-1} \\ 1 & \omega^2 & \omega^4 & \cdots & \omega^{2(n-1)} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 1 & \omega^{n-1} & \omega^{2(n-1)} & \cdots & \omega^{(n-1)^2} \end{pmatrix}.F=​111⋮1​1ωω2⋮ωn−1​1ω2ω4⋮ω2(n−1)​⋯⋯⋯⋱⋯​1ωn−1ω2(n−1)⋮ω(n−1)2​​.

Multiplying a vector xxx by FFF produces the discrete Fourier transform (DFT):

x^=Fx,x^j=∑k=0n−1xk ωjk.\hat{x} = Fx, \qquad \hat{x}_j = \sum_{k=0}^{n-1} x_k\, \omega^{jk}.x^=Fx,x^j​=k=0∑n−1​xk​ωjk.

Each frequency bin x^j\hat{x}_jx^j​ is the inner product of xxx against a pure complex exponential of frequency jjj. The inverse transform recovers xxx from x^\hat{x}x^ by conjugation (up to scaling): x=1nF‾ x^x = \frac{1}{n} \overline{F}\,\hat{x}x=n1​Fx^.

Unitary (up to scaling). The columns of FFF are the discrete complex exponentials

fk=(1,  ωk,  ω2k,  …,  ω(n−1)k)T.f_k = \bigl(1,\; \omega^k,\; \omega^{2k},\; \ldots,\; \omega^{(n-1)k}\bigr)^T.fk​=(1,ωk,ω2k,…,ω(n−1)k)T.

These columns are orthogonal with respect to the complex inner product: fjHfk=nf_j^H f_k = nfjH​fk​=n when j≡k(modn)j \equiv k \pmod nj≡k(modn) and 000 otherwise. Equivalently,

FHF=n I.F^H F = n\, I.FHF=nI.

Scaling by 1/n1/\sqrt{n}1/n​ produces a truly unitary matrix 1nF\frac{1}{\sqrt{n}} Fn​1​F with (1nF)H(1nF)=I\bigl(\frac{1}{\sqrt{n}} F\bigr)^H\bigl(\frac{1}{\sqrt{n}} F\bigr) = I(n​1​F)H(n​1​F)=I. So FFF itself is unitary up to that standard factor — the complex cousin of an orthogonal change of basis.

Circulant connection. A circulant matrix is constant on every wrap-around diagonal: each row is a right cyclic shift of the row above. Remarkably, every n×nn \times nn×n circulant matrix is diagonalized by the same Fourier matrix FFF. The columns of FFF are simultaneous eigenvectors of the entire circulant family. That is why convolutions (which become multiplications after a DFT) and many shift-invariant filters are natural in the Fourier basis.

Tiny example. For n=2n = 2n=2, ω=eπi=−1\omega = e^{\pi i} = -1ω=eπi=−1, so

F=(111−1).F = \begin{pmatrix} 1 & 1 \\ 1 & -1 \end{pmatrix}.F=(11​1−1​).

For n=4n = 4n=4, ω=i\omega = iω=i and the second column is (1,i,−1,−i)T(1, i, -1, -i)^T(1,i,−1,−i)T. Direct matrix–vector multiplication costs O(n2)O(n^2)O(n2) arithmetic — fine for n=4n = 4n=4, painful for n=106n = 10^6n=106. The next section is about doing the same product much faster.


The Fast Fourier Transform#

A naive product FxFxFx walks every entry of FFF and every component of xxx, which is Θ(n2)\Theta(n^2)Θ(n2) work. The FFTFast Fourier Transform (Fast Fourier Transform) is a family of algorithms that compute the same DFT in O(nlog⁡n)O(n\log n)O(nlogn) operations when nnn is a power of two (and with similar near-linear cost for highly composite nnn).

The key is a divide-and-conquer factorization of FnF_nFn​. Split the input into even and odd indices:

xeven=(x0,x2,…,xn−2),xodd=(x1,x3,…,xn−1).x_{\text{even}} = (x_0, x_2, \ldots, x_{n-2}), \qquad x_{\text{odd}} = (x_1, x_3, \ldots, x_{n-1}).xeven​=(x0​,x2​,…,xn−2​),xodd​=(x1​,x3​,…,xn−1​).

Each of those half-length vectors has a DFT of size n/2n/2n/2. The Cooley–Tukey identity says the full DFT can be assembled from the two half-size DFTs with only O(n)O(n)O(n) extra multiplications by “twiddle factors” ωj\omega^jωj:

x^j=xeven^j+ωj xodd^j,x^j+n/2=xeven^j−ωj xodd^j\hat{x}_j = \widehat{x_{\text{even}}}_j + \omega^j\, \widehat{x_{\text{odd}}}_j, \qquad \hat{x}_{j+n/2} = \widehat{x_{\text{even}}}_j - \omega^j\, \widehat{x_{\text{odd}}}_jx^j​=xeven​​j​+ωjxodd​​j​,x^j+n/2​=xeven​​j​−ωjxodd​​j​

for j=0,…,n/2−1j = 0,\ldots,n/2-1j=0,…,n/2−1 (indices of the half-size transforms taken modulo n/2n/2n/2). In matrix language, FnF_nFn​ factors into a product involving a permutation (even/odd reordering), a block-diagonal matrix with two copies of Fn/2F_{n/2}Fn/2​, and a sparse diagonal of twiddles glued by an n×nn \times nn×n “butterfly” step.

Complexity. Let T(n)T(n)T(n) be the cost of an nnn-point FFT. The recurrence is

T(n)=2 T(n/2)+O(n),T(1)=O(1).T(n) = 2\, T(n/2) + O(n), \qquad T(1) = O(1).T(n)=2T(n/2)+O(n),T(1)=O(1).

Unrolling gives T(n)=O(nlog⁡n)T(n) = O(n\log n)T(n)=O(nlogn) — each of log⁡2n\log_2 nlog2​n levels costs O(n)O(n)O(n) work across the whole tree. Compared with the O(n2)O(n^2)O(n2) direct matrix product, that is the difference between “impossible at audio or image scale” and “routine in real time.”

You do not need a full derivation of every butterfly diagram to use the idea: the Fourier matrix is structured; the structure is recursive even/odd splitting; recursion plus O(n)O(n)O(n) combine steps yields O(nlog⁡n)O(n\log n)O(nlogn). Libraries such as numpy.fft.fft implement carefully optimized variants of this idea (and more general factorizations when nnn is not a power of two).


Principal Component Analysis#

Shift from frequency bases to data geometry. PCAPrincipal Component Analysis (Principal Component Analysis) finds orthonormal directions in feature space along which a dataset varies the most. It is the statistical reading of the SVD from Week 13.

Setup. Collect mmm observations of nnn features into a data matrix X∈Rm×nX \in \mathbb{R}^{m \times n}X∈Rm×n, with rows as observations and columns as features. (Images, sensor readings, word counts — any tabular cloud of points works.)

Center the data. Subtract the sample mean of each column so the cloud sits at the origin:

X~=X−1μT,μj=1m∑i=1mXij.\tilde{X} = X - \mathbf{1}\mu^T, \qquad \mu_j = \frac{1}{m}\sum_{i=1}^{m} X_{ij}.X~=X−1μT,μj​=m1​i=1∑m​Xij​.

Without centering, the first “component” often just points toward the mean rather than along the spread of the data.

SVD of the centered matrix. Compute

X~=UΣVT\tilde{X} = U\Sigma V^TX~=UΣVT

with orthogonal UUU (m×mm \times mm×m or thin), diagonal singular values σ1≥σ2≥⋯≥0\sigma_1 \ge \sigma_2 \ge \cdots \ge 0σ1​≥σ2​≥⋯≥0, and orthogonal VVV (n×nn \times nn×n). The principal components are the columns of VVV — the right singular vectors — ordered by decreasing singular value. Column v1v_1v1​ is the direction of greatest variance; v2v_2v2​ is the next, orthogonal to v1v_1v1​; and so on.

Why “maximum variance”? For a unit vector w∈Rnw \in \mathbb{R}^nw∈Rn, the sample variance of the projected (centered) data is

1m−1∥X~w∥2=1m−1 wT(X~TX~)w.\frac{1}{m-1}\|\tilde{X} w\|^2 = \frac{1}{m-1}\, w^T(\tilde{X}^T\tilde{X})w.m−11​∥X~w∥2=m−11​wT(X~TX~)w.

The matrix X~TX~\tilde{X}^T\tilde{X}X~TX~ is symmetric positive semidefinite. By the spectral theorem (Week 12) and the SVD link X~TX~=VΣTΣVT\tilde{X}^T\tilde{X} = V\Sigma^T\Sigma V^TX~TX~=VΣTΣVT, its leading eigenvector is v1v_1v1​ and the maximum of ∥X~w∥2\|\tilde{X} w\|^2∥X~w∥2 over ∥w∥=1\|w\|=1∥w∥=1 is σ12\sigma_1^2σ12​. Each subsequent principal component solves the same problem in the orthogonal complement of the previous ones.

Scores. The coordinates of the data in the principal-component basis are the rows of X~V=UΣ\tilde{X}V = U\SigmaX~V=UΣ. Keeping only the first kkk columns of VVV projects every observation onto a kkk-dimensional subspace spanned by the top principal components.


Variance and Dimensionality Reduction#

Singular values quantify how much structure each principal component captures. Because

∥X~∥F2=∑i=1rσi2\|\tilde{X}\|_F^2 = \sum_{i=1}^{r} \sigma_i^2∥X~∥F2​=i=1∑r​σi2​

(with r=rank⁡(X~)r = \operatorname{rank}(\tilde{X})r=rank(X~)), the fraction of variance explained by principal component iii is

σi2∑jσj2.\frac{\sigma_i^2}{\sum_j \sigma_j^2}.∑j​σj2​σi2​​.

The cumulative fraction for the first kkk components is (∑i=1kσi2)/(∑jσj2)\bigl(\sum_{i=1}^{k}\sigma_i^2\bigr)/\bigl(\sum_j\sigma_j^2\bigr)(∑i=1k​σi2​)/(∑j​σj2​). If that number is 0.950.950.95, the top kkk directions retain 95% of the total (centered) energy of the data.

Low-rank approximation. Truncating the SVD to the top kkk singular values produces

X~k=UkΣkVkT,\tilde{X}_k = U_k \Sigma_k V_k^T,X~k​=Uk​Σk​VkT​,

the best rank-kkk approximation of X~\tilde{X}X~ in both Frobenius and spectral norms (Eckart–Young, previewed in Week 13). PCA as dimensionality reduction is exactly this truncation: store the n×kn \times kn×k matrix VkV_kVk​ and the m×km \times km×k scores UkΣkU_k\Sigma_kUk​Σk​, and reconstruct approximately when needed.

Practice sketch. Suppose centered 2-D data has singular values σ1=3\sigma_1 = 3σ1​=3 and σ2=1\sigma_2 = 1σ2​=1. Then

σ12σ12+σ22=910=0.9,σ22σ12+σ22=0.1.\frac{\sigma_1^2}{\sigma_1^2+\sigma_2^2} = \frac{9}{10} = 0.9, \qquad \frac{\sigma_2^2}{\sigma_1^2+\sigma_2^2} = 0.1.σ12​+σ22​σ12​​=109​=0.9,σ12​+σ22​σ22​​=0.1.

Ninety percent of the variance lies along PC1. Projecting onto that single axis compresses each point from two numbers to one while losing only 10% of the energy — often an excellent trade for visualization or noise filtering.

In high dimensions the same arithmetic applies: many datasets are approximately low-rank after centering, so a handful of principal components replace hundreds of raw features. The browser lab below runs PCA via np.linalg.svd on a synthetic correlated cloud and prints the explained-variance ratios.


Course Recap#

Fourteen weeks, one throughline: factorizations that turn hard linear problems into easy ones.

  • Elimination (LULULU) — Weeks 2–4. Gaussian elimination factors A=LUA = LUA=LU (with pivots and permutations when needed) so that Ax=bAx = bAx=b becomes two triangular solves. The algebra of row operations becomes a product of elementary matrices.
  • Orthogonalization (QRQRQR) — Weeks 7–8. Gram–Schmidt and Householder build A=QRA = QRA=QR with orthonormal columns in QQQ. Least squares min⁡∥Ax−b∥\min\|Ax-b\|min∥Ax−b∥ stabilizes into solving Rx=QTbRx = Q^TbRx=QTb instead of forming the often-ill-conditioned normal equations alone.
  • Eigendecomposition — Weeks 9–12. A=SΛS−1A = S\Lambda S^{-1}A=SΛS−1 (and A=QΛQTA = Q\Lambda Q^TA=QΛQT when AAA is symmetric) explains powers AkA^kAk, differential systems, quadratic forms, and positive definiteness. Dynamics become independent modes along eigenvectors.
  • The SVD — Week 13. A=UΣVTA = U\Sigma V^TA=UΣVT works for every matrix, square or not. It unifies and generalizes the spectral picture: singular values replace eigenvalues when symmetry or squareness is missing.
  • This week. The Fourier matrix is a structured unitary (up to scale) change of basis that diagonalizes every circulant operator; the FFT makes that change cheap. PCA reads the SVD of centered data as variance-maximizing coordinates — the same VVV and σi\sigma_iσi​ you already know, reinterpreted for statistics and compression.

If you remember only one sentence from the course: choose the right factorization, and the geometry of the problem becomes visible. LULULU for systems, QRQRQR for least squares, eigenvalues for dynamics, SVD for almost everything else — including the Fourier and PCA tools that close the loop into applications.


Knowledge check#

Exercise · Multiple choice

The FFT computes the discrete Fourier transform of n points in what time complexity, compared to the O(n²) direct approach?

O(n log n)
O(n)
O(n³)
O(log n)

Browser lab#

Run an FFT on a synthetic signal, then PCA on synthetic 2D data via the SVD.

python · runs in browser
import numpy as np
import matplotlib.pyplot as plt

# Part 1: FFT
t = np.linspace(0, 1, 256, endpoint=False)
signal = np.sin(2 * np.pi * 5 * t) + 0.5 * np.sin(2 * np.pi * 20 * t)
spectrum = np.fft.fft(signal)
freqs = np.fft.fftfreq(len(t), d=t[1] - t[0])

# Part 2: PCA via SVD
rng = np.random.default_rng(0)
mean = [0, 0]
cov = [[3, 1.5], [1.5, 1]]
data = rng.multivariate_normal(mean, cov, size=200)
data_centered = data - data.mean(axis=0)
U, S, Vt = np.linalg.svd(data_centered, full_matrices=False)
explained_variance_ratio = (S ** 2) / np.sum(S ** 2)

print("explained variance ratio =", explained_variance_ratio)

fig, axes = plt.subplots(1, 2, figsize=(11, 4.5))
axes[0].plot(freqs[freqs >= 0], np.abs(spectrum[freqs >= 0]))
axes[0].set_title("FFT magnitude spectrum")
axes[0].set_xlabel("frequency (Hz)")

axes[1].scatter(data_centered[:, 0], data_centered[:, 1], alpha=0.4, s=10)
for i in range(2):
    v = Vt[i] * S[i] / np.sqrt(len(data))
    axes[1].plot([0, v[0]], [0, v[1]], linewidth=2,
                 label=f"PC{i+1} ({explained_variance_ratio[i]*100:.1f}%)")
axes[1].set_aspect("equal")
axes[1].legend()
axes[1].set_title("Principal components")
plt.tight_layout()
plt.show()

Part 1 builds a sum of 5 Hz and 20 Hz sines and plots the magnitude of np.fft.fft against non-negative frequencies — expect clear peaks at those two bins. Part 2 draws a correlated Gaussian cloud, centers it, runs np.linalg.svd, and overlays the principal directions scaled by singular values. The printed explained_variance_ratio should sum to 111 and put most of the mass on PC1, matching the elongated shape of the scatter.


Quiz#

Question 1 of 3

In PCA, the principal components are the columns of ___ in the SVD of the (centered) data matrix.

← Previous
Week 13: The SVD and Complex Matrices
On this page
  • The Fourier Matrix
  • The Fast Fourier Transform
  • Principal Component Analysis
  • Variance and Dimensionality Reduction
  • Course Recap
  • Knowledge check
  • Browser lab
  • Quiz