| jupytext |
|
||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| kernelspec |
|
:tags: [hide-input]
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from tqdm import tqdm
mpl.rcParams['axes.spines.top'] = 0
mpl.rcParams['axes.spines.right'] = 0
mpl.rcParams['axes.spines.left'] = 1
mpl.rcParams['axes.spines.bottom'] = 1
mpl.rcParams.update({'font.size': 12})
We have seen that the discrete-time Fourier transform (or discrete-space Fourier transform) is a great tool to understand linear shift-invariant filtering of discrete signal and imaging. On the other hand, it is clear that in a computer we will only ever deal with finite-length signals, and in the case of images, often standardized dimensions. It is natural to ask whether there exists a tool similar to DTFT that is tailor-made for finite-length (finite-support) signals. This is also related to the fact that the frequency
We'd like to have a Fourier transform for finite-length signals (say of length
$$
\omega_k = \frac{2\pi}{N}k, \ \text{for} \ k \in { 0, 1, \ldots, N - 1 }.
$$
The corresponding base complex exponentials are the roots of unity. That is,
equally spaced on the unit circle. Here is an illustration for
+++
N = 8
angles = np.linspace(0, 2*np.pi, 128, endpoint=True)
root_angles = 2 * np.pi / N * np.arange(N)
fig, ax = plt.subplots(1, 1, figsize=(8, 8))
ax.spines[['left', 'bottom']].set_position('center')
ax.spines[['right', 'top']].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
ax.plot(np.cos(angles), np.sin(angles))
ax.plot(np.cos(root_angles), np.sin(root_angles), 'o', markersize=20)
ax.set_aspect(1)
+++
It turns out that such sinusoids are orthogonal. Indeed, denoting
$$
\begin{aligned}
\langle \nu_k, \nu_\ell \rangle
&= \sum_{n = 0}^{N - 1} \nu_k[n] \nu_\ell[n] \
&= \sum_{n = 0}^{N - 1} e^{i \omega_k n} e^{-i \omega_\ell n} \
&= \sum_{n = 0}^{N - 1} e^{i \frac{2\pi n}{N} (k - \ell) } \
&= (\ast)
\end{aligned}
$$
If
Applying the formula with
Now since
\begin{cases} N & k = \ell \ 0 & k \neq \ell. \end{cases} $$
Write a code snippet to test this orthogonality numerically.
This finally allows us to define the forward and the inverse discrete Fourier transform (DFT) as
Is there an alternative intuitive derivation of the DFT? Sure there is! We can obtain it as a limit DTFT for periodized signals. The math gets a bit involved, especially if you want to do it carefully, so we won't go into the details. But we can write some code. We begin with a simple triangular pulse of
L = 31
n_pulse = np.arange(1 + 2*L)
x = (L - np.abs(n_pulse - L)) / L
x -= x.mean()
plt.plot(n_pulse, x, '.');
Assuming that this pulse is extended by zeros to both infinities we can plot its DTFT.
from scipy.signal import freqz
omega, X = freqz(x)
plt.plot(omega, np.abs(X))
plt.xlabel('$\\omega$')
plt.ylabel('$X(\\omega)$');
(We are only showing the spectral magnitude for frequencies
We now construct a periodic extension
R_list = [2, 5, 1000] # number of repetitions
fig, axs = plt.subplots(2, 3, figsize=(12, 6))
for i_R, R in enumerate(R_list):
x_tilde = np.tile(x, R)
omega, X_tilde = freqz(x_tilde)
axs[0, i_R].plot(np.arange(len(x_tilde)), x_tilde)
axs[1, i_R].plot(omega, np.abs(X_tilde))
axs[1, i_R].set_ylim(0, 50)
We see that the more periodic repetitions we make, the more discrete the spectrum becomes! With a bit more work we could prove that the spacing between the spectral lines is exactly
From the definition of the DFT and the above discussion, we see that the DFT implicitly periodizes the finite-length signals. The expression for the inverse transform,
should a priori only make sense for those
$$
\begin{aligned}
x[n + N]
&= \frac{1}{N} \sum_{k = 0}^{N - 1} X[k] e^{i \frac{2\pi k}{N} (n + N)} \
&= \frac{1}{N} \sum_{k = 0}^{N - 1} X[k] e^{i \frac{2\pi k}{N} n} e^{i \frac{2\pi k}{N} N} \
&= \frac{1}{N} \sum_{k = 0}^{N - 1} X[k] e^{i \frac{2\pi k}{N} n}.
\end{aligned}
$$
Thus with the DFT both the spectrum
(Warning: puritanism) Strictly speaking we should not use $x[n]$ in the above expression since our starting $x[n]$ is only defined for $n \in \{ 0, \ldots, N - 1\}$. The inverse DFT agrees with $x[n]$ on this interval but is also defined everywhere else.
We've seen that the DTFT gives us a nice and useful interpretation of convolution in the frequency domain. Do we get the same with the DFT? Well... almost. Since DFT implicitly treats the signals as periodic we have to replace our old definition of convolution by the so-called circular convolution. This just means that when we run out of indices, we wrap around back to the beginning. We'll use the following convenient modulo notation,
which is just the usual modulo-$N$ division. For example,
This yields the definition
$$
(x \circledast_N h)[n] = \sum_{m = 0}^{N - 1} x[m] h[(n - m)_N].
$$
We will omit the subscript
With this definition it is not hard to show (do it for fun!) that if
Conversely, multiplying DFTs of two sequences corresponds to their circular convolution in time (or space when we work with images). This is very important to remember. Unlike forward and inverse DTFT which can only be approximated in a computer by finely discetizing the frequency
But there is a catch: we almost always want to compute or old linear2 convolution, not circular. Reverberation in a cathedral is not a cricular phenomenon. We need a way to use the described excursion via the FFT to emulate linear convolution.
Luckily, this is not hard. The idea is to pad the signal with zeros so that the modulo formula does not have to "wrap around". To see how, let again
\begin{cases} x[n] & n \in {0, 1, \ldots, N - 1} \ 0 & n \in {N, N + 1, \ldots, 2N - 1}. \end{cases} $$
It then follows that
Zero padding is part of the broader theme of properly handling boundary conditions in convolution.
Footnotes
-
This is even true for infinite-support discrete time/space signals. Since they are indexed by integers $\mathbb{Z}$ or pairs of integers $\mathbb{Z}^2$, they are countable, and thus spanned by bases with much fewer elements than the interval $[-\pi, \pi)$ which has as many elements as the real line. ↩
-
Here, linear is not meant in the sense of a linear system, but in the sense of not being circular. Both "linear" and circular convolution with some filter $h$ and linear operators. ↩