Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct order of implementing fftshift and ifftshift (in python)

Tags:

python

scipy

fft

I want to Fourier transform a function psi(x), multiply it by a k-space function exp(-kx^2-ky^2), and then inverse Fourier transform the product back to x-space.

But my x-space and k-space grids are centred, and I know that I need fftshift and ifftshift to implement my k-space multiplication properly. But I don't understand how they work, so I don't know in which order to implement them. Could someone please tell me if I have done it correctly here?

import scipy.fftpack as spfft
import numpy as np

#Create a centred k-space grid]

kxmax, kymax = 10,10
kxgrid = np.linspace(-kxmax/2, kxmax/2, NX)
kygrid = np.linspace(-kymax/2, kymax/2, NY)
KX, KY = np.meshgrid(kxgrid, kygrid, indexing='xy')

psi = spfft.ifft2(spfft.fftshift(np.exp(-(KX**2 + KY**2)) * spfft.fftshift(spfft.fft2(psi))))
like image 366
ap21 Avatar asked Feb 10 '17 05:02

ap21


1 Answers

No you haven’t, but that’s ok, it can be very confusing.

First thing: fft and ifft require the origin to be in the beginning of the vector (or in your 2D case, in the top-left of the array). Is the input psi’s origin centered like KX? If so, its origin must be shifted to the beginning with ifftshift. (If not, then just leave it alone.)

Second: since KX and KY have origins in their centers, you have to unshift them: you need spfft.ifftshift(np.exp(-(KX**2 + KY**2)) (note the i).

Finally: your output psi will therefore have its origin in the beginning. If you want its origin to be centered like KX, fftshift it.

In summary:

inputOriginStart = # ...
inputOriginStartFFT = spfft.fft2(psiOriginStart)
filterOriginStartFFT = spfft.ifftshift(np.exp(-(KX**2 + KY**2)))
outputOriginStart = spfft.ifft2(filterOriginStartFFT * inputOriginStartFFT)

where inputOriginStart is the input psi assuming it’s origin is in the beginning, and where outputOriginStart is the output psi—renamed for clarity. (I always go for clarity. If it does not work, you can more easily figure it out.)

Edit fixed the error pointed out by the asker—yes, I had a mistake, leave psiOriginStart’s origin at the start; then ifftshift the centered-origin function of KX and KY. (If you want to unshift outputOriginStart’s origin to the center then use fftshift.)

Edit 2 separated the filter (function of KX and KY) from the data to make the correct parentheses obvious.


How to keep these straight? A few tricks to remember:

  • fft and ifft always need inputs and give outputs whose origins are in the beginning. This should be easy to remember from experience.
  • fftshift takes the beginning-origin that fft needs/makes and shifts origin to the center. Again, I tend to readily remember this because of muscle-memory from typing fftshift(fft(...)) a thousand times.
  • Finally, the only remaining thing is to deduce that ifftshift is the inverse of fftshift: it takes centered-origin vectors/arrays and shifts the origin to the beginning.
like image 149
Ahmed Fasih Avatar answered Sep 29 '22 09:09

Ahmed Fasih