Last active

Perfect FFT

  • Download Gist
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
from __future__ import division
from pylab import *
# Sampling rate
fs = 128 # Hz
# Time is from 0 to 1 seconds, but leave off the endpoint, so that 1.0 seconds is the first sample of the *next* chunk
length = 1 # second
N = fs * length
t = linspace(0, length, num = N, endpoint = False)
# Generate a sinusoid at frequency f
f = 10 # Hz
a = cos(2 * pi * f * t)
# Use FFT to get the amplitude of the spectrum
ampl = 1/N * abs(fft(a))
# FFT frequency bins
freqs = fftfreq(N, 1/fs)
# Plot shifted data on a shifted axis
stem(fftshift(freqs), fftshift(ampl))

This is just a note to self, for remembering the little details about NumPy's FFT implementation.

  • To get the FFT bins to line up perfectly, without any "skirts" or spectral leakage, you need to make a perfect cycle, where the next sample after this chunk lines up with the first. (In other words, the first and last samples should not be the same.)
  • To get a sinusoid of amplitude 1 to produce 2 complex exponentials of amplitude 0.5, you need to divide the fft() results by the number of samples.
  • The fft() output is from 0 Hz to Nyquist frequency to sampling rate. To plot the spectrum from negative Nyquist frequency to positive Nyquist frequency, with 0 in the center, use fftshift() on both the freqs and ampl variables. You can also just use fftfreq() to generate a horizontal axis for plotting, but the plot will have extraneous lines on it.
  • If the result of an IFFT has some complex residue, use real() to get rid of it, not abs().

The function stem does not work? It is from which module? Thanks


from matplotlib.pyplot import stem

or just

from pylab import *

which is what I do

Thanks a lot, endolith.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.