Source Material:

The following exercises are adapted from Chapter 7 of Mark Newman’s book, “Computational Physics”

Exercises: DFTs of Various Signals

In this notebook, you will be generating samples from various functions, \(f(t)\) over a given duration \(t \in [0, T)\) and for a specified number of samples \(N\). I.e. the samples are \(y_n = f(t_n)\).

Then you will use the discrete Fourier transform to compute \((c_k)_{k=0}^{\lfloor \frac{N}{2} \rfloor}\) for those samples, and then convert these to \((|a_k|)_{k=0}^{\lfloor \frac{N}{2} \rfloor}\) and \((|\varphi'_k|)_{k=0}^{\lfloor \frac{N}{2} \rfloor}\)

You will plot both the sampled wave form of \(f\) – a scatter plot of \((t_n, y_n)\) – and the Fourier spectrum of \(f\) – a histogram/stem chart of \((|a_k|)_{k=0}^{\lfloor \frac{N}{2} \rfloor}\) vs \((|\nu_k|)_{k=0}^{\lfloor \frac{N}{2} \rfloor}\)

Make sure that your time values \(t_n\) and frequencies \(\nu_k\) all have the appropriate physical units for the specified signal. E.g. most wave form plots should have “seconds” on the x axis, and most Fourier spectra should have “1/seconds (Hz)” on the x axis.

For all problems, take \(N = 1,000\) as the number of samples

[ ]:
import numpy as np
import matplotlib.pyplot as plt
from typing import Tuple

%matplotlib notebook

(1.5.1) Generate \(N=1,000\) samples of a single period of a square wave of amplitude \(1\), whose period lasts for \(5\) seconds. A square wave is like a sine-wave, except a square wave only takes on values of \(1\) (wherever \(\sin(x)\) is positive) or \(-1\) (wherever \(\sin(x)\) is negative). An example of eight samples of a single period of a square wave with amplitude 1 is:

[1, 1, 1, 1, -1, -1, -1, -1]

Also compute the Fourier coefficients, \((|a_k|)_{k=0}^{\lfloor \frac{N}{2} \rfloor}\), for these samples.

Plot the sampled wave form of this square wave versus time and plot the Fourier spectrum, \(|a_{k}|\) vs \(\nu_{k}\).

Here is some code that you can use to plot these side-by-side:

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 4))
ax1.plot(t, y, marker="o")  # plot time (t) and waveform-samples (y)
ax1.grid()
ax1.set_xlabel("t (seconds)")  # make sure `t` actually represents seconds!

ax2.stem(freqs, amps, basefmt=" ", use_line_collection=True) # plot frequency (freqs) and amplitudes (amps)
ax2.set_xlim(0, 10)
ax2.grid()
ax2.set_ylabel(r"$|a_{k}|$")
ax2.set_xlabel(r"$\nu_{k}$ (Hz)")  # make sure `freqs` actually represents Hertz!
fig.tight_layout()
[ ]:
# STUDENT CODE HERE

(1.5.2) \(f\) is a simple linear function \(f(t) = t\) on \(t \in [0, 1000)\) seconds. Using \(N = 1,000\) samples, plot both the sampled waveform and the Fourier spectrum, \(|a_{k}|\) vs \(\nu_{k}\).

[ ]:
# STUDENT CODE HERE

(1.5.3) \(f\) is the modulated wave: \(\sin\!\big(2\pi\frac{1}{2Q}t\big) \sin\!\big(2 \pi\frac{10}{Q}t\big)\), where \(Q=5\:\mathrm{seconds}\). Sample this signal starting from \(t=0\) over one period of the lower-frequency term (a.k.a the modulating term): \(\sin\!\big(2\pi\frac{1}{2Q}t\big)\), using \(N = 1,000\) samples.

  • What are the frequencies of the respective terms in our modulated wave, in Hz?

  • Do you expect that these two frequencies present in the Fourier spectrum? Why might we expect for different frequencies to be prominent in our series (hint: compare the functional form of this waveform to that of a Fourier series)?

  • Use the relationship \(\sin{(a)}\sin{(b)}=\frac{1}{2}(\cos{(a-b)} - \cos{(a+b)})\) to rewrite this modulated wave as a sum of cosines. From this, predict the number, locations, and heights of the peaks in your Fourier spectrum.

  • Plot the wave form vs time and plot the Fourier spectrum, \(|a_{k}|\) vs \(\nu_{k}\). Be sure to zoom in on your peaks and check that they are located where you expect them to be.

SOLUTION HERE

[ ]:
# STUDENT CODE HERE

(1.5.4) \(f\) is a signal that produced uniform random noise on \([-1, 1)\). np.random.rand generates random numbers on \([0, 1)\). Define a Python function noise:

def noise(t: np.ndarray) -> np.ndarray:
    # t is a shape-(N,) array
    # Use np.random.rand to draw a shape-(N,)
    # array of uniform random numbers on [0, 1)
    #
    # Modify these numbers so that they instead fall
    # on the range [-1, 1)
    #
    # return these random samples

Use this to generate \(N = 1,000\) samples of a noisy signal last for \(5\) seconds. Plot the sampled wave form and Fourier spectrum. Do you see any pattern in the Fourier spectrum?

[ ]:
# STUDENT CODE HERE