FFTW 反向变换乘以 N
Posted
技术标签:
【中文标题】FFTW 反向变换乘以 N【英文标题】:FFTW backwards transform is multiplied by N 【发布时间】:2020-07-13 17:21:58 【问题描述】:基本上,CPP_FFTW(N, signal, backwards) = NP_IFFT(N, signal) * N
其中CPP_FFTW
是 C++ 中 FFTW 库的(浮动版本),NP_IFFT
是 Python 中的 numpy.fft.ifft
。
这里的问题是CPP_FFTW(N, CPP_FFTW(N, signal, forwards), backwards)
等于N * signal
,而不是人们可能期望的signal
。
我可以除以N
,但我的问题是我的N
非常大,所以我失去了浮点精度。它基本上破坏了我的程序;我在 C++ 和 Python 应用程序中有几乎相同的复数系数。但是,我失去了所有的精确度,因为我在执行反向变换后基本上使用了(c*N)/N
。
是否有可能阻止这种乘法的发生?
直到IFFT
,系数几乎相同。这是IFFT之后的:
Python CPP
【问题讨论】:
你确定是这个问题吗? fp 乘法即使乘以非常大的数也不会对相对精度产生很大影响。 @PaulPanzer 我不明白为什么结果首先会相乘?我在文档中没有找到任何内容 从技术上讲,它不会成倍增加。它只是没有标准化。如何规范化 FFT/IFFT 是一个因实现而异的约定问题。 @PaulPanzerCPP_FFTW(N, CPP_FFTW(N, signal, forwards), backwards)
应该等于 signal
是否有标准化。除非,两个方向之间的规范化不一致?
在规范化之后,我的浮点精度从 ~6 变为只有 3。然而,numpy 以某种方式能够保持正常的精度 - 诚然它的速度较慢
【参考方案1】:
正如您在the documentation 中看到的,FFTW 计算一个非标准化 变换。也就是说,需要额外除以信号的长度,才能在前向和逆变换后恢复输入信号:IFFT(FFT(signal))/N = signal
。
Python NumPy FFT 是标准化的,它包括在逆变换中除以N
。
请注意,这种额外的除法不会改变您的相对精度,因为信号中的所有值都除以完全相同的数字。
附加信息:
一些库(例如 FFTW)计算非归一化 FFT,在逆变换中跳过除以 N
以提高速度,因为有时它可能没有必要。其他库完全定义了不同的归一化,例如,它们可能在正向变换而不是逆向变换中除以 N
,或者在正向和反向变换中它们可能除以 N
的平方根。
【讨论】:
@orlp:你能举一个不正确的例子吗? 我也不明白这一点。增加足够大的值将导致浮点精度降低 - 所有值都乘以相同的数字有什么关系?precision(complex) >= precision((complex*N) / N)
的精度。但是,如果您说的是真的,那么在这种情况下这并不重要,因为在这两个应用程序中,/ N
正在发生(并且没有* N
)。
@TobiAkinyemi:相对精度是数字除以该数字的误差。 1e2 +- 1e-2
与 1e12 +- 1e8
或 1e-8 +- 1e-12
的精度级别相同。您正在考虑绝对精度。以上是关于FFTW 反向变换乘以 N的主要内容,如果未能解决你的问题,请参考以下文章