我正在测试FFTW 3.3.8 C库,以进行一维离散傅里叶变换(DFT)计算。当我使用库的float
(单精度)版本并配置了--enable-generic-simd128
或--enable-generic-simd256
选项(并为--enable-float
支持时选择float
)时,得到的结果通常是不正确的。我已经在MinGW-w64以及用于Linux的Windows子系统中进行了测试,并以gcc作为编译器。当我对MinGW-w64使用预构建的FFTW软件包(通过MSYS2中的pacman下载)时,也会遇到相同的错误。
作为一个简单的测试,我使用的输入向量为1。期望DFT的第一个元素应等于输入向量的长度,其他所有元素均为零。
以前有人遇到过这个问题吗,还是有人愿意尝试复制它?我是否要使用库的--enable-generic-simd128
版本不支持--enable-generic-simd256
和float
优化?我的CPU是Intel i7-4720HQ。
这里是一个简单的测试程序来演示该问题:
main.c
#include <stdio.h>
#include <fftw3.h>
int main()
{
fftwf_complex *in, *out;
fftwf_plan p;
int N = 21;
int i;
in = fftwf_malloc(sizeof(fftwf_complex) * N);
out = fftwf_malloc(sizeof(fftwf_complex) * N);
p = fftwf_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
for (i = 0; i < N; i++) {
in[i][0] = 1.0f;
in[i][1] = 0.0f;
}
fftwf_execute(p);
for (i = 0; i < N; i++)
printf("%d: %8.5g\t + j %8.5g\n", i, out[i][0], out[i][1]);
fftwf_destroy_plan(p);
fftwf_free(in);
fftwf_free(out);
}
我用gcc -o main main.c -lfftw3f -lm
构建它。输出如下:
0: 21 + j -7.87
1: 0 + j 0
2: 0 + j 0
3: -5.2972 + j 1.9
4: 0 + j 0
5: 0 + j 0
6: -1.862 + j 1.08
7: 0 + j 0
8: 0 + j 0
9: -0.52584 + j 0.956
10: 0 + j 0
11: 0 + j 0
12: 0.52584 + j 0.956
13: 0 + j 0
14: 0 + j 0
15: 1.862 + j 1.08
16: 0 + j 0
17: 0 + j 0
18: 5.2972 + j 1.9
19: 0 + j 0
20: 0 + j 0
这似乎是FFTW 3.3.8中的错误。
[我在装有macOS 10.14.6,Clang 11.0.0和Xcode 11.3.1的2016年15英寸MacBook Pro上使用--enable-float
构建了FFTW 3.3.8,并构建并执行了问题中的代码。对于元素0,它显示的输出为21,对于其他元素,它的输出值接近0(例如“ 6.6324e-07 + j -2.0458e-07”)。在添加--enable-generic-simd128
的情况下重建FFTW之后,程序给出了问题中显示的输出。
这确实是FFTW 3.3.8中的错误。我在多个平台上重现了该问题,包括埃里克·波斯特皮斯希尔(Eric Postpischil)在内的许多人证实了这一问题。我将此问题报告给FFTW开发人员,并已在recent commit中修复。