Problem 5.49 Explanation¶
Find the Fourier coefficients $a_n$ and $b_n$ for the function shown in Figure 5.23, comparing the function with itself with the first couple of terms in the Fourier series.
Solution¶
This problems wants us to decompose this triangle wave into discrete Fourier space. That is, return the list of Fourier coefficients $a_n$ and $b_n$. The coeficients are defined on page 194 and 195:
$$ \begin{align} f(t) &= \sum_{n=0}^\infty [a_n \cos(n \omega t) + b_n \sin(n \omega t)] \\ a_0 &= \frac{1}{\tau} \int_{-\tau/2}^{\tau/2} f(t) dt \\ a_n &= \frac{2}{\tau} \int_{-\tau/2}^{\tau/2} f(t) \cos(n \omega t) dt \\ b_n &= \frac{2}{\tau} \int_{-\tau/2}^{\tau/2} f(t) \sin(n \omega t) dt \end{align} $$We also need to define out $f(x)$. Looking at the function we can define it on the domain $(-1, 1]$ as $$ f(t) = \begin{cases} f_{max}t+f_{max} & -1 \lt t \le 0 \\ -f_{max}t+f_{max} & 0 \lt t \le 1 \end{cases} $$
We can get away with only defining thi section because it will just be repeating this small section.
import numpy as np
import matplotlib.pyplot as plt
def triangle_function(t, f_max):
if -1 < t <= 0:
return f_max*(t+1)
if 0 < t <= 1:
return f_max*(-t+1)
else:
return np.nan
def triF(ts, f_max):
return np.array([triangle_function(t, f_max) for t in ts])
xs = np.linspace(-1, 1, 100)
fig, ax = plt.subplots()
ax.plot(xs, triF(xs, 1))
plt.show()
We can now start doing the Fourier transform. First we want to identify $\omega$ and $\tau$. It is easy to see that our function is periodic every 2 time steps, so we can set $\tau = 2$. We can then say $\omega = \frac{2 \pi}{\tau} = \pi$. Note that $f(t)$ is an even function.
$ \begin{align} a_0 &= \frac{1}{\tau} \int_{-\tau/2}^{\tau/2} f(t) dt \\ &= \frac{f_{max}}{2} \int_{-1}^{0} (t+1) dt + \frac{f_{max}}{2} \int_{0}^{1} (-t+1) dt \\ &= f_{max} \int_{0}^{1} (-t+1) dt \\ &= f_{max} [-t^2/2+t]_0^1 \\ &= f_{max} (-1/2+1) \\ &= f_{max}/2 \\ \end{align} $
This is the vertical shift of our function. It is sometimes called the DC offset.
$ \begin{align} a_n &= \frac{2}{\tau} \int_{-\tau/2}^{\tau/2} f(t) \cos(n \omega t) dt \\ &= \frac{2}{2} \int_{-1}^{1} f(t) \cos(\pi n t) dt \\ &= 2 f_{max} \int_{0}^{1} (1-t) \cos(\pi n t) dt \\ &= -2 f_{max} \frac{\cos\left(\pi n\right) - 1}{\pi^{2} n^{2}} \\ \end{align} $
You might notice that the value of $\cos(\pi n) - 1$ is zero if $n$ is even and $-2$ if $n$ is odd. You can then rewrite this as $$ a_n = -2 f_{max} (-2) / (\pi^2 n^2) = \frac{4 f_{max}}{\pi^2 n^2} $$ for odd $n$ only if you wanted to. The integrand for $b_n$ is odd so $b_n=0$.
We now have everything for an approximation of the original function. The nice thing about or approximation is that it is now differentiable. Adding more terms gets us closer to the actual answer.
f_max = 1
frequency = np.pi
def a_n(n):
if n == 0:
return f_max / 2
else:
return -2*f_max*(np.cos(np.pi*n)-1)/(np.pi**2 * n**2)
def fourier_approximation(n, t):
final = 0
for n in range(n+1):
final += a_n(n) * np.cos(n*frequency*t)
return final
fig, axs = plt.subplots(2, 2)
axs = axs.flatten()
ts = np.linspace(-3, 3, 100)
for i, n in enumerate([1, 3, 5, 21]):
# print(fourier_approximation(n, 0))
axs[i].set_title(f"n={n} Fourier terms")
axs[i].plot(ts, [fourier_approximation(n, t) for t in ts])
axs[i].plot(xs, triF(xs, 1))