FFTW 从 numpy.fft 产生不同的结果
Posted
技术标签:
【中文标题】FFTW 从 numpy.fft 产生不同的结果【英文标题】:FFTW producing different results from numpy.fft 【发布时间】:2018-05-03 18:05:13 【问题描述】:我正在将一些 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])
我认为我可能需要将 norm='ortho'
选项添加到 numpy 以执行单一 IDFT,但这也不能使它们匹配。
我不明白这两个库如何以不同的方式计算逆 DFT,而不仅仅是一点点,完全不同的结果。
【问题讨论】:
【参考方案1】:FFTW claims: "FFTW 计算一个未归一化的 DFT"
也就是说,对于 ifft they compute
但是,如 wikipedia 中所述,逆 DFT 定义为
所以fftw的输出其实是不正确的,需要缩放。
【讨论】:
【参考方案2】:至少在电气工程界没有标准化的标准。这些都不是“错误的”,你只需要知道每个库在计算什么并处理它。
【讨论】:
任何地方都没有标准规范化。每个字段都以不同的方式定义 DFT 中的归一化。了解您的图书馆如何规范化至关重要。【参考方案3】:没关系。我找到了答案。显然,FFTW 通过归一化因子处理与 numpy 不同的归一化。如果我将 numpys ifft
乘以 N
,我会得到与 FFTW 相同的结果。
这引发了另一个问题:其中哪一个跳过了正向变换中的归一化?为什么?这似乎是非常不一致的行为。
【讨论】:
不是不一致的,每个库中应用的规范化每次都是一样的。查看文档以了解每个工具的工作原理。 DFT 没有单一的定义。见this section的最后一段。以上是关于FFTW 从 numpy.fft 产生不同的结果的主要内容,如果未能解决你的问题,请参考以下文章
如何消除由于 scipy/numpy fft 中的零填充而产生的边界效应?