This page was generated from notebooks/L6/3_fourier_analysis.ipynb.
Binder badge
You can directly download the pdf-version of this page using the link below.
download

Fourier Analysis#

Fourier analysis, or the approximation of functions as series of sine and cosine functions, can be a very useful tool in the numerical analysis of data as well as in the numerical solution of differential equations. When analyzing experiments, Fourier transforms are frequently used.

  • Optical tweezers are often characterised by the frequency spectrum of position fluctuations.

  • Lock-in detection works by Fourier analysis for a very specific frequency of signals.

  • Optics can be understood with the help of Fourier transforms.

There are a number of other areas where Fourier transforms and analysis are important. We will take a brief look at Fourier series and Fourier transforms from a mathematical point of view. We will apply them to analyse the frequency spectrum of the oscillations of our coupled pendulum. We will come back to this later when we simulate the motion of a Gaussian wave packet for quantum mechanics.

[1]:
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from matplotlib import animation

%matplotlib inline
%config InlineBackend.figure_format = 'retina'

# default values for plotting
plt.rcParams.update({'font.size': 12,
                     'axes.titlesize': 18,
                     'axes.labelsize': 16,
                     'axes.labelpad': 14,
                     'lines.linewidth': 1,
                     'lines.markersize': 10,
                     'xtick.labelsize' : 16,
                     'ytick.labelsize' : 16,
                     'xtick.top' : True,
                     'xtick.direction' : 'in',
                     'ytick.right' : True,
                     'ytick.direction' : 'in',})

# center the plots
from IPython.core.display import HTML
HTML("""
<style>
.output_png {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
}
</style>
""")
[1]:

Fourier series#

A Fourier series is a representation of periodic function f(t) of period 2π or more general as described below on an arbitrary interval T regarding sine and cosine functions

f(t)=A02+k=1(Akcos(ωkt)+Bksin(ωkt))

where ωk=2πkT. T represents the period of the cosine and sine functions. Their amplitude is defined by the coefficients Ak and Bk. The term A0 is a constant offset added to the oscillating sine and consine functions. Equation ??? therefore represents an arbitrary periodic function f(t) on an interval T as a sum of oscillating sine and cosine functions of discrete frequencies (ωk)

ωk=0,2πT,4πT,6πT,...,nπT

and varying amplitudes. The cosine and sine functions in the sum (Eq. ???) can be shown to be orthogonal by using the trigonometric identity

sin(ωit)sin(ωkt)=12{cos((ωiωk)t)cos((ωi+ωk)t}

Therefore the integral

T2+T2sin(ωit)sin(ωkt)dt

can be split into two integrals over a cosine function with the sum (ω1+ω2) and the difference frequency (ω1ω2). As the integration results in a sine function and has to be evaluated at T/2 and T/2 with ωk=k2π/T, (kZ+), the integral results in

T2+T2sin(ωit)sin(ωkt)dt={0for ik,Tfor i=k

Equivalently, the same can be carried out for the cosine functions, which yields

T2+T2cos(ωit)cos(ωkt)dt={0for ik,Tfor i=k

As mentioned above the coefficients Ak and Bk are determined by the projections of the function f(t) onto the basis functions as displayed in Eq.:nbsphinx-math:ref{A_k}-???.

T2+T2cos(ωkt)dt={0for k0,Tfor k=0T2+T2sin(ωkt)dt=0 for all k

Ak=2TT2+T2f(t)cos(ωkt)dt for k0

and for k=0

A0=1TT2+T2f(t)dt

In this case 2T and 1T are the mean values for the Equations. To get the coefficient Bk I need to multiply f(t) with sin(ωkt) and integrate it from T2 to +T2.

As a result of this, we obtain

Bk=2TT2+T2f(t)sin(ωkt)dt,k

Fourier transform#

The Fourier transform is a generalisation of the complex Fourier series to the representation of arbitrary non-periodic functions f(t) by a continuous spectrum of complex functions exp(iωt). This transform is therefore also called continuous Fourier transform. The sum of individual sine and cosine functions with discrete frequencies ωk in the Fourier series is now replaced by an integral over the complex function exp(iωt) with arbitrary continuous values of the frequency ω.

The Fourier transform of the function f(t) is therefore defined by

F(ω)=+f(t)eiωtdt

with F(ω) now representing the spectrum of frequencies contributing to the function f(t). Similarly, the so called inverse Fourier transform of the spectrum F(ω) yields the original function f(t) again (Eq. ???).

f(t)=12π+F(ω)e+iωtdt

Note that the Fourier transform F(ω) is a complex number, which gives you information on the phase and amplitude of the oscillations. Not all of the oscillations have to align in with the same phase. As compared to the last lecture, we may get the phase of the oscillation at a frequency ω by

ϕ=tan1(Im(F(ω))Re(F(ω)))

and the amplitude at a frequency ω by

x0theo=|F(ω)|

There are a number of efficient numerical algorithms available, which simplify the Fourier transformation. These are called Fast Fourier Transforms and implemented in numpy for example. We will use these algorithms to calculate the numerical Fourier transforms of our signals to identify the different oscillations in our signal. Below is an example how the numpy function cab be used and how to obtain the proper frequency axis.

f=np.fft.fft(alpha)
freq = np.fft.fftfreq(t.shape[-1],time/t.shape[-1])

Frequency analysis of our coupled pendula#

To use the Fourier analysis we load the data of our previous simulation with the normal modes and the beat mode of the harmonic oscillator.

[2]:
nm1=np.loadtxt('nm1.txt',delimiter=',')
nm2=np.loadtxt('nm2.txt',delimiter=',')
beats=np.loadtxt('beats.txt',delimiter=',')

The follwing code extracts the data and sorts them into individual arrays for eaysier plotting.

[3]:
t=nm1[:,0]
theta1_nm1=nm1[:,1]
theta1_nm2=nm2[:,1]
theta1_beats=beats[:,1]

The next few lines are mainly for plotting the data but contain also the Fourier transform of the signal.

[4]:
# calculate the frequency spectrum of the oscillations for different initial conditions
plt.figure(1,figsize=(6,5))
plt.xlabel('frequency [Hz]', fontsize=16)
plt.ylabel('Amplitude',fontsize=16)
plt.tick_params(labelsize=14)
ft1=np.fft.fft(theta1_nm1)
freq = np.fft.fftfreq(t.shape[-1],t[-1]/t.shape[-1])
plt.plot(freq[:1000],np.abs(ft1)[:1000],label='normal mode 1')

ft1=np.fft.fft(theta1_nm2)
freq = np.fft.fftfreq(t.shape[-1],t[-1]/t.shape[-1])
plt.plot(freq[:1000],np.abs(ft1)[:1000],label='normal mode 2')

ft1=np.fft.fft(theta1_beats)
freq = np.fft.fftfreq(t.shape[-1],t[-1]/t.shape[-1])
plt.plot(freq[:1000],np.abs(ft1)[:1000],'k--',lw=1,label='beat mode')

plt.legend()
plt.xlim(0.2,0.4)
plt.show()
../../_images/notebooks_L6_3_fourier_analysis_11_0.png

The result of our calculation is now, that the beat mode is actually a superposition of the two normal modes of the system. In fact, it turns out, that all of the possible states of a coupled oscillator system can be constructed from a superposition of its normal modes with specific amplitudes.