FFTW正逆FFT特定长度(如84)结果错误,切换FFTW_MEASURE恢复正常
FFTW使用FFTW_ESTIMATE标志在特定长度下FFT/IFFT结果异常的原因
问题场景
使用FFTW执行正向FFT后再进行逆向FFT时,当FFT长度为特定值(如84),通过FFTW_ESTIMATE标志创建变换计划会得到错误结果;将标志切换为FFTW_MEASURE后,结果恢复正常。其他长度(如95)下无异常。
代码示例
int main() { const int rows = 84; fftw_complex *in = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * rows); memset(in, 0, sizeof(fftw_complex) * rows); in[0][0] = in[1][0] = in[2][0] = 1.0; fftw_plan plan_fft = fftw_plan_dft_1d(rows, in, in, FFTW_FORWARD, FFTW_ESTIMATE); fftw_plan plan_ifft = fftw_plan_dft_1d(rows, in, in, FFTW_BACKWARD, FFTW_ESTIMATE); fftw_execute(plan_fft); fftw_execute(plan_ifft); for (int i = 0; i < rows; ++i) { std::cout << in[i][0] / rows << " "; } std::cout << std::endl; return 0; }
预期与实际结果
预期结果
1 1 1 0 0 0 0 ... 0 0
实际错误结果
1 0.999068 0.996277 0.991643 1.65826e-17 -1.22373e-17 -3.68811e-17 -1.88926e-17 -9.12265e-18 3.45078e-17 2.30831e-17 4.92708e-17 4.17271e-17 2.61058e-17 1.60247e-17 -0.0100873 -0.0187201 -0.0258501 -1.0593e-17 -2.53148e-17 2.5538e-17 2.24688e-17 1.60449e-17 3.79879e-17 1.26333e-17 2.47918e-17 3.51694e-17 -4.52437e-18 -4.57848e-18 0.0105533 0.0205816 0.0300288 3.14536e-18 -1.80787e-17 9.25439e-18 1.71057e-18 6.38559e-18 2.79698e-17 -2.29849e-17 5.09812e-18 1.19693e-17 6.06313e-19 0 -8.45884e-17 8.45884e-17 0 -2.5447e-18 -1.02155e-17 3.16047e-17 2.33067e-17 1.64392e-17 2.23584e-17 -3.89767e-18 1.83711e-17 1.46201e-17 -7.95307e-18 4.57848e-18 -0.0110194 -0.0224432 -0.0342075 -6.40249e-18 -2.12686e-17 3.15629e-17 9.25186e-18 1.97198e-17 6.53782e-18 -2.50131e-18 -5.43689e-17 6.60354e-18 1.12718e-17 -1.60247e-17 0.0114854 0.0243047 0.0383862 -2.99259e-17 5.53942e-17 1.82227e-17 2.5596e-17 -1.88591e-18 -3.41998e-17 -4.34999e-18 -4.31629e-17 -4.66482e-17 -2.55064e-17
原因分析
FFTW中FFTW_ESTIMATE与FFTW_MEASURE的核心区别在于计划生成逻辑:
FFTW_ESTIMATE:仅通过启发式规则快速生成计划,不会实际运行FFT算法测试。它依赖长度分解的经验选择算法,对于84这类可分解为2²×3×7的复合长度,启发式选择的算法组合可能存在精度缺陷,或是在in-place变换场景下的临时内存处理出现偏差,导致正向+逆向FFT后结果失真。FFTW_MEASURE:会实际运行多种FFT算法实现,通过测量性能和验证正确性选择最优计划。对于84这类容易触发启发式错误的长度,它会自动避开问题算法,选择稳定可靠的实现,因此结果恢复正常。
而95这类长度(分解为5×19)的算法选择逻辑在FFTW启发式规则中已充分验证,所以无论用哪种标志都能得到正确结果。
内容的提问来源于stack exchange,提问作者hjzhao
相关产品推荐
相关产品推荐

