我无法理解scipy
的这种行为从scipy.fftpack
docs中,我了解到fft
的输出显然是复杂的,形状如下:
[y(0),y(1),..,y(n/2),y(1-n/2),...,y(-1)] if n is even
[y(0),y(1),..,y((n-1)/2),y(-(n-1)/2),...,y(-1)] if n is odd
因此,如果绘制类似于
np.abs(fft(signal))
的图,就可以得到fft的大小。如果我的信号是真值的,那么负频率就没有信息,因此可以使用
rfft
来稍微加快速度我不明白的是:为什么rfft
的输出值是实值的,形状奇怪:[y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2))] if n is even
[y(0),Re(y(1)),Im(y(1)),...,Re(y(n/2)),Im(y(n/2))] if n is odd
实际上,有了这个定义,
np.abs(rfft(signal))
会给你带来垃圾(你交替得到fft实部和虚部的绝对值…),你需要一些技巧来得到fft的幅度。为什么不把复数输出为:[y(0),y(1),..,y(n/2)] if n is even
[y(0),y(1),..,y((n-1)/2)] if n is odd
所以一切都会很好地运行(正如人们所期望的那样)?
我错过了什么?
编辑:正在讨论这个问题here
最佳答案
不是一个很好的原因,但一个可能的原因是将独立自由度的数量与变换函数的输入和输出中的变量数量相匹配。如果只从严格实数输入输出复数向量元素,则im(y(0))和im(y(n/2))始终为零(即使n),因此复数函数返回将浪费内存,同时使输出的两个元素分量大于输入,从而不携带任何附加信息,即使自由度应该完全相同。
输入和输出矢量存储器大小的相等还允许在不需要任何额外存储器分配的情况下进行就地RFFT,这在具有相对于FFT大小的受限存储器的实时系统中可能很重要。
而FFTW更典型地运行在大系统上,在大系统中程序员使用它更为普遍(浪费?)大量的内存超过了理论上所需的最小值。