Skip to content
ELECTRONICS ENGINEERINGelectronics-engineering.com
Author's pick Numerical Calculus Digital Signal Processing Signal Theory

The discrete Fourier transform (DFT): from the DTFT, inverse, properties and circular convolution proved

The DFT as sampling of the DTFT and time aliasing, inverse via orthogonality, Parseval, circular shift, Hermitian symmetry, circular versus linear convolution, Dirichlet kernel, zero padding, checked in Python.

https://www.electronics-engineering.com/en/dft-discrete-fourier-transform-proofs-properties-circular-convolution/

Was this page useful? Rate it:
average 4.0 from 1 rating

The discrete Fourier transform (DFT) is the transform a computer can actually compute: it takes N numbers and returns N numbers. Every digital spectrum analyser, every equaliser, every OFDM modem (Wi-Fi, 4G, 5G) and every fast filter uses it, almost always through the FFT algorithm. This in-depth study derives the DFT from the discrete-time Fourier transform (DTFT) and proves its formulas and properties: inverse transform, Parseval, circular shift, Hermitian symmetry, circular convolution and how to obtain linear convolution from it. The linked lessons explain the FFT algorithm and practical use in spectral analysis (leakage, windows, Welch’s method). The path follows the topics of Sandro Petrizzelli’s notes from which this page originated.

From the DTFT to the DFT

A sequence x[n] has DTFT

    \[ X(e^{j\omega}) = \sum_{n=-\infty}^{\infty} x[n]\,e^{-j\omega n} \]

a continuous function, periodic with period 2\pi in the normalised angular frequency \omega. A computer cannot store a continuous function: it takes N equally spaced samples of it, \omega_k = \frac{2\pi k}{N}, k = 0, \dots, N - 1. If x[n] is nonzero only for 0 \le n \le N - 1, these samples are

    \[ X[k] = X(e^{j2\pi k/N}) = \sum_{n=0}^{N-1} x[n]\,W_N^{kn},\qquad W_N = e^{-j2\pi/N} \]

This is the N-point DFT. The number W_N is an N-th root of unity: W_N^N = 1, and its powers are N equally spaced points on the unit circle.

The DFT samples the DTFT
The dashed grey curve is the magnitude of the DTFT of a 4-sample rectangular pulse; the red dots are the 8-point DFT, the blue ones the 16-point DFT of the same pulse padded with zeros: they sample the same curve more densely.

Theorem (sampling in frequency is repeating in time). If x[n] is longer than N, the samples X(e^{j2\pi k/N}) of its DTFT coincide with the DFT of the sequence \tilde x[n] = \sum_{r} x[n - rN], 0 \le n \le N - 1: the parts of x beyond N overlap (time aliasing).

Proof. Split the DTFT sum into blocks of N samples, n = m + rN with 0 \le m \le N - 1: X(e^{j2\pi k/N}) = \sum_r\sum_{m=0}^{N-1} x[m + rN]\,W_N^{k(m + rN)}. Since W_N^{krN} = 1, what remains is \sum_{m=0}^{N-1}\big(\sum_r x[m + rN]\big)W_N^{km}, the DFT of \tilde x. ∎

It is the dual of the sampling theorem: sampling in time makes the spectrum periodic, sampling the spectrum makes the signal periodic. This is why the DFT always treats the block of N samples as if it were one period of a periodic signal: all the properties that follow are “circular”.

The inverse transform

Theorem. x[n] = \dfrac{1}{N}\displaystyle\sum_{k=0}^{N-1} X[k]\,W_N^{-kn}.

Proof. A lemma is needed, the orthogonality of discrete exponentials: \sum_{k=0}^{N-1} W_N^{k\ell} = N if \ell is a multiple of N, otherwise 0. Indeed in the first case every term equals 1; in the second W_N^\ell \ne 1 and the geometric sum is \frac{1 - W_N^{N\ell}}{1 - W_N^\ell} = \frac{1 - 1}{1 - W_N^\ell} = 0. Now substitute the definition:

    \[ \frac{1}{N}\sum_{k=0}^{N-1}\Big(\sum_{m=0}^{N-1} x[m]W_N^{km}\Big)W_N^{-kn} = \frac{1}{N}\sum_{m=0}^{N-1} x[m]\sum_{k=0}^{N-1} W_N^{k(m - n)} \]

The inner sum equals N only for m = n (with m, n between 0 and N - 1, m - n is a multiple of N only if it is zero): x[n] remains. ∎

In matrix form X = F_N x with (F_N)_{kn} = W_N^{kn}, and the theorem says F_N^{-1} = \frac{1}{N}F_N^*: the matrix \frac{1}{\sqrt N}F_N is unitary. Parseval’s theorem follows immediately:

    \[ \sum_{n=0}^{N-1}|x[n]|^2 = \frac{1}{N}\sum_{k=0}^{N-1}|X[k]|^2 \]

because a unitary matrix preserves the norm: \|x\|^2 = \|\tfrac{1}{\sqrt N}X\|^2. Energy can be measured equally in time or in frequency.

The properties, proved

In all that follows indices are taken modulo N: (n)_N is the remainder of n divided by N.

Linearity. a\,x[n] + b\,y[n] \leftrightarrow a\,X[k] + b\,Y[k]: the definition is a sum.

Circular time shift. x[(n - m)_N] \leftrightarrow W_N^{km}X[k].

Proof. \sum_n x[(n - m)_N]W_N^{kn}; with p = (n - m)_N, as n runs over 0, \dots, N - 1 so does p (in another order), and W_N^{kn} = W_N^{k(p + m)} because W_N^{kN} = 1. The sum becomes W_N^{km}\sum_p x[p]W_N^{kp} = W_N^{km}X[k]. ∎

The delay only changes the phase of the coefficients, not the magnitude. But it is a circular delay: samples leaving on the right re-enter on the left.

Circular shift of 3 samples out of 8
The last three samples of the blue sequence, in orange, leave on the right and re-enter at the start: it is the delay corresponding to multiplying the DFT by W to the power 3k.

Frequency shift (modulation). W_N^{-k_0n}x[n] \leftrightarrow X[(k - k_0)_N]: same proof with the roles swapped. Multiplying by a complex exponential shifts the spectrum: it is the principle of frequency conversion in digital receivers.

Hermitian symmetry. If x[n] is real, X[N - k] = X^*[k].

Proof. X[N - k] = \sum_n x[n]W_N^{(N - k)n} = \sum_n x[n]W_N^{-kn}, because W_N^{Nn} = 1. For real x, conjugation only changes the sign of the exponent: X^*[k] = \sum_n x[n]W_N^{-kn}. ∎

So real part and magnitude are symmetric about k = N/2, imaginary part and phase antisymmetric: for a real signal the coefficients from 0 to N/2 are enough, and the “real” FFT does half the computation. The coefficient X[N/2] (with even N) is the Nyquist frequency and is real.

Symmetry of the DFT of a real signal
The 8-point DFT of the real sequence 3, 1, −1, 2, 0, 1, 0, −2: the real part, blue, is symmetric about N/2; the imaginary part, red, is antisymmetric.

Circular symmetry. If moreover x[(-n)_N] = x[n] (even in the circular sense, i.e. x[N - n] = x[n]), the DFT is real; if it is odd, purely imaginary. It follows from the previous property: for even x, X^*[k] = X[N - k] = X[k].

Circular convolution

Theorem. The product of DFTs corresponds to circular convolution:

    \[ Y[k] = X[k]H[k] \;\leftrightarrow\; y[n] = \sum_{m=0}^{N-1} x[m]\,h[(n - m)_N] = (x \circledast h)[n] \]

Proof. Compute the DFT of y and use the circular shift: \sum_n\sum_m x[m]h[(n - m)_N]W_N^{kn} = \sum_m x[m]\Big(\sum_n h[(n - m)_N]W_N^{kn}\Big) = \sum_m x[m]W_N^{km}H[k] = X[k]H[k]. ∎

Filtering a signal is instead a linear convolution, y[n] = \sum_m x[m]h[n - m], with length L + M - 1 if x and h have lengths L and M. Circular convolution on N points is the linear one “wrapped around”: samples beyond N - 1 are added at the start (the frequency-sampling theorem applied to y).

Example. x = (1, 2, 3), h = (1, 1). The linear convolution is (1, 3, 5, 3). With an N = 3 point DFT the last 3 wraps onto n = 0: (1 + 3, 3, 5) = (4, 3, 5), a wrong result for a filter. With N = 4 \ge L + M - 1 there is no overlap and (1, 3, 5, 3) is obtained again.

Linear and circular convolution
On the left the linear convolution of (1, 2, 3) with (1, 1), 4 samples long; with N = 3 the last sample, orange, wraps onto the first and the circular convolution, red, is 4, 3, 5.

Practical rule: to filter with the FFT, pad x and h with zeros up to N \ge L + M - 1. For long signals the signal is split into blocks and the overlap-add and overlap-save methods are used, which reassemble the blocks without errors; with large N the cost, O(N\log N) instead of O(LM), is much lower than direct convolution.

Two DFTs to know by heart

Rectangular pulse of L samples on N points: with the geometric sum

    \[ X[k] = \sum_{n=0}^{L-1} W_N^{kn} = \frac{1 - W_N^{kL}}{1 - W_N^k} = e^{-j\pi k(L - 1)/N}\,\frac{\sin(\pi kL/N)}{\sin(\pi k/N)} \]

(factoring e^{-j\pi kL/N} in the numerator and e^{-j\pi k/N} in the denominator). The magnitude is the Dirichlet kernel, the discrete version of the sinc: for L = 4, N = 8 it is 4, 2.613, 0, 1.082, 0, 1.082, 0, 2.613. It is also the response of the rectangular window, the origin of spectral leakage.

Cosine on a bin. x[n] = \cos\frac{2\pi k_0n}{N} = \frac{1}{2}\big(W_N^{-k_0n} + W_N^{k_0n}\big): by orthogonality the DFT equals \frac{N}{2} at k = k_0 and at k = N - k_0, zero elsewhere. If the frequency does not fall exactly on a bin the DFT has values at all k: this is spectral leakage, covered in the spectral analysis lesson.

Zero padding

Padding a block of L samples with zeros up to N \gt  L does not add information: by the first theorem, the N-point DFT samples the same DTFT more densely (figure at the top, 8 and 16 points). It helps to read peak positions better and to reach a power of 2 for the FFT, but the ability to separate two close frequencies depends only on the duration L of the observed signal: about \Delta\omega \approx 2\pi/L.

Checking in Python

import numpy as np

def dft(x):
    """DFT from the definition: X[k] = sum x[n] e^{-j 2 pi k n / N}."""
    N = len(x)
    n = np.arange(N)
    W = np.exp(-2j * np.pi * np.outer(n, n) / N)     # Fourier matrix
    return W @ x

def idft(X):
    N = len(X)
    n = np.arange(N)
    return np.exp(2j * np.pi * np.outer(n, n) / N) @ X / N

rng = np.random.default_rng(1)
x = rng.standard_normal(8)
X = dft(x)
print("equal to np.fft.fft:", np.allclose(X, np.fft.fft(x)))
print("exact inverse:", np.allclose(idft(X), x))
print("Parseval:", np.isclose(np.sum(x**2), np.sum(abs(X)**2) / 8))
print("Hermitian symmetry X[N-k] = X*[k]:", np.allclose(X[1:][::-1], np.conj(X[1:])))
m = 3
print("circular shift:", np.allclose(dft(np.roll(x, m)), np.exp(-2j * np.pi * np.arange(8) * m / 8) * X))

# circular versus linear convolution
a, h = np.array([1.0, 2, 3]), np.array([1.0, 1])
lin = np.convolve(a, h)
circ3 = np.real(idft(dft(a) * dft(np.r_[h, 0])))
circ4 = np.real(idft(dft(np.r_[a, 0]) * dft(np.r_[h, 0, 0])))
print("linear:", lin, " circular N=3:", np.round(circ3, 6), " circular N=4:", np.round(circ4, 6))

# DFT of a rectangular pulse of L = 4 samples on N = 8 points: Dirichlet kernel
L, N = 4, 8
r = np.r_[np.ones(L), np.zeros(N - L)]
k = np.arange(1, N)
dirichlet = np.exp(-1j * np.pi * k * (L - 1) / N) * np.sin(np.pi * k * L / N) / np.sin(np.pi * k / N)
print("rectangle, Dirichlet formula:", np.allclose(dft(r)[1:], dirichlet), " |X| =", np.round(abs(dft(r)), 3))

# cosine falling exactly on bin 2
c = np.cos(2 * np.pi * 2 * np.arange(N) / N)
print("cosine on bin 2:", np.round(abs(dft(c)), 6))

All checks print True; the 3-point circular convolution gives (4, 3, 5) and the 4-point one (1, 3, 5, 3), equal to the linear one; the magnitude of the rectangle and the cosine on bin 2 (value 4 at k = 2 and k = 6) match the formulas. The DFT from the definition costs N^2 multiplications: for N = 8 it does not matter, for N = 10^6 it does, and this is the reason for the FFT algorithm, explained in the linked lesson.

Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
1
0
Would love your thoughts, please comment.x
()
x