我想数值计算numpy数组Y上的FFT.为了测试,我使用高斯函数Y = exp(-x ^ 2).(符号)傅立叶变换是Y'=常数*exp(-k ^ 2/4).
import numpy
X = numpy.arange(-100,100)
Y = numpy.exp(-(X/5.0)**2)
Run Code Online (Sandbox Code Playgroud)
天真的方法失败了:
from numpy.fft import *
from matplotlib import pyplot
def plotReIm(x,y):
f = pyplot.figure()
ax = f.add_subplot(111)
ax.plot(x, numpy.real(y), 'b', label='R()')
ax.plot(x, numpy.imag(y), 'r:', label='I()')
ax.plot(x, numpy.abs(y), 'k--', label='abs()')
ax.legend()
Y_k = fftshift(fft(Y))
k = fftshift(fftfreq(len(Y)))
plotReIm(k,Y_k)
Run Code Online (Sandbox Code Playgroud)
实数(Y_k)在正值和负值之间跳跃,这对应于跳跃阶段,这在符号结果中不存在.这当然是不可取的.(结果在技术上是正确的,因为abs(Y_k)给出了预期ifft(Y_k)为Y的幅度.)
这里,函数fftshift()使数组k单调递增并相应地改变Y_k.通过对两个向量应用此操作,不会更改对zip(k,Y_k).
此更改似乎可以解决此问题:
Y_k = fftshift(fft(ifftshift(Y)))
k = fftshift(fftfreq(len(Y)))
plotReIm(k,Y_k)
Run Code Online (Sandbox Code Playgroud)
如果需要单调Y和Y_k,这是使用fft()函数的正确方法吗?
以上的反向操作是:
Yx = fftshift(ifft(ifftshift(Y_k)))
x = fftshift(fftfreq(len(Y_k), k[1] - k[0]))
plotReIm(x,Yx)
Run Code Online (Sandbox Code Playgroud)
对于这种情况,文档清楚地指出Y_k必须与fft()和fftfreq()的输出进行排序,我们可以通过应用ifftshift()来实现.
那些问题一直困扰着我很长时间:fft()和ifft()的输出和输入数组是否总是如此a[0] should contain the zero frequency term, a[1:n/2+1] should contain the positive-frequency terms, and a[n/2+1:] should contain the negative-frequency terms, in order of decreasingly negative frequency[numpy reference],其中'frequency'是自变量?
FFT 可以被认为是产生一组向量,每个向量都有幅度和相位。fft_shift 操作将零相位角的参考点从 FFT 孔径的边缘更改为原始输入数据矢量的中心。
完成此操作后,结果的相位(以及复矢量的实数分量)有时不会那么“跳跃”,特别是如果某些输入函数被加窗,使其在 FFT 孔径边缘周围不连续。或者,如果输入围绕 FFT 孔径中心对称,则 FFT 结果的相位在 fft_shift 后将始终为零。
fft_shift 可以通过 N/2 的向量旋转来完成,或者通过简单地翻转 FFT 结果中的交替符号位来完成,这可能对 CPU dcache 更友好。