实现fftshift和ifftshift的正确顺序(在python中)

实现fftshift和ifftshift的正确顺序(在python中),python,scipy,fft,Python,Scipy,Fft,我想对一个函数进行傅里叶变换,将它乘以一个k空间函数exp(-kx^2-ky^2),然后将乘积逆傅里叶变换回x空间 但是我的x空间和k空间网格是居中的,我知道我需要fftshift和ifftshift来正确实现我的k空间乘法。但我不明白它们是如何工作的,所以我不知道以什么样的顺序来实现它们。有人能告诉我我在这里做的是否正确吗 import scipy.fftpack as spfft import numpy as np #Create a centred k-space grid] kxm

我想对一个函数进行傅里叶变换,将它乘以一个k空间函数exp(-kx^2-ky^2),然后将乘积逆傅里叶变换回x空间

但是我的x空间和k空间网格是居中的,我知道我需要
fftshift
ifftshift
来正确实现我的k空间乘法。但我不明白它们是如何工作的,所以我不知道以什么样的顺序来实现它们。有人能告诉我我在这里做的是否正确吗

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))))

不,你没有,但没关系,这可能会让人很困惑

首先:
fft
ifft
要求原点位于向量的开头(或者在2D情况下,位于数组的左上角)。输入
psi
的原点是否像
KX
一样居中?如果是这样,则必须使用
ifftshift
将其原点移到开头。(如果没有,那就别管它了。)

第二:因为
KX
KY
都起源于它们的中心,所以必须取消它们的移位:需要
spfft.ifftshift(np.exp(-(KX**2+KY**2))
(注意
i

最后:您的输出
psi
将因此在一开始就有它的原点。如果您希望它的原点像
KX
一样居中,
fftshift

总之:

inputOriginStart = # ...
inputOriginStartFFT = spfft.fft2(psiOriginStart)
filterOriginStartFFT = spfft.ifftshift(np.exp(-(KX**2 + KY**2)))
outputOriginStart = spfft.ifft2(filterOriginStartFFT * inputOriginStartFFT)
其中,
inputOriginStart
是输入
psi
,假设它的原点在开头,而
outputOriginStart
是输出
psi
,为了清晰起见,将其重命名。(我总是为了清晰起见。如果它不起作用,你可以更容易地找出它。)

Edit修复了询问者指出的错误是的,我犯了一个错误,在开始时离开了
psiOriginStart
的原点;然后
ifftshift
KX
KY
的原点函数居中。(如果要将
OutputOrgInstart
的原点反移位到中心,请使用
fftshift

Edit 2将过滤器(KX和KY的功能)与数据分开,以使正确的括号清晰可见


如何保持这些笔直?请记住一些技巧:

  • fft
    ifft
    始终需要输入,并给出起源于开始的输出。根据经验,这应该很容易记住
  • fftshift
    fft
    需要/做的起始原点,并将原点移到中心。同样,我倾向于很容易记住这一点,因为输入
    fftshift(fft(…)
    一千次后,我的肌肉记忆都很好
  • 最后,剩下的唯一一件事是推断
    ifftshift
    fftshift
    相反:它采用居中的原点向量/数组,并将原点移到起点

我有一个困惑,为什么
spfft.fftshift(spfft.fft2(psiOriginStart))
?一旦我在左上角进行了傅立叶变换
psiOriginStart
,我需要留在那里与
spfft.ifftshift(np.exp(-(KX**2+KY**2))相乘
,对吗?最后,我
ifftshift
回到中心。所以,它应该是
spfft.ifft2(spfft.ifftshift(np.exp(-(KX**2+KY**2))*spfft.fft2(psiOriginStart))
,对吗?@ap21你完全正确你现在明白了!!!很抱歉混淆了!我编辑了答案。只需注意:在你的评论中,“最后,我将ifftshift移回中心”-不完全是,您将
fftshift
原点从起点移到中心(参见第二个项目符号)。编辑包括此注释。我认为您的妄想可能仍然存在错误。我们只想将
exp(-kx^2+ky^2)
的原点移到
spfft.ifftshift(np.exp)中(-(KX**2+KY**2))
,而不是像你写的那样做
spfft.ifftshift(np.exp(-(KX**2+KY**2))*spfft.fft2(psiOriginStart))
。对吗?哦,不,你又完全正确了,我很惭愧!我编辑了答案以弄清楚是什么。谢谢你的耐心!