Skip to content
← All notes
12 min read

The Graph Fourier Transform: From Sinusoids to Eigenvectors

Signal Processing Graph Theory Linear Algebra

The ordinary Fourier transform decomposes a signal into frequencies, and “frequency” makes intuitive sense when your signal lives on a line or a circle: it’s how fast a sine wave oscillates as you walk along that line. But plenty of data doesn’t live on a line. Sensor readings sit on the nodes of a sensor network. Traffic measurements sit on a road graph. A signal on a social network is one number per user, connected in whatever irregular way friendships happen to connect them. There’s no natural direction to walk in, so “how fast does this oscillate” stops meaning anything obvious.

And yet there’s a well defined way to talk about frequency on a graph, and it turns out to be exactly the machinery from the last article. The eigenvectors of the graph Laplacian play the same role that sine and cosine waves play for ordinary Fourier analysis, and the connection isn’t just an analogy, it’s the same underlying idea (decomposing a signal into the eigenbasis of a particular operator) applied to two different domains, one continuous and one discrete.


Part 1: what frequency actually is

Start with a periodic function ff on the circle, meaning f(x)=f(x+2π)f(x) = f(x + 2\pi). The building blocks of its Fourier series are the complex exponentials eikxe^{ikx} for integer kk. Differentiate one twice:

ddxeikx=ikeikx,d2dx2eikx=(ik)2eikx=k2eikx\frac{d}{dx} e^{ikx} = ik \, e^{ikx}, \qquad \frac{d^2}{dx^2} e^{ikx} = (ik)^2 e^{ikx} = -k^2 e^{ikx}

So eikxe^{ikx} is an eigenfunction of the second-derivative operator, with eigenvalue k2-k^2. Flip the sign and write L=d2dx2\mathcal{L} = -\dfrac{d^2}{dx^2} (calling it L\mathcal{L} deliberately, this is the continuous Laplacian), and

Leikx=k2eikx\mathcal{L} \, e^{ikx} = k^2 \, e^{ikx}

This is the entire content of the claim “sinusoids are the natural frequency basis”: they are, quite literally, the eigenfunctions of the Laplacian operator, and the eigenvalue k2k^2 is what we’ve been informally calling the frequency squared. The Fourier transform isn’t a separate piece of machinery bolted onto calculus, it’s an eigendecomposition.

Why the Laplacian specifically, and not some other operator? Because L\mathcal{L} measures local roughness. For a function ff, the Dirichlet energy f(x)2dx\int |f'(x)|^2 \, dx quantifies how much ff oscillates: a flat function has zero Dirichlet energy, a wildly oscillating one has a large one. Expand ff in its Fourier series, f(x)=kckeikxf(x) = \sum_k c_k e^{ikx}, differentiate term by term, and use the orthogonality relation 02πeikxeijxdx=2πδkj\int_0^{2\pi} e^{ikx} e^{-ijx}\,dx = 2\pi \, \delta_{kj}:

02πf(x)2dx=kjckcj(ik)(ij)02πei(kj)xdx=2πkk2ck2\int_0^{2\pi} |f'(x)|^2\, dx = \sum_k \sum_j c_k \overline{c_j} (ik)(\overline{ij}) \int_0^{2\pi} e^{i(k-j)x}\,dx = 2\pi \sum_k k^2 |c_k|^2

The cross terms vanish by orthogonality, and what survives is a direct correspondence: the roughness of ff is exactly a weighted sum of its Fourier coefficients, weighted by k2k^2, the eigenvalue attached to each mode. High-frequency modes carry more of the roughness, low-frequency modes carry less, and the constant mode k=0k=0 carries none at all. Frequency, roughness, and eigenvalue of the Laplacian are three names for the same quantity.

That last identity is the thread to pull on. It doesn’t actually use anything about the circle specifically, translation invariance, periodicity, none of it enters the argument. All it needs is an operator that measures roughness and a basis that diagonalises it. A graph has no translations to speak of, but it absolutely has a notion of roughness, and it has an operator to match.

A sine wave next to its second derivative, showing the second derivative is the negative of the original scaled by k squared


Part 2: the graph version

A graph signal is just a function f:VRf : V \to \mathbb{R}, one real number per vertex. The graph Laplacian from before, L=DAL = D - A, is the discrete stand-in for L\mathcal{L}, and the parallel to Dirichlet energy is immediate. For any signal ff,

fLf=(i,j)E(fifj)2f^\top L f = \sum_{(i,j) \in E} (f_i - f_j)^2

This is a direct calculation: fLf=fDffAf=idifi2(i,j)E2fifjf^\top L f = f^\top D f - f^\top A f = \sum_i d_i f_i^2 - \sum_{(i,j)\in E} 2 f_i f_j, and regrouping the sum edge by edge turns this into (i,j)E(fifj)2\sum_{(i,j)\in E}(f_i-f_j)^2. It’s non-negative for every ff (it’s a sum of squares), which is why LL is positive semidefinite, and it’s the exact discrete analogue of f2dx\int |f'|^2\,dx: instead of measuring how much ff changes over an infinitesimal step along a line, it measures how much ff changes across each edge of the graph.

Because LL is real and symmetric, the spectral theorem guarantees an orthonormal basis of eigenvectors u1,,unu_1, \dots, u_n with real eigenvalues 0=λ1λ2λn0 = \lambda_1 \le \lambda_2 \le \cdots \le \lambda_n. Collect the eigenvectors as columns of an orthogonal matrix UU. The Graph Fourier Transform of a signal ff is defined as

f^=Uf,f=Uf^=kf^kuk\hat{f} = U^\top f, \qquad f = U \hat{f} = \sum_k \hat{f}_k \, u_k

exactly mirroring the Fourier series, a signal written as a weighted sum of fixed basis modes. And because f=Uf^f = U\hat{f} diagonalises the quadratic form,

fLf=(Uf^)L(Uf^)=f^(ULU)f^=f^Λf^=kλkf^k2f^\top L f = (U\hat f)^\top L (U\hat f) = \hat f^\top (U^\top L U) \hat f = \hat f^\top \Lambda \hat f = \sum_k \lambda_k \, \hat{f}_k^2

which is the discrete Parseval identity: total roughness equals the sum of squared Fourier coefficients weighted by eigenvalue, the same relationship derived above for the circle, except the finite-dimensional version falls out in one line of linear algebra instead of an integration by parts. The eigenvalue λk\lambda_k is the graph’s notion of k2k^2: small λk\lambda_k means the eigenvector uku_k is nearly constant across every edge (low frequency, smooth), large λk\lambda_k means uku_k flips sign or swings wildly between neighbours (high frequency, rough). The smallest eigenvalue is always λ1=0\lambda_1 = 0, achieved by the constant vector (every row of LL sums to zero), playing the role of the k=0k=0 DC component in the continuous case.


Part 3: an exact case where the analogy is not an analogy

For most graphs the eigenvectors of LL have no closed form, you compute them numerically and that’s that. But for one important family, the cycle graph CnC_n (vertices 0,,n10, \dots, n-1 arranged in a ring, each connected to its two neighbours), the eigenvectors work out exactly, and they turn out to be the classical discrete Fourier basis itself.

The Laplacian of CnC_n has a special structure: every row is the previous row shifted over by one, because every vertex looks identical to every other vertex up to relabelling. A matrix with this property is called circulant: Cjk=c(kj)modnC_{jk} = c_{(k-j)\bmod n} for some fixed sequence c0,,cn1c_0, \dots, c_{n-1} (the “first row”).

Claim. Every circulant matrix has eigenvectors vm=(1,ωm,ω2m,,ω(n1)m)v_m = (1, \omega^m, \omega^{2m}, \dots, \omega^{(n-1)m}), for m=0,,n1m = 0, \dots, n-1, where ω=e2πi/n\omega = e^{2\pi i/n}, with eigenvalue μm=l=0n1clωml\mu_m = \sum_{l=0}^{n-1} c_l \, \omega^{ml}.

Proof. Compute the jj-th entry of CvmCv_m directly:

(Cvm)j=k=0n1Cjk(vm)k=k=0n1c(kj)modnωmk(Cv_m)_j = \sum_{k=0}^{n-1} C_{jk} (v_m)_k = \sum_{k=0}^{n-1} c_{(k-j)\bmod n} \, \omega^{mk}

Substitute l=(kj)modnl = (k-j) \bmod n, so kj+l(modn)k \equiv j + l \pmod n and ωmk=ωm(j+l)=ωmjωml\omega^{mk} = \omega^{m(j+l)} = \omega^{mj}\omega^{ml} (this holds even across the wraparound because ωn=1\omega^n = 1). As kk ranges over 0,,n10, \dots, n-1, ll ranges over the same set, so

(Cvm)j=l=0n1clωmjωml=ωmjl=0n1clωml=μm(vm)j(Cv_m)_j = \sum_{l=0}^{n-1} c_l \, \omega^{mj}\omega^{ml} = \omega^{mj} \sum_{l=0}^{n-1} c_l \,\omega^{ml} = \mu_m \, (v_m)_j

for every jj, so Cvm=μmvmCv_m = \mu_m v_m. \blacksquare

This proof used nothing about CnC_n specifically, it’s a general fact about any circulant matrix. Now apply it. The Laplacian of CnC_n has first row c0=2c_0 = 2 (the degree), c1=1c_1 = -1 (the clockwise neighbour), cn1=1c_{n-1} = -1 (the counterclockwise neighbour), and zero everywhere else. Plugging into the formula for μm\mu_m:

μm=2ωmωm=22cos ⁣(2πmn)=4sin2 ⁣(πmn)\mu_m = 2 - \omega^m - \omega^{-m} = 2 - 2\cos\!\left(\frac{2\pi m}{n}\right) = 4\sin^2\!\left(\frac{\pi m}{n}\right)

using ωm+ωm=2cos(2πm/n)\omega^m + \omega^{-m} = 2\cos(2\pi m/n) and the half-angle identity 1cosθ=2sin2(θ/2)1 - \cos\theta = 2\sin^2(\theta/2). So the eigenvalues of the cycle Laplacian are λm=4sin2(πm/n)\lambda_m = 4\sin^2(\pi m/n), and the eigenvectors are vm(j)=ωmj=e2πimj/nv_m(j) = \omega^{mj} = e^{2\pi i mj/n}: the exact complex exponential basis of the classical discrete Fourier transform, on the nose. On a cycle, the Graph Fourier Transform is the DFT, not an analogue of it. (Pairing up mm and nmn-m, which share the same eigenvalue since sin2\sin^2 is symmetric about π/2\pi/2, and taking real and imaginary parts recovers real sine and cosine eigenvectors, exactly as combining eikxe^{ikx} and eikxe^{-ikx} recovers real sinusoids in the continuous case.)

As a check, take n=4n=4: λm=4sin2(πm/4)\lambda_m = 4\sin^2(\pi m/4) gives λ0=0\lambda_0 = 0, λ1=412=2\lambda_1 = 4 \cdot \tfrac12 = 2, λ2=41=4\lambda_2 = 4 \cdot 1 = 4, λ3=412=2\lambda_3 = 4 \cdot \tfrac12 = 2. Four vertices, eigenvalues {0,2,4,2}\{0, 2, 4, 2\}, one zero mode, two mirror-image frequency-1 modes at λ=2\lambda = 2, and one fastest-oscillating mode at λ=4\lambda = 4 where adjacent vertices alternate sign. That last one is the graph equivalent of the highest frequency a 4-sample signal can represent, the discrete analogue of the Nyquist limit.


Part 4: a worked example on an irregular graph

Cycles are convenient because of the symmetry, but the whole point of the graph Fourier transform is that it works on graphs with no symmetry at all. The diamond graph from the spanning tree article (vertices 1,2,3,41,2,3,4, edges 12,13,14,23,2412,13,14,23,24) has less symmetry than a cycle but still enough to get a clean answer by hand, using its automorphisms directly: swapping vertices 121 \leftrightarrow 2 leaves the graph unchanged, and so does swapping 343 \leftrightarrow 4, independently. Any eigenvector must be symmetric or antisymmetric under each of those swaps, which splits the 4×44\times 4 eigenvalue problem into small independent pieces.

Solving each piece (the algebra is routine, so only the results are shown) gives eigenvalues {0,2,4,4}\{0, 2, 4, 4\} with orthogonal eigenvectors

u1=12(1,1,1,1),u2=12(0,0,1,1),u3=12(1,1,1,1),u4=12(1,1,0,0)u_1 = \tfrac{1}{2}(1,1,1,1), \quad u_2 = \tfrac{1}{\sqrt2}(0,0,1,-1), \quad u_3 = \tfrac{1}{2}(1,1,-1,-1), \quad u_4 = \tfrac{1}{\sqrt2}(1,-1,0,0)

u1u_1 is the constant mode, zero frequency, as always. u2u_2 oscillates only between the two low-degree vertices 33 and 44. u3u_3 and u4u_4 both sit at the top eigenvalue λ=4\lambda = 4, the fastest disagreement the graph can support, one splitting the high-degree pair from the low-degree pair, the other splitting the two high-degree vertices from each other.

Take a signal, say a temperature reading at each vertex: f=(10,8,3,1)f = (10, 8, 3, 1). Its graph Fourier transform is f^=Uf\hat f = U^\top f:

f^1=u1f=12(22)=11,f^2=u2f=12(2)=2\hat f_1 = u_1 \cdot f = \tfrac12(22) = 11, \quad \hat f_2 = u_2\cdot f = \tfrac{1}{\sqrt2}(2) = \sqrt2 f^3=u3f=12(14)=7,f^4=u4f=12(2)=2\hat f_3 = u_3\cdot f = \tfrac12(14) = 7, \quad \hat f_4 = u_4\cdot f = \tfrac{1}{\sqrt2}(2) = \sqrt2

The dominant coefficient is f^1=11\hat f_1 = 11, the mean level of the signal, exactly as the DC term dominates a smooth continuous signal. The two λ=4\lambda=4 coefficients are comparatively small, meaning the signal doesn’t disagree much between the high-degree pair or between the low-degree pair, most of the actual variation is captured by the low and mid frequency terms.

Low-pass filtering. Attenuating the high-frequency coefficients and reconstructing is exactly what a graph low-pass filter does. Zeroing out the λ=4\lambda=4 terms entirely and inverting:

ffiltered=f^1u1+f^2u2=1112(1,1,1,1)+212(0,0,1,1)=(5.5,5.5,6.5,4.5)f_{\text{filtered}} = \hat f_1 u_1 + \hat f_2 u_2 = 11\cdot\tfrac12(1,1,1,1) + \sqrt2\cdot\tfrac{1}{\sqrt2}(0,0,1,-1) = (5.5,\, 5.5,\, 6.5,\, 4.5)

The sharp local disagreements are smoothed out while the overall shape of the signal (high near vertices 1,2, tapering toward 3,4) survives. This is the same operation as blurring an image, just performed on an arbitrary graph instead of a pixel grid.

The diamond graph with four small panels showing each eigenvector as vertex colours, from smooth uniform colour to alternating colours


Part 5: filtering is diffusion

The low-pass filter above was done by hand, picking which coefficients to zero out. There’s a more principled way to choose the attenuation, and it comes from the same operator playing a third role: governing diffusion.

The continuous heat equation u/t=Lu\partial u/\partial t = -\mathcal{L}u describes how heat spreads out over time. Solved in the Fourier basis, each mode decays independently: u(x,t)=kck(0)ek2teikxu(x,t) = \sum_k c_k(0) \, e^{-k^2 t} \, e^{ikx}, high-frequency components (large k2k^2) die out fast, low-frequency components persist. That’s why heat diffusion looks like blurring: it’s a low-pass filter that runs continuously in time rather than being applied in one discrete step.

The graph version is identical in structure. The graph heat equation u˙=Lu\dot u = -Lu has solution u(t)=etLu(0)u(t) = e^{-tL} u(0), and expanding in the eigenbasis,

u(t)=ketλku^k(0)uku(t) = \sum_k e^{-t\lambda_k} \, \hat u_k(0) \, u_k

Each graph-frequency component decays at a rate set by its own eigenvalue, exactly mirroring the continuous case term for term. Letting this run for a short time tt is a low-pass filter, a soft, continuously tunable version of the hard cutoff used in the worked example above: instead of zeroing high-frequency coefficients outright, they’re scaled down by etλke^{-t\lambda_k}, with larger tt suppressing more of the spectrum. Graph filtering and graph diffusion aren’t two separate applications sitting next to each other, they’re the same computation, viewed either as a signal-processing operation or as a physical process running on the graph.


Where the analogy breaks

The comparison holds up remarkably well, but it isn’t perfect. The circle has translation symmetry: shifting a function and then Fourier transforming gives the same result as transforming and then shifting, and this is exactly why the same eikxe^{ikx} basis works everywhere on the circle regardless of where you start counting. Most graphs have no such symmetry (the diamond graph example only had it because of its particular automorphisms), so the graph Fourier basis is tied to the specific graph you built it from. There’s no universal graph-frequency basis the way there’s a universal continuous one, every graph gets its own, computed from its own Laplacian. The idea generalises cleanly; the specific basis functions do not.