3
votes

I'm trying to make sense of the differences between these two numpy Fourier transforms:

import numpy as np

samples = 256

# define the domain in slightly different ways
t_1 = np.linspace( 0.0, 1.0, samples )
t_2 = np.arange( 0.0, 1.0, 1.0/samples )

## The two domains are not identical, but they're close
print np.sum( (t_1 - t_2) ** 2 )
# 0.0013046364379084878

# simple sin wave
f = lambda t : 2 * np.sin( 2 * 2 * pi * t )

# signals over each domain
s_1 = f( t_1 )
s_2 = f( t_2 )

# fourier transform
fft_1 = np.fft.fft( s_1 )
fft_2 = np.fft.fft( s_2 )

freq = np.fft.fftfreq( samples )

# plot the FFT differences
plt.figure()
plt.subplot( 2,1,1 )
plt.plot( freq, fft_1, 'x' )
plt.subplot( 2,1,2 )
plt.plot( freq, fft_2, 'x' )

fft_plot

In one case, the single frequency in the signal is clearly detected, and in the other it's not. Is one procedure more correct than the other?

1

1 Answers

3
votes

The two plots are more similar than you realize. Keep in mind that the fft returns a complex array. Also a shift of the input function results in a phase shift in the "k-space". Because 2*sin(a*pi*x) == i*(exp(i*a*pi*x) - exp(-i*a*pi*x)), s_2 has all of it's power in the imaginary component of k-space (notice the y axis is on the order of 1e-12), s_1 is shifted slightly so you see a little bit of signal in the real component of k-space, but most of the power is still in the imaginary component. See what happens when I plot the magnitude, abs(k-space), instead of plotting just the real component (which is what matplotlib seems to do when given complex numbers).

import numpy as np

samples = 256

# define the domain in slightly different ways
t_1 = np.linspace( 0.0, 1.0, samples )
t_2 = np.arange( 0.0, 1.0, 1.0/samples )

## The two domains are not identical, but they're close
print np.sum( (t_1 - t_2) ** 2 )
# 0.0013046364379084878

# simple sin wave
f = lambda t : 2 * np.sin( 2 * 2 * pi * t )

# signals over each domain
s_1 = f( t_1 )
s_2 = f( t_2 )

# fourier transform
fft_1 = np.fft.fft( s_1 )
fft_2 = np.fft.fft( s_2 )

freq = np.fft.fftfreq( samples )

# plot the FFT differences
plt.figure()
plt.subplot( 2,1,1 )
plt.plot( freq, np.abs(fft_1.imag), 'x' )
plt.subplot( 2,1,2 )
plt.plot( freq, np.abs(fft_2.imag), 'x' )

PLot of abs(fft(f))