我正在使用 numpy 和 matplotlib 来分析来自我的模拟的数据输出。有一个(明显的)不一致我找不到根源。这是以下内容:
我有一个具有给定能量 a^2~1 的信号。当我使用 rfft 进行 FFT 并计算傅立叶空间中的能量时,结果明显更大。为了避免提供我的数据等的详细信息,这里有一个简单的正弦波示例:
from pylab import *
xx=np.linspace(0.,2*pi,128)
a=np.zeros(128)
for i in range(0,128):
a[i]=sin(xx[i])
aft=rfft(a)
print mean(abs(aft)**2),mean(a**2)
原则上,这两个数字应该相同(至少在数字意义上),但这就是我从这段代码中得到的:
62.523081632 0.49609375
我试图通过 numpy.fft 文档但找不到任何东西。此处的搜索给出了以下内容,但我无法理解那里的解释:
Big FFT amplitude difference between the existing (synthesized) signal and the filtered signal
我错过了什么/误解了什么?在这方面的任何帮助/指针将不胜感激。
谢谢!
最佳答案
Henry 在非规范化部分是正确的,但还有一点,因为您使用的是 rfft
,而不是 fft
。以下与他的回答一致:
>>> x = np.linspace(0, 2 * np.pi, 128)
>>> y = 1 - np.sin(x)
>>> fft = np.fft.fft(y)
>>> np.mean((fft * fft.conj()).real)
191.49999999999991
>>> np.mean(y**2)
1.4960937500000004
>>> fft = fft / np.sqrt(len(fft))
>>> np.mean((fft * fft.conj()).real)
1.4960937499999991
但是,如果您现在对
rfft
进行相同的尝试,事情就不太顺利了:>>> rfft = np.fft.rfft(y)
>>> np.mean((rfft * rfft.conj()).real)
314.58462009358772
>>> rfft /= np.sqrt(len(rfft))
>>> np.mean((rfft * rfft.conj()).real)
4.8397633860551954
65
>>> np.mean((rfft * rfft.conj()).real) / len(rfft)
4.8397633860551954
不过,以下确实可以正常工作:
>>> (rfft[0] * rfft[0].conj() +
... 2 * np.sum(rfft[1:] * rfft[1:].conj())).real / len(y)
1.4960937873636722
当您使用
rfft
时,您得到的不是数据的 DFT,而是数据的正半部分,因为负数与其对称。要计算平均值,您需要将 DC 分量以外的每个值都考虑两次,这就是最后一行代码所做的。关于python - (numpy)FFT 数组的幅度错误(?)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15147287/