Fourier transform
We begin with the usual loading of modules.
import numpy as np # for numerics
import sympy as sp # for symbolics
import matplotlib.pyplot as plt # for plots!
Let’s consider a periodic function with period (T
). Each period, the function has a triangular
pulse of width (pulse_width
) and height
.
= 15 # period
period = 2 # pulse width pulse_width
First, we plot the function in the time domain. Let’s begin by defining .
def pulse_train(t,T,pulse_width):
= lambda x:pulse_width/2-abs(x) # pulse
f = np.mod(t,T)
tm if tm <= pulse_width/2:
return f(tm)
elif tm >= T-pulse_width/2:
return f(-(tm-T))
else:
return 0
Now, we develop a numerical array in time to plot .
= 151 # number of points to plot
N = np.linspace(-period/2,5*period/2,N) # time values
tpp = np.array(np.zeros(tpp.shape))
fpp for i,t_now in enumerate(tpp):
= pulse_train(t_now,period,pulse_width) fpp[i]
Now we plot.
= plt.subplots()
fig, ax 'b-',linewidth=2) # plot
ax.plot(tpp,fpp,'time (s)')
plt.xlabel(-period/2,3*period/2])
plt.xlim([
plt.xticks(0,period],
[0,'$T='+str(period)+'$ s']
[
)0,pulse_width/2],['0','$\delta/2$'])
plt.yticks([ plt.draw()
Consider the following argument. Just as a Fourier series is a frequency domain representation of a periodic signal, a Fourier transform is a frequency domain representation of an aperiodic signal (we will rigorously define it in a moment). The Fourier series components will have an analog, then, in the Fourier transform. Recall that they can be computed by integrating over a period of the signal. If we increase that period infinitely, the function is effectively aperiodic. The result (within a scaling factor) will be the Fourier transform analog of the Fourier series components.
Let us approach this understanding by actually computing the Fourier
series components for increasing period using . We’ll use sympy
to compute the Fourier series cosine and
sine components and for component (n
)
and period (T
).
= sp.symbols('x, a_0, a_n, b_n', real=True)
x, a_0, a_n, b_n = sp.symbols('delta, T', positive=True)
delta, T = sp.symbols('n', nonnegative=True)
n = sp.integrate(
an 2/T*(delta/2-sp.Abs(x))*sp.cos(2*sp.pi*n/T*x),
-delta/2, delta/2) # otherwise zero
(x,
).simplify()= 2/T*sp.integrate(
bn /2-sp.Abs(x))*sp.sin(2*sp.pi*n/T*x),
(delta-delta/2, delta/2) # otherwise zero
(x,
).simplify()print(sp.Eq(a_n,an), sp.Eq(b_n,bn))
Eq(a_n, Piecewise((T*(1 - cos(pi*delta*n/T))/(pi**2*n**2), n > 0), (delta**2/(2*T), True))) Eq(b_n, 0)
Furthermore, let us compute the harmonic amplitude
(f_harmonic_amplitude
): $$\begin{align}
C_n = \sqrt{a_n^2 + b_n^2}
\end{align}$$ which we have also scaled by a factor in order to plot it
with a convenient scale.
= sp.symbols('C_n', positive=True)
C_n = sp.sqrt(an**2+bn**2)
cn print(sp.Eq(C_n, cn))
Eq(C_n, Piecewise((T*Abs(cos(pi*delta*n/T) - 1)/(pi**2*n**2), n > 0), (delta**2/(2*T), True)))
Now we lambdify the symbolic expression for a numpy
function.
= sp.lambdify((n, T, delta), cn) cn_f
Now we can plot. Write a function to plot pulses in the time domain with the corresponding frequency spectrum.
def plot_pulses_and_spectrum(T, pulse_width, omega_max):
= round(omega_max*T/(2*np.pi)) # max harmonic
n_max = np.linspace(0,n_max,n_max+1)
n_a = 2*np.pi*n_a/T
omega = plt.subplots(1, 2)
fig, ax 0])
plt.sca(ax[for i in range(0, 3):
= np.linspace(-T/2, 5*T/2,N)
tpp = np.array(np.zeros(tpp.shape))
fpp for i,t_now in enumerate(tpp):
= pulse_train(t_now, T, pulse_width)
fpp[i] 'b-', linewidth=2)
plt.plot(tpp, fpp, -T/2, 3*T/2])
plt.xlim([0, T], [0, '$T='+str(T)+'$ s'])
plt.xticks([0, pulse_width/2], ['0', '$\delta/2$'])
plt.yticks(['time (s)')
plt.xlabel(1])
plt.sca(ax[
plt.stem(*T/pulse_width, 'bo-'
omega, cn_f(n_a, T, pulse_width)
)0, omega_max])
plt.xlim([0, 1.1])
plt.ylim(['Frequency $\omega$ (rad/s)')
plt.xlabel('$C_n T/\delta$')
plt.ylabel(return fig
Now we plot the pulses and their spectra for rad/s and .
= 12 # Maximum frequency to plot
omega_max = plot_pulses_and_spectrum(5, pulse_width, omega_max)
fig plt.draw()
= plot_pulses_and_spectrum(15, pulse_width, omega_max)
fig plt.draw()
= plot_pulses_and_spectrum(25, pulse_width, omega_max)
fig plt.draw()
The line spectra are shown in the right-hand columns of the plots above. Note that with our chosen scaling, as increases, the line spectra reveal a distinct waveform.
Let be the continuous function of angular frequency $$\begin{align} F(\omega) = \frac{\delta}{2} \cdot \frac{\sin^2(\omega \delta/4)}{(\omega \delta/4)^2}. \end{align}$$ First, we plot it.
def F(w):
return pulse_width/2*np.sin(w*pulse_width/4)**2 / \
*pulse_width/4)**2
(w= 201 # number of points to plot
N = np.linspace(0.0001, omega_max,N)
wpp = []
Fpp for i in range(0,N):
# build array of function values
Fpp.append(F(wpp[i])) = plt.subplots()
fig, ax 'b-', linewidth=2) # plot
plt.plot(wpp, Fpp, 0, omega_max])
plt.xlim([0, pulse_width/2],['0','$\delta/2$'])
plt.yticks(['Frequency $\omega$ (rad/s)')
plt.xlabel('$F(\omega)$')
plt.ylabel( plt.show()
The plot of is clearly emerging from the preceding line spectra as the period increases.
Now we are ready to define the Fourier transform and its inverse. We will define the Fourier transform in two ways: as a trigonometric transform and as a complex transform. We begin with the trigonometric transform and its inverse.
Fourier Transform (Trigonometric)
Fourier transform (analysis): $$\begin{align} A(\omega) &= \int_{-\infty}^\infty y(t) \cos(\omega t) dt \\ B(\omega) &= \int_{-\infty}^\infty y(t) \sin(\omega t) dt. \end{align}$$ Inverse Fourier transform (synthesis): $$\begin{align} y(t) = \frac{1}{2\pi} \int_{-\infty}^\infty A(\omega) \cos(\omega t) d\omega + \frac{1}{2\pi} \int_{-\infty}^\infty B(\omega) \sin(\omega t) d\omega. \end{align}$$
The Fourier transform is a generalization of the Fourier series to aperiodic functions (i.e., functions with infinite period). The complex form of the Fourier transform is more convenient for analysis and computation, as we will see.
Fourier Transform (Complex)
Fourier transform (analysis): $$\begin{align}\label{eq:fourier_transform} \mathcal{F}(y(t)) = Y(\omega) = \int_{-\infty}^\infty y(t) e^{-j\omega t} dt. \end{align}$$ Inverse Fourier transform (synthesis): $$\begin{align}\label{eq:inverse_fourier_transform} \mathcal{F}^{-1}(Y(\omega)) = y(t) = \frac{1}{2\pi}\int_{-\infty}^\infty Y(\omega) e^{j\omega t} d\omega. \end{align}$$
So now we have defined the Fourier transform. There are many
applications, including solving differential equations and frequency
domain
representations—called spectra—of time domain
functions.
There is a striking similarity between the Fourier transform and the Laplace transform, with which you are already acquainted. In fact, the Fourier transform is a special case of a Laplace transform with Laplace transform variable instead of having some real component. Both transforms convert differential equations to algebraic equations, which can be solved and inversely transformed to find time-domain solutions. The Laplace transform is especially important to use when an input function to a differential equation is not absolutely integrable and the Fourier transform is undefined (for example, our definition will yield a transform for neither the unit step nor the unit ramp functions). However, the Laplace transform is also preferred for initial value problems due to its convenient way of handling them. The two transforms are equally useful for solving steady state problems. Although the Laplace transform has many advantages, for spectral considerations, the Fourier transform is the only game in town.
A table of Fourier transforms and their properties can be found in section B.2.
Consider the aperiodic signal with the unit step function and . The signal is plotted below. Derive the complex frequency spectrum and plot its magnitude and phase.
The signal is aperiodic, so the Fourier transform can be computed from [@eq:fourier_transform]: $$\begin{align*} Y(\omega) &= \int_{-\infty}^\infty y(t) e^{j\omega t} dt \\ &= \int_{-\infty}^\infty u_s(t) e^{-a t} e^{j\omega t} dt \tag{def.\ of $y$} \\ &= \int_{0}^\infty e^{-a t} e^{j\omega t} dt \tag{$u_s$ effect} \\ &= \int_{0}^\infty e^{(-a + j\omega) t} dt \tag{multiply} \\ &= \left.\frac{1}{-a+j\omega} e^{(-a + j\omega) t}\right|_{0}^\infty dt \tag{antiderivative} \\ &= \frac{1}{-a+j\omega} \left( \lim_{t\rightarrow \infty} e^{(-a + j\omega) t} - e^0 \right) \tag{evaluate} \\ &= \frac{1}{-a+j\omega} \left( \lim_{t\rightarrow \infty} e^{-a t} e^{j\omega t} - 1 \right) \tag{arrange} \\ &= \frac{1}{-a+j\omega} \left( (0) (\text{complex with mag} \le 1) - 1 \right) \tag{limit} \\ &= \frac{-1}{-a+j\omega} \tag{consequence} \\ &= \frac{1}{a-j\omega} \\ &= \frac{a+j\omega}{a+j\omega}\cdot\frac{1}{a-j\omega} \tag{rationalize} \\ &= \frac{a+j\omega}{a^2 + \omega^2}. \end{align*}$$
The magnitude and phase of this complex function are straightforward to compute: $$\begin{align*} |Y(\omega)| &= \sqrt{\Re(Y(\omega))^2 + \Im(Y(\omega))^2} \\ &= \frac{1}{a^2 + \omega^2}\sqrt{a^2 + \omega^2} \\ &= \frac{1}{\sqrt{a^2 + \omega^2}} \\ \angle Y(\omega) &= \arctan(\omega/a). \end{align*}$$
Now we can plot these functions of $\omega$. Setting $a = 1$ (arbitrarily), we obtain the plots of figure 6.11.
Online Resources for Section 6.3
No online resources.