我有一个时间信号,我计算其傅立叶变换以获得频率信号。根据Parseval定理,这两个信号具有相同的能量。我用Python成功演示了它。然而,当我计算频率信号的逆傅立叶变换时,能量不再被保存。这是我的代码:
import numpy as np
import numpy.fft as nf
import matplotlib.pyplot as plt
#create a gaussian as a temporal signal
x = np.linspace(-10.0,10.0,num=1000)
dx = x[1]-x[0]
sigma = 0.4
gx = (1.0/(2.0*np.pi*sigma**2.0)**0.5)*np.exp(-0.5*(x/sigma)**2.0)
#calculate the spacing of the frequencial signal
f=nf.fftshift(nf.fftfreq(1000,dx))
kk = f*(2.0*np.pi)
dk = kk[1]-kk[0]
#calculate the frequencial signal (FT)
#the convention used here allows to find the same energy
gkk = nf.fftshift(nf.fft(nf.fftshift(gx)))*(dx/(2.0*np.pi)**0.5)
#inverse FT
gx_ = nf.ifft(nf.ifftshift(gkk))*dk/(2 * np.pi)**0.5
#Parseval's theorem
print("Total energy in time domain = "+str(sum(abs(gx)**2.0)*dx))
print("Total energy in freq domain = "+str(sum(abs(gkk)**2.0)*dk))
print("Total energy after iFT = "+str(sum(abs(gx_)**2.0)*dx))
执行此代码后,您可以看到两个第一能量是相同的,而第三个是比第一个能量小的数量级,但我应该找到相同的能量。这里发生了什么?
答案 0 :(得分:4)
numpy
FFT程序实际上和其他软件相比,确实调整了序列长度,以便你得到
nf.ifft(nf.fft(gx)) == gx
高达一些浮点错误。如果dx
和dk
按常规方式计算,则dk*dx=(2*pi)/N
仅适用于未经调整的FFT例程。
您可以使用
测试numpy.fft
的行为
In [20]: sum(abs(gx)**2.0)
Out[20]: 35.226587122763036
In [21]: gk = nf.fft(gx)
In [22]: sum(abs(gk)**2.0)
Out[22]: 35226.587122763049
In [23]: sum(abs(nf.ifft(gk))**2.0)
Out[23]: 35.226587122763014
告诉我们fft
是通常未调整的转换,ifft
将结果除以序列长度N=num
。
ifft
gxx = (nf.fft(gk.conj())).conj()
然后你得到了
gx == gxx/1000
最多浮点错误。或者您可以使用
撤消调整#inverse FT
gx_ = nf.ifft(nf.ifftshift(gkk))*(num*dk)/(2 * np.pi)**0.5