1
$\begingroup$

I have written a code to compute the Fast Fourier Transform of a simple complex exponential with frequency $f=50.0$, using scipy.fft. The code is written below:

import numpy as np
from scipy.fft import fft, fftfreq, fftshift
import matplotlib.pyplot as plt

T = 10
dt = 0.001
f = 50.0 

x = np.arange(0.0, T, dt)
y = np.exp(1.j * 2 * np.pi * f * x)

xf = fftfreq(len(x), dt)
xf = fftshift(xf)

yf = fft(y)
yf = fftshift(yf)

plt.plot(xf, 1.0/len(x) * yf, label='yf')
plt.plot(xf, 1.0/len(x) * np.abs(yf), label='abs(yf)')
plt.xlabel('f')
plt.legend()
plt.show()

The output of the calculation is a frequency spectrum with a single peak, for both yf and its absolute value (which are perfectly overlapped) centered at frequency $f=50.0$:

Now instead of using the frequency, I assume to work with an angular frequency $\omega=50.0$:

import numpy as np
from scipy.fft import fft, fftfreq, fftshift
import matplotlib.pyplot as plt

T = 10
dt = 0.001
omega = 50.0 

x = np.arange(0.0, T, dt)
y = np.exp(1.j * omega * x)

xf = fftfreq(len(x), dt)
xf = fftshift(xf)

yf = fft(y)
yf = fftshift(yf)

plt.plot(2 * np.pi * xf, 1.0/len(x) * yf)
plt.plot(2 * np.pi * xf, 1.0/len(x) * np.abs(yf))
plt.show()

In the plot I have multiplied xf by $2 \pi$ to convert from frequency $f$ to angular frequency $\omega$. Surely this corresponds to a frequency $f = \frac{\omega}{2 \pi}$ different from the first example but I would have expected similar behavior. In this case yt have a kind of dispersive shape, while its absolute value is very broad, it is not normalized and it is not perfectly peaked at $\omega=50.0$ but it is slightly shifted to $50.26$.

enter image description here

Could someone give me some explanation about this unexpected behavior? If I have to work with raw data, coming from a complex calculation, expressed in terms of angular frequency $\omega$, how can I obtain trusty results from the second programs?

$\endgroup$
0
2
$\begingroup$

This is probably the single most asked question on this forum. A similar one was asked and answered just a few hours ago: Spectral leakage from mathematical point of view

Your expectations are wrong: you only get a spectral dirac impulse if the frequency of the complex exponential on he FFT grid, i.e. an integer multiple of the sample rate divided by the FFT length. In your case you have $N_{FFT} = 10000$ and $F_s = 1000$, so your FFT bin spacing is 0.1 Hz. 50 Hz is an integer multiple of 0.1Hz but $50/(2\pi)$ isn't and so the energy will spread out over the adjacent bins.

A different way to look at it: the DFT assumes that the time signal is periodic with the FFT length. Since your exponential does NOT have an integer number of periods inside one FFT frame, the periodic repetition creates a discontinuity at the frame boundary

$\endgroup$
4
  • $\begingroup$ Thanks for your answer and sorry if it is a duplicate. So FFT is unuseful for non-periodic signals? How can we deal with them? $\endgroup$ – Bruscaliffo Dec 26 '20 at 18:00
  • 1
    $\begingroup$ Of course it's useful for non-periodic signals as well. You just need to understand how it works and how the FFT results & parameters relate to the requirements of your specific application. $\endgroup$ – Hilmar Dec 26 '20 at 19:59
  • $\begingroup$ Do you recommend any resource or python tutorial to understand FFT more deeply? $\endgroup$ – Bruscaliffo Dec 26 '20 at 21:11
  • $\begingroup$ @Bruscaliffo en.wikipedia.org/wiki/Spectral_leakage#Window_tradeoffs $\endgroup$ – endolith Dec 28 '20 at 1:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.