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

FFTW producing different results from numpy.fft

我正在将一些 C++ 代码移植到 Python。 C++ 代码使用 FFTW 库执行 DFT 和 IDFT,而在 Python 中,我暂时选择使用 numpys 实现。

我遇到了一些奇怪的行为。似乎在两种情况下正向变换的计算相同,但逆变换产生不同的结果!

相关的C++代码:

int N = 12;
auto fft_coefficients = new complex<double>[N] {
        5.45, -0.54, 1.81, 1.49, 0.48, 3.98, 0.93, 3.98, 0.48, 1.49, 1.81, -0.54 };
fftw_plan plan_ifft = fftw_plan_dft_1d(
        N, reinterpret_cast<fftw_complex *>(fft_coefficients),
        reinterpret_cast<fftw_complex *>(fft_coefficients), FFTW_BACKWARD,
        FFTW_ESTIMATE);
fftw_execute(plan_ifft);
// Results in
// [20.82, -1.98, 4.55, 1.86, 3.63, 13.68, 1.10, 13.68,, 3.63, 1.86, 4.55, -1.98]

但是,当我 运行 Python 中的相同代码但使用 numpy 时,我得到以下信息:

np.fft.ifft(np.array([5.45, -0.54, 1.81, 1.49, 0.48, 3.98, 0.93, 3.98, 0.48, 1.49,
                      1.81, -0.54], dtype=np.complex64)).real
# array([ 1.73, -0.16,  0.38,  0.15,  0.3 ,  1.14,  0.09,  1.14,  0.3 ,
#         0.15,  0.38, -0.16])

我想我可能需要向 numpy 添加 norm='ortho' 选项来进行单一 IDFT,但这也不会使它们匹配。

我不明白这两个库如何以不同的方式计算逆 DFT,而且不仅仅是一点点,而且结果截然不同。

没关系。我找到了答案。显然,FFTW 通过标准化因子处理标准化与 numpy 不同。如果我将 numpys ifft 乘以 N,我得到与 FFTW 相同的结果。

这引发了另一个问题:它们中的哪一个在正向变换中跳过了归一化?为什么?这似乎是非常不一致的行为。

FFTW claims: "FFTW computes an unnormalized DFT"

也就是说,对于ifft they compute

但是,如上例所述wikipedia, the inverse DFT is defined as

所以 fftw 输出实际上是不正确的,需要缩放。

至少在电气工程界没有规范化标准。 None个是"wrong",你只需要知道每个库在计算什么,然后处理就可以了。