正确执行 fftshift 和 ifftshift 的顺序(在 python 中)
Correct order of implementing fftshift and ifftshift (in python)
我想对一个函数psi(x)
进行傅里叶变换,乘以一个k-space函数exp(-kx^2-ky^2)
,然后傅里叶逆变换回x-space.
但是我的 x-space 和 k-space 网格是居中的,我知道我需要 fftshift
和 ifftshift
来实现我的 k-space乘法正确。但是我不明白它们是如何工作的,所以我不知道按什么顺序来实现它们。有人可以告诉我我在这里做的是否正确吗?
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
要求原点位于矢量的开头(或者在二维情况下,位于数组的 top-left 处)。输入 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
- 为清楚起见重命名。 (我总是为了清楚起见。如果它不起作用,你可以更容易地弄清楚。)
编辑修正了提问者指出的错误——是的,我错了,开头留下psiOriginStart
的出处;然后 ifftshift
KX
和 KY
的 centered-origin 函数。 (如果你想取消 outputOriginStart
的原点到中心然后使用 fftshift
。)
编辑 2 将过滤器(KX
和 KY
的功能)与数据分开,使正确的括号显而易见。
如何保持这些笔直?需要记住的一些技巧:
fft
和 ifft
总是需要输入并给出起源在开头的输出。根据经验,这应该很容易记住。
fftshift
取 fft
needs/makes 的 beginning-origin 并将原点移到中心。同样,我倾向于很容易记住这一点,因为 muscle-memory 键入 fftshift(fft(...))
一千次。
- 最后,唯一剩下的就是推导出
ifftshift
是 fftshift
的倒数:它需要 centered-origin vectors/arrays 并将原点移到开头。
我想对一个函数psi(x)
进行傅里叶变换,乘以一个k-space函数exp(-kx^2-ky^2)
,然后傅里叶逆变换回x-space.
但是我的 x-space 和 k-space 网格是居中的,我知道我需要 fftshift
和 ifftshift
来实现我的 k-space乘法正确。但是我不明白它们是如何工作的,所以我不知道按什么顺序来实现它们。有人可以告诉我我在这里做的是否正确吗?
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
要求原点位于矢量的开头(或者在二维情况下,位于数组的 top-left 处)。输入 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
- 为清楚起见重命名。 (我总是为了清楚起见。如果它不起作用,你可以更容易地弄清楚。)
编辑修正了提问者指出的错误——是的,我错了,开头留下psiOriginStart
的出处;然后 ifftshift
KX
和 KY
的 centered-origin 函数。 (如果你想取消 outputOriginStart
的原点到中心然后使用 fftshift
。)
编辑 2 将过滤器(KX
和 KY
的功能)与数据分开,使正确的括号显而易见。
如何保持这些笔直?需要记住的一些技巧:
fft
和ifft
总是需要输入并给出起源在开头的输出。根据经验,这应该很容易记住。fftshift
取fft
needs/makes 的 beginning-origin 并将原点移到中心。同样,我倾向于很容易记住这一点,因为 muscle-memory 键入fftshift(fft(...))
一千次。- 最后,唯一剩下的就是推导出
ifftshift
是fftshift
的倒数:它需要 centered-origin vectors/arrays 并将原点移到开头。