执行fftshift和ifftshift的正确顺序(在python中)

时间:2017-02-10 05:10:28

标签: python scipy fft

我希望对函数psi(x)进行傅里叶变换,将其乘以k空间函数exp(-kx^2-ky^2),然后将傅里叶逆变换产生回x空间。

但我的x空间和k空间网格是居中的,我知道我需要fftshiftifftshift来正确实现我的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))))

1 个答案:

答案 0 :(得分:1)

不,你没有,但没关系,这可能非常令人困惑。

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

第二:由于KXKY来自他们的中心,你必须取消他们:你需要spfft.ifftshift(np.exp(-(KX**2 + KY**2))(注意i)。

最后:您的输出psi因此将起源于它。如果您希望其原点像KXfftshift那样居中。

总结:

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

其中inputOriginStart是输入psi,假设它的起源位于开头,而outputOriginStart是输出psi - 为了清晰起见而重命名。 (我总是说清楚。如果它不起作用,你可以更容易地弄明白。)

编辑修正了提问者指出的错误 - 是的,我有一个错误,在开始时留下psiOriginStart的来源;然后ifftshift KXKY的居中原点函数。 (如果您想将outputOriginStart的原点移至中心,请使用fftshift。)

编辑2 将过滤器(KXKY的功能)从数据中分离出来,使正确的括号显而易见。

如何保持这些直线?要记住一些技巧:

  • fftifft始终需要输入并提供其起源位于开头的输出。这应该很容易从经验中记住。
  • fftshift采用fft需要/生成的起始来源并将原点移至中心。同样,我倾向于容易记住这一点,因为输入fftshift(fft(...))一千次的肌肉记忆。
  • 最后,唯一剩下的就是推断ifftshiftfftshift的倒数:它采用居中原点矢量/数组并将原点移到开头。