In this article, we will illustrate several basic properties of the Fourier Transform, which are essential for working with the transform from day to day. First, let us define a Python function which approximates the Fourier transform
$$ X(f) = \int_{-\infty}^{\infty}x(t)\exp(-j2\pi ft) dt $$from a sampled version $x(\frac{n}{F_s}-t_0), n=0,\dots,N-1$ of the signal, by using the discrete Fourier transform (refer to Approximation of Fourier Transform with DFT for an explanation):
def ft(samples, Fs, t0):
"""Approximate the Fourier Transform of a time-limited signal
by means of the discrete Fourier Transform.
samples: signal values sampled at the positions t0 + n/Fs
Fs: Sampling frequency of the signal
t0: starting time of the sampling of the signal
"""
f = np.linspace(-Fs/2, Fs/2, len(samples), endpoint=False)
return np.fft.fftshift(np.fft.fft(samples)/Fs * np.exp(-2j*np.pi*f*t0))
Let us start with some basic known correspondences of the Fourier Transform and plot these to ensure the correctnes of our Fourier Transform function.
Fs = 10000 # The sampling frequency we use for the simulation
t0 = 10 # The half time interval we look at
t = np.arange(-t0, t0, 1/Fs) # the time samples
f = np.arange(-Fs/2, Fs/2, Fs/len(t)) # the corresponding frequency samples
g = lambda t: (abs(t) <=0.5).astype(float) # define rect function
plt.subplot(121)
plt.plot(t, g(t))
plt.subplot(122)
plt.plot(f, ft(g(t), Fs, -t0).real)
g = lambda t: np.sin(2*np.pi*2*t)
plt.subplot(121)
plt.plot(t, g(t))
plt.subplot(122)
plt.plot(f, ft(g(t), Fs, -t0).real, label='real')
plt.plot(f, ft(g(t), Fs, -t0).imag, label='imag')
g = lambda t: np.cos(3*np.pi*2*t)
plt.subplot(121)
plt.plot(t, g(t))
plt.subplot(122)
plt.plot(f, ft(g(t), Fs, -t0).real, label='real')
plt.plot(f, ft(g(t), Fs, -t0).imag, label='imag')
g = lambda t: np.exp(-abs(t*t))
plt.subplot(121)
plt.plot(t, g(t))
plt.subplot(122)
plt.plot(f, ft(g(t), Fs, -t0).real, label='real')
plt.plot(f, ft(g(t), Fs, -t0).imag, label='imag')
g = lambda t: np.sinc(t)**2
plt.subplot(121)
plt.plot(t, g(t))
plt.subplot(122)
plt.plot(f, ft(g(t), Fs, -t0).real, label='real')
plt.plot(f, ft(g(t), Fs, -t0).imag, label='imag')
plt.tight_layout()
The Fourier Transform is a linear operation, i.e. it does not matter if you perform scaling and summation of two functions before or after Fourier Transform. Let $x(t)$ and $y(t)$ be two signals. Then the following holds:
\begin{align} \mathcal{F}\{x(t)\} &= X(f) \\ \mathcal{F}\{y(t)\} &= Y(f) \\ \mathcal{F}\{ax(t)+by(t)\} &= aX(f)+bY(f) \\ \end{align}Let us verify this operation numerically by calculating the Fourier transform of a the sum of a rect plus a Gaussian:
def rect(t):
return (abs(t) <= 0.5).astype(float)
def gauss(t):
return np.exp(-t*t)
def triang(t):
return (1-abs(t)) * rect(t/2)
tstart = 10
Fs = 1000
t = np.arange(-tstart, tstart, 1/Fs)
f = np.arange(-Fs/2, Fs/2, Fs/len(t))
x = rect
y = gauss
X = ft(x(t), Fs, -tstart)
Y = ft(y(t), Fs, -tstart)
def showLinearity(a):
plt.subplot(221)
plt.plot(t, x(t), label='$x(t)$')
plt.plot(t, y(t), label='$y(t)$')
plt.subplot(222)
plt.plot(f, X.real, label='$X(f)$')
plt.plot(f, Y.real, label='$Y(f)$')
xplusay = lambda t: x(t) + a*y(t)
XplusaY = ft(xplusay(t), Fs, -t0)
plt.subplot(223)
plt.plot(t, xplusay(t), '-*', label='$x(t)+ay(t)$', markevery=400)
plt.plot(t, x(t), label='$x(t)$')
plt.plot(t, a*y(t), label='$ay(t)$')
plt.subplot(224)
plt.plot(f, XplusaY.real, '-*', label='$X(f)+aY(f)$', markevery=10)
plt.plot(f, X.real, label='$X(f)$')
plt.plot(f, a*Y.real, label='$aY(f)$')
As visible, the Fourier Transform of a linear combination of two input signals is the same linear combination of the Fourier Transforms of the input signal.
The time-shifting property means that a shift in time corresponds to a phase rotation in the frequency domain:
$$\mathcal{F}\{x(t-t_0)\} = \exp(-j2\pi ft_0)X(f). $$Let us verify this property numerically with the code below. For example, see that for a time-shift of 1s, in the spectrum the phase rotates by one full period every Hz.
x = rect
X = ft(x(t), Fs, -tstart)
def showShift(t0):
plt.gcf().clear()
plt.subplot(121)
plt.plot(t, x(t), label='$x(t)$')
plt.plot(t, x(t-t0), label='$x(t-t_0)$')
plt.subplot(122)
Xt0 = ft(x(t-t0), Fs, -tstart)
plt.plot(f, X.real, label='Re $X(f)$')
plt.plot(f, Xt0.real, label='Re $X_{t_0}(f)$')
plt.plot(f, Xt0.imag, label='Im $X_{t_0}(f)$')
Apparently, a shift in the time domain corresponds to a phase rotation in the frequency domain. In particular, when the time-shift equal 1s (or in general: $t_0$), the period of the phase rotation in frequency domain amounts 1Hz (or in general $1/t_0$Hz).
Modulation means multiplying a signal with a complex exponential. In the Fourier Transform, modulating a signal in time domain corresponds to shifting it in the frequency domain. As such, it is the counterpart of shifting in the time domain (which corresponds to modulation in frequency domain). Mathematically, we have
$$ \mathcal{F}\{\exp(j2\pi f_0t)x(t)\} = X(f-f_0). $$Let us verify this property numerically. For example, when the signal is multiplied with a complex exponential of 1Hz frequency, the corresponding spectrum of the signal is shifted by 1Hz.
x = gauss
X = ft(x(t), Fs, -tstart)
def showModulation(f0):
plt.gcf().clear()
xf0 = lambda t: np.exp(2j*np.pi*f0*t) * x(t)
plt.subplot(121)
plt.plot(t, x(t), label='$x(t)$')
plt.plot(t, xf0(t).real, label=r'Re $\exp(j2\pi f_0t)x(t)$')
plt.plot(t, xf0(t).imag, label=r'Im $\exp(j2\pi f_0t)x(t)$')
plt.subplot(122)
Xf0 = ft(xf0(t), Fs, -tstart)
plt.plot(f, X.real, label='Re $X(f)$')
plt.plot(f, Xf0.real, label='Re $X(f-f_0)$')
See, how a multiplication with a complex exponential in the time domain corresponds to a shift in the frequency domain. In particular, if we multiply the time domain with a complex exponential with a period of $1s$, then the shift in frequency domain amounts 1Hz.
This article has shown the most basic properties of the Fourier Transform, namely
We have illustrated these properties with animations, showing the behaviour when the parameters change. Of particular interest:
Time-shifting a function by $1s$ corresponds to multiplying the frequency domain with a complex exponential with period $1/(1s)=1Hz$.
Multiplying a function with a complex exponential with period $t_0=1/f_0$, corresponds to shifting the frequency domain by $1/t_0=f_0$.
Do you have questions or comments? Let's dicuss below!