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))))
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.ifftshift
is the inverse of fftshift
: it takes centered-origin vectors/arrays and shifts the origin to the beginning.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With