Skip to content

The DFT as a matrix

Write the DFT as one matrix times one column, see why its rows cancel, and see why a circular convolution becomes a bin-by-bin product.

Before this13.3 · 13.4 · 6 more
Chapter 13 · Lesson 5 of 6

First, the picture

Here the eight probes of The DFT (13.2) sit in a grid, one per row, beside the column x=1,2,3,4,3,2,1,0x=1,2,3,4,3,2,1,0. Make a guess before you play it: what does row 0, whose arrows never turn, do to the column?

The DFT as one matrix

F has entry W₈^{kn} = e^{−j2πkn/8} in row k, column n, drawn as a small arrow. x = 1, 2, 3, 4, 3, 2, 1, 0.

Row k of the grid is 13.2's probe k: arrows that turn k/8 of a turn per column. Row 0 never turns; row 4 flips every column.

row k
none yet
X[k]
none yet
0.00 / 14.00 s
Describe this picture

Three panels for N=8N=8 and x=1,2,3,4,3,2,1,0x=1,2,3,4,3,2,1,0. The first is the grid F\mathbf{F}, an 8×88\times8 array of unit arrows with rows k=0k=0 to 7 and columns n=0n=0 to 7; the arrow in row kk, column nn is W8kn=e−j2πkn/8W_8^{kn}=e^{-j2\pi kn/8} and points at angle −2πkn/8-2\pi kn/8. Arrows are drawn rather than colours, so an angle reads by its shape. The second panel is the column x\mathbf{x} as eight numbers, and the third is the column X\mathbf{X}, empty at first. The readouts are the row kk and the bin X[k]X[k]. The clip plays once and holds on its last frame.

It opens with both readouts at “none yet”: row kk is 13.2’s probe kk, arrows that turn k/8k/8 of a turn per column, so row 0 never turns and row 4 flips every column. Then a rectangular outline picks out row 0 and its result entry: 1+2+3+4+3+2+1+0=16=X[0]1+2+3+4+3+2+1+0=16=X[0]. Row 1 gives 13.2’s chain for bin 1, X[1]=−4.83−4.83jX[1]=-4.83-4.83j; row 2 gives X[2]=0X[2]=0; row 3 gives X[3]=0.83−0.83jX[3]=0.83-0.83j. Rows 4 to 7 then fill their results together, with the caption blank. The last frame reads “Eight rows, eight bins: X = Fx, one matrix times one column”, with the readouts “all 8” and “see the column”.

After the clip ends, a slider named “Row k” picks a row: tap it, or use the arrow keys. Rows 4 to 7 read in the same form, for example “Row 5 times x: X[5] = 0.83 + 0.83j.”

The DFT as one matrix

The DFT (13.2) gave you NN bins, and each bin was a probe: eight arrows that turn a fixed amount per sample, multiplied into the signal and added up. That is NN sums of NN products. In Discrete convolution (5.2) you met a grid of numbers multiplied into a column, and this is the same shape of calculation. This page writes the DFT that way, and then asks what the grid is good for.

Stack the samples x[0],…,x[N−1]x[0],\dots,x[N-1] into one column, x\mathbf{x}. Stack the bins into another, X\mathbf{X}. Then

X=Fx,\mathbf{X}=\mathbf{F}\mathbf{x},

where F\mathbf{F} is the DFT matrix, an N×NN\times N grid whose entry in row kk and column nn is

Fkn=WNkn=e−j2πkn/N.F_{kn}=W_N^{kn}=e^{-j2\pi kn/N}.

Here WN=e−j2π/NW_N=e^{-j2\pi/N}, the arrow from 13.2 that turns 1/N1/N of a turn clockwise. Row kk of the grid is probe kk. A row times a column means: multiply entry by entry, then add. This is the dot product, and it is exactly the sum that defined X[k]X[k].

In the picture at the top, row 0 is all ones, so its dot product is the plain sum of the samples, 16. Row 1 times x\mathbf{x} is the chain of arrows you drew in 13.2, now as one row of the grid, and it gives X[1]=−4.83−4.83jX[1]=-4.83-4.83j. After the clip ends, tap a row, or use the arrow keys, to read its bin.

Notice the two extremes. Row 0 never turns, so it adds the samples as they are. Row 4 turns half a turn per column, so its arrows alternate +1,−1,+1,…+1,-1,+1,\dots and every other column is flipped. Every other row is somewhere between.

A small case by hand

Take N=4N=4. Then W4=e−jπ/2=−jW_4=e^{-j\pi/2}=-j, and the four rows of F\mathbf{F} are

(1, 1, 1, 1),(1, −j, −1, j),(1, −1, 1, −1),(1, j, −1, −j).\begin{aligned} &(1,\ 1,\ 1,\ 1),\\ &(1,\ -j,\ -1,\ j),\\ &(1,\ -1,\ 1,\ -1),\\ &(1,\ j,\ -1,\ -j). \end{aligned}

For x=(1,2,3,4)\mathbf{x}=(1,2,3,4), the dot product of row 1 with x\mathbf{x} is 1−2j−3+4j=−2+2j1-2j-3+4j=-2+2j. Doing the other rows the same way gives

X=(10, −2+2j, −2, −2−2j),\mathbf{X}=(10,\ -2+2j,\ -2,\ -2-2j),

which is what np.fft.fft returns for the same input.

Rows that cancel

If F\mathbf{F} is a grid, can I undo it? To find out, I need to know what happens when I multiply two of its rows against each other. First, three words.

The conjugate transpose of F\mathbf{F}, written FH\mathbf{F}^{\mathsf H}, swaps rows and columns and conjugates every entry. Because F\mathbf{F} is symmetric, Fkn=FnkF_{kn}=F_{nk}, this only conjugates: (FH)kn=e+j2πkn/N(\mathbf{F}^{\mathsf H})_{kn}=e^{+j2\pi kn/N}. Now take row pp and row qq. Multiply row pp by the conjugate of row qq, entry by entry, and add. Two rows are orthogonal when this sum is 0. The identity matrix I\mathbf{I} has 1 on its diagonal and 0 elsewhere, so Ix=x\mathbf{I}\mathbf{x}=\mathbf{x}.

Before you play the clip, make a guess. Row 1 turns 1/81/8 of a turn per column. Row 2 turns twice as fast. When I multiply row 1 by the conjugate of row 2, how fast do the products turn? Then watch the chain of products: it closes for every row but one.

Rows that cancel

Multiply row 1 by the conjugate of row q, entry by entry, and add: a chain of eight arrows.

Row 1 against row 0: each product turns 45° further than the last, and the eight close an octagon. Sum 0.

row q
0
sum
0.00
0.00 / 13.00 s
Describe this picture

One plane with real and imaginary axes, and no control. Row 1 is multiplied by the conjugate of row qq, entry by entry, and the eight products are unit arrows laid nose to tail; a filled square at the tip marks their sum. A key names the arrows “products” and the square “sum”. The readouts are the row qq and the sum.

At q=0q=0 each product turns 45° further than the last, and the eight close an octagon: sum 0. At q=1q=1, row 1 against itself, every product is 1, the arrows line up, and the sum is 8=N8=N. At q=2q=2 the products turn the other way and close again: sum 0. Rows 3 to 7 pass in turn, and each chain closes with sum 0. The last frame reads “Different rows cancel, and a row against itself gives N: Fᴴ F = N I. So the inverse is Fᴴ/N, and F/√N keeps every vector’s length”, with the readouts “0 to 7” and “8 only for q = 1”.

A chain that closes adds to 0, which is the fact from The DTFT (12.2) and from Complex numbers for signals (3.3): NN equal steps round a circle add to 0. Row 1 against itself is the exception. Each product is e−j2πn/8 e+j2πn/8=1e^{-j2\pi n/8}\,e^{+j2\pi n/8}=1, so the chain is a straight line of length 8. Only q=1q=1 gives a straight chain.

What the cancelling gives

Every row against every row is one entry of the product FHF\mathbf{F}^{\mathsf H}\mathbf{F} (the rows of FH\mathbf{F}^{\mathsf H} are the conjugated columns, and these match the conjugated rows because F\mathbf{F} is symmetric). The clip showed that those entries are NN on the diagonal and 0 off it:

FHF=N I.\mathbf{F}^{\mathsf H}\mathbf{F}=N\,\mathbf{I}.

Divide by NN and you have the inverse, F−1=1NFH\mathbf{F}^{-1}=\tfrac1N\mathbf{F}^{\mathsf H}, so

x=1NFHX.\mathbf{x}=\tfrac1N\mathbf{F}^{\mathsf H}\mathbf{X}.

This is the inverse DFT of 13.2, with e+j2πkn/Ne^{+j2\pi kn/N} and the 1/N1/N in front. In the N=4N=4 case, FHF\mathbf{F}^{\mathsf H}\mathbf{F} comes out as 4I4\mathbf{I}, and 14FH(10, −2+2j, −2, −2−2j)\tfrac14\mathbf{F}^{\mathsf H}(10,\,-2+2j,\,-2,\,-2-2j) gives back (1,2,3,4)(1,2,3,4).

There is a way to keep every length. A matrix is unitary when its conjugate transpose is its inverse. The matrix F\mathbf{F} is not, because FHF=NI\mathbf{F}^{\mathsf H}\mathbf{F}=N\mathbf{I} and not I\mathbf{I}. But 1NF\tfrac1{\sqrt N}\mathbf{F} is, because the two factors of 1/N1/\sqrt N multiply to the missing 1/N1/N. On this site the unitary DFT always shows its scale, and its output is never called X[k]X[k], because X[k]X[k] is the DFT with no scale.

Length squared is energy, from How big is a signal (1.3). The unitary DFT keeps it:

∥1NFx∥2=∥x∥2.\left\lVert\tfrac1{\sqrt N}\mathbf{F}\mathbf{x}\right\rVert^2=\lVert\mathbf{x}\rVert^2.

That is Parseval’s relation from 13.2, ∑n∣x[n]∣2=1N∑k∣X[k]∣2\sum_n\lvert x[n]\rvert^2=\tfrac1N\sum_k\lvert X[k]\rvert^2, in matrix form. Check it for x=(1,2,3,4)\mathbf{x}=(1,2,3,4): the energy is 1+4+9+16=301+4+9+16=30, and the squared sizes of X\mathbf{X} are 100100, 88, 44 and 88, which sum to 120=4×30120=4\times30. Divide by N=4N=4 and you are back at 30.

Arrows in, the same arrows out

Now the second use of the grid. In Circular vs linear convolution (13.4) you saw that a circular convolution can be written as a matrix. This is the circulant matrix C\mathbf{C} of hh: each row is the row above it, rotated right by one place, and

Cx=h⊛Nx.\mathbf{C}\mathbf{x}=h\circledast_N x.

For the two-point average h=0.5, 0.5h=0.5,\,0.5 on a ring of N=8N=8 samples, the first row of C\mathbf{C} has 0.5 in column 0 and in column 7, and the second row has 0.5 in columns 0 and 1. Each output is (Cx)[n]=0.5 x[n]+0.5 x[n−1](\mathbf{C}\mathbf{x})[n]=0.5\,x[n]+0.5\,x[n-1], the average of a sample and its neighbour round the ring.

One more word. An eigenvector of a matrix is a column that comes out of it only scaled, and the scale is its eigenvalue. Where have you met this? In Properties of LTI systems (5.4), a complex exponential went through a system and came out as the same exponential times a number. A circulant is the circular version of that statement.

Before you play the clip, make a guess. Feed C\mathbf{C} the arrow ej2πkn/8e^{j2\pi kn/8} for n=0,…,7n=0,\dots,7, which is column kk of FH\mathbf{F}^{\mathsf H}. What do you expect to come out?

Arrows in, the same arrows out

C is the 8×8 circulant of h = 0.5, 0.5: a 2-point average on the ring. In: the arrow e^{j2πkn/8}, n = 0 to 7.

Arrow k = 0 is all ones. Averaging neighbours leaves it alone: out = 1 × in.

arrow k
0
H[k]
1.00∠0.0°
0.00 / 14.00 s
Describe this picture

Three panels for the 8×88\times8 circulant C\mathbf{C} of h=0.5, 0.5h=0.5,\,0.5, a 2-point average on the ring, fed the arrow ej2πkn/8e^{j2\pi kn/8} for n=0n=0 to 7. The first draws C\mathbf{C} as a grid of cells, with 0.5 as a filled square and 0 as an empty one. The second is the row marked “in”: eight dials, each a unit circle with a triangle-headed arrow. The third is the row marked “out”: eight dials showing (Cv)[n](\mathbf{C}\mathbf{v})[n] on the same scale, with square-headed arrows. Each time a new arrow comes in, the output dials first copy it and then turn to their scaled place, with the caption blank until they settle. The readouts are the arrow kk and H[k]H[k], as a size and an angle, and one large dial repeats H[k]H[k].

At k=0k=0 the arrow is all ones, and averaging neighbours leaves it alone: H[0]H[0] reads 1.00∠0.0°. At k=1k=1 every output dial is its input dial times the same number, 0.92∠−22.5°: the same arrow, shorter and turned. At k=2k=2 all eight dials are scaled by 0.71∠−45.0°. The last frame, k=4k=4, alternates, and averaging neighbours cancels it: H[4]=0H[4]=0. Its caption ends “Every arrow is an eigenvector of C, and its eigenvalue H[k] is the DFT of h.”

After the clip ends, a slider named “Arrow k” chooses any arrow from 0 to 7: drag across the input dials, or use the arrow keys. At k=3k=3, for example, the caption reads “k = 3: every dial scaled by H[3] = 0.38∠−67.5°.”

Notice that all eight output dials shrink and turn by the same amount. After the clip ends, drag across the input dials to try any arrow kk from 0 to 7.

Why every sample is scaled by the same number

Put the arrow vk[n]=ej2πkn/Nv_k[n]=e^{j2\pi kn/N} through C\mathbf{C}. For the two-point average,

(Cvk)[n]=0.5 ej2πkn/N+0.5 ej2πk(n−1)/N=(0.5+0.5 e−j2πk/N) ej2πkn/N.(\mathbf{C}\mathbf{v}_k)[n]=0.5\,e^{j2\pi kn/N}+0.5\,e^{j2\pi k(n-1)/N} =\Bigl(0.5+0.5\,e^{-j2\pi k/N}\Bigr)\,e^{j2\pi kn/N}.

The bracket does not contain nn. It is the same number for every sample, and it is the DFT of h=0.5, 0.5h=0.5,\,0.5 at bin kk:

H[k]=0.5+0.5 WNk=cos⁡ ⁣(πkN) e−jπk/N.H[k]=0.5+0.5\,W_N^{k}=\cos\!\Bigl(\frac{\pi k}{N}\Bigr)\,e^{-j\pi k/N}.

For N=8N=8 and k=1k=1 this has size cos⁡(π/8)=0.92\cos(\pi/8)=0.92 and angle −π/8=−22.5°-\pi/8=-22.5°, which matches the clip at k=1k=1. For k=4k=4 it is cos⁡(π/2)=0\cos(\pi/2)=0: the arrow alternates +1,−1+1,-1, and the average of a sample and its neighbour is 0. The wrap-around matters here. Because the ring closes, the identity holds at every nn including n=0n=0, where the neighbour is x[7]x[7].

Convolution becomes multiplication

Stack the eight eigenvectors as the columns of FH\mathbf{F}^{\mathsf H}. Feeding all of them in at once gives

CFH=FH diag(H[0],…,H[N−1]),\mathbf{C}\mathbf{F}^{\mathsf H}=\mathbf{F}^{\mathsf H}\,\mathrm{diag}(H[0],\dots,H[N-1]),

where diag(⋅)\mathrm{diag}(\cdot) is the matrix with those numbers on its diagonal and 0 elsewhere. Multiply by F\mathbf{F} on the right, and use FHF=NI\mathbf{F}^{\mathsf H}\mathbf{F}=N\mathbf{I}:

C=1N FH diag(H[0],…,H[N−1]) F.\mathbf{C}=\tfrac1N\,\mathbf{F}^{\mathsf H}\,\mathrm{diag}(H[0],\dots,H[N-1])\,\mathbf{F}.

Read it from right to left. First F\mathbf{F} takes the DFT. Then the diagonal matrix multiplies each bin by its own H[k]H[k], with no bin touching another. Then 1NFH\tfrac1N\mathbf{F}^{\mathsf H} inverts. This is the rule of Properties of the DFT (13.3), h⊛Nx↔H[k]X[k]h\circledast_N x\leftrightarrow H[k]X[k], proved a second time with matrices.

Check it with N=4N=4 and h=0.5, 0.5, 0, 0h=0.5,\,0.5,\,0,\,0. Then H=(1, 0.5−0.5j, 0, 0.5+0.5j)H=(1,\ 0.5-0.5j,\ 0,\ 0.5+0.5j). For x=(1,2,3,4)\mathbf{x}=(1,2,3,4), the matrix product Cx\mathbf{C}\mathbf{x} gives (2.5, 1.5, 2.5, 3.5)(2.5,\ 1.5,\ 2.5,\ 3.5), and taking the inverse DFT of H[k]X[k]H[k]X[k] gives the same four numbers. The first output is the average of x[0]=1x[0]=1 and its neighbour x[3]=4x[3]=4.

The maths behind it · unitary matrices

The matrix 1NF\tfrac1{\sqrt N}\mathbf{F} is a unitary matrix, the complex version of a rotation: it changes the basis to the NN arrows without changing any length. Every circulant matrix shares this one set of eigenvectors, so any two circulants of the same size commute: filtering by h1h_1 and then by h2h_2 gives the same answer as the other order.

The maths behind it · principal components

The covariance matrix of a stationary signal that wraps round is circulant, so its principal components are the DFT’s arrows and the variances along them are its power spectrum. PCA of such data is a DFT. Power spectral density (24.4) follows this up.

Worked example

Here is one by hand, to check that the pieces fit. Take N=4N=4, x=(1,2,3,4)\mathbf{x}=(1,2,3,4) and h=0.5, 0.5, 0, 0h=0.5,\,0.5,\,0,\,0.

  1. The DFT matrix gives X=Fx=(10, −2+2j, −2, −2−2j)\mathbf{X}=\mathbf{F}\mathbf{x}=(10,\ -2+2j,\ -2,\ -2-2j).
  2. The eigenvalues are the DFT of hh: H=(1, 0.5−0.5j, 0, 0.5+0.5j)H=(1,\ 0.5-0.5j,\ 0,\ 0.5+0.5j).
  3. Multiply bin by bin. Bin 1 gives (0.5−0.5j)(−2+2j)=2j(0.5-0.5j)(-2+2j)=2j and bin 3 gives (0.5+0.5j)(−2−2j)=−2j(0.5+0.5j)(-2-2j)=-2j, so H[k]X[k]=(10, 2j, 0, −2j)H[k]X[k]=(10,\ 2j,\ 0,\ -2j).
  4. Invert with 14FH\tfrac14\mathbf{F}^{\mathsf H}. The first output is 14(10+2j+0−2j)=2.5\tfrac14(10+2j+0-2j)=2.5. The full result is (2.5, 1.5, 2.5, 3.5)(2.5,\ 1.5,\ 2.5,\ 3.5), which is the circular convolution computed directly.

Each product in step 3 uses (0.5−0.5j)(−2+2j)=−1+j+j−j2=−1+2j+1=2j(0.5-0.5j)(-2+2j)=-1+j+j-j^2=-1+2j+1=2j and its conjugate partner −2j-2j.

Where you’ll meet this

The matrix F\mathbf{F} has a lot of structure, and the next page, The FFT (14.1), uses it: F\mathbf{F} can be factored into a few sparse matrices, so the N2N^2 products of this page shrink to about Nlog⁡2NN\log_2N. The two-dimensional version, a DFT along rows and then along columns, is The 2-D DFT (28.3).

Reference card

QuantityFormulaNotes
DFT matrixX=Fx\mathbf{X}=\mathbf{F}\mathbf{x}, Fkn=WNkn=e−j2πkn/NF_{kn}=W_N^{kn}=e^{-j2\pi kn/N}row kk is probe kk
Orthogonal rowsFHF=NI\mathbf{F}^{\mathsf H}\mathbf{F}=N\mathbf{I}rows cancel unless equal
Inversex=1NFHX\mathbf{x}=\tfrac1N\mathbf{F}^{\mathsf H}\mathbf{X}the inverse DFT
Unitary DFT1NF\tfrac1{\sqrt N}\mathbf{F}, keeps ∥x∥\lVert\mathbf{x}\rVertParseval; never called X[k]X[k]
CirculantCx=h⊛Nx\mathbf{C}\mathbf{x}=h\circledast_Nx; each row the one above, rotated13.4
EigenvectorsC ej2πkn/N=H[k] ej2πkn/N\mathbf{C}\,e^{j2\pi kn/N}=H[k]\,e^{j2\pi kn/N}eigenvalue H[k]H[k], the DFT of hh
DiagonalisationC=1NFHdiag(H[k])F\mathbf{C}=\tfrac1N\mathbf{F}^{\mathsf H}\mathrm{diag}(H[k])\mathbf{F}convolution becomes multiplication

End of lesson 13.5

Where to go next.

Phasorium
LibraryEvery lesson, in order

Parts

About Phasorium
Look