Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Discrete Fourier Transform: How to use fftshift correctly with fft

Tags:

python

numpy

fft

I want numerically compute the FFT on a numpy array Y. For testing, I'm using the Gaussian function Y = exp(-x^2). The (symbolic) Fourier Transform is Y' = constant * exp(-k^2/4).

import numpy
X = numpy.arange(-100,100)
Y = numpy.exp(-(X/5.0)**2)

The naive approach fails:

from numpy.fft import *
from matplotlib import pyplot

def plotReIm(x,y):
    f = pyplot.figure()
    ax = f.add_subplot(111)
    ax.plot(x, numpy.real(y), 'b', label='R()')
    ax.plot(x, numpy.imag(y), 'r:', label='I()')
    ax.plot(x, numpy.abs(y), 'k--', label='abs()')
    ax.legend()


Y_k = fftshift(fft(Y))
k = fftshift(fftfreq(len(Y)))
plotReIm(k,Y_k)

real(Y_k) jumps between positive and negative values, which correspond to a jumping phase, which is not present in the symbolic result. This is certainly not desirable. (The result is technically correct in the sense that abs(Y_k) gives the amplitudes as expected ifft(Y_k) is Y.)

Here, the function fftshift() renders the array k monotonically increasing and changes Y_k accordingly. The pairs zip(k, Y_k) are not changed by applying this operation to both vectors.

This changes appears to fix the issue:

Y_k = fftshift(fft(ifftshift(Y)))
k = fftshift(fftfreq(len(Y)))
plotReIm(k,Y_k)

Is this the correct way to employ the fft() function if monotonic Y and Y_k are required?

The reverse operation of the above is:

Yx = fftshift(ifft(ifftshift(Y_k)))
x = fftshift(fftfreq(len(Y_k), k[1] - k[0]))
plotReIm(x,Yx) 

For this case, the documentation clearly states that Y_k must be sorted compatible with the output of fft() and fftfreq(), which we can achieve by applying ifftshift().

Those questions have been bothering me for a long time: Are the output and input arrays of both fft() and ifft() always such that a[0] should contain the zero frequency term, a[1:n/2+1] should contain the positive-frequency terms, and a[n/2+1:] should contain the negative-frequency terms, in order of decreasingly negative frequency [numpy reference], where 'frequency' is the independent variable?

The answer on Fourier Transform of a Gaussian is not a Gaussian does not answer my question.

like image 497
Jan Avatar asked Oct 12 '11 17:10

Jan


People also ask

How do you use Fftshift?

Y = fftshift( X ) rearranges a Fourier transform X by shifting the zero-frequency component to the center of the array. If X is a vector, then fftshift swaps the left and right halves of X . If X is a matrix, then fftshift swaps the first quadrant of X with the third, and the second quadrant with the fourth.

What is the difference between fft and Fftshift?

fft computes the discrete Fourier transform and by definition the output is complex. fftshift doesn't compute anything except swaping the position of the samples, so if your input is real, you get real output.

What does NP fft Fftshift do?

fft. fftshift. Shift the zero-frequency component to the center of the spectrum.

Should I use Fftshift?

It depends on what you are going to do with the transformed data. If you don't perform an fftshift before transforming, the fft result will have every other value multiplied by -1. This doesn't matter if you plan to view the magnitude or magnitude squared of the result.


2 Answers

The FFT can be thought of as producing a set vectors each with an amplitude and phase. The fft_shift operation changes the reference point for a phase angle of zero, from the edge of the FFT aperture, to the center of the original input data vector.

The phase (and thus the real component of the complex vector) of the result is sometimes less "jumpy" when this is done, especially if some input function is windowed such that it is discontinuous around the edges of the FFT aperture. Or if the input is symmetric around the center of the FFT aperture, the phase of the FFT result will always be zero after an fft_shift.

An fft_shift can be done by a vector rotate of N/2, or by simply flipping alternating sign bits in the FFT result, which may be more CPU dcache friendly.

like image 97
hotpaw2 Avatar answered Oct 11 '22 12:10

hotpaw2


The definition for the output of fft (and ifft) is here: http://docs.scipy.org/doc/numpy/reference/routines.fft.html#background-information

This is what the routines compute, no more and no less. Observe that the discrete Fourier transform is rather different from the continuous Fourier transform. For a densely sampled function there is a relation between the two, but the relation also involves phase factors and scaling in addition to fftshift. This is the cause of the oscillations you see in your plot. The necessary phase factor you can work out yourself from the above mathematical formula for the DFT.

like image 44
pv. Avatar answered Oct 11 '22 13:10

pv.