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 是一个因实现而异的约定问题。 @PaulPanzer CPP_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-21e12 +- 1e81e-8 +- 1e-12 的精度级别相同。您正在考虑绝对精度。

以上是关于FFTW 反向变换乘以 N的主要内容,如果未能解决你的问题,请参考以下文章

求教matlab FFt变换 几个问题

clarke变换为啥要乘以2/3

FFTW 从 numpy.fft 产生不同的结果

2D R2C FFT 作为 1D FFT 使用 FFTW

2969 角谷猜想

fft 算法的基准测试方法