在使用FFTW时,我只对FFT进行了正向FFT,然后对array进行了逆FFT,但是当FFT的length
具有特定值时,例如length==84
,我得到了错误的结果。
代码示例:
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;
}
如上面代码所示,wanted result为:
但实际结果为:
当我将FFT的标志值从FFTW_ESTIMATE
更改为FFTW_MEASURE
时,结果正确。
为什么会发生这种情况?我已经困惑了很长一段时间,有人能帮助我吗?
只有当FFT length
的值为例如84
时,才会产生这样的误差,而其他值又是正常的,例如95
。
1条答案
按热度按时间7d7tgy0s1#
它使用浮点数学,所以它不太可能精确地给予
0
或1
,而是一些非常接近的值。你也可以尝试其他的planner flags:
FFTW_ESTIMATE
规定,不是使用不同算法的实际测量,而是使用简单的启发式来快速选择(可能是次优的)计划。有了这个标志,输入/输出阵列在计划期间不会被覆盖。FFTW_MEASURE
告诉FFTW通过实际计算几个FFT并测量它们的执行时间来找到优化的计划。根据您的计算机,这可能需要一些时间(通常为几秒钟)。FFTW_MEASURE
是默认计划选项。FFTW_PATIENT
类似于FFTW_MEASURE
,但考虑了更广泛的算法,并且通常会产生“更优化”的计划(特别是对于大型变换),但代价是规划时间延长了几倍(特别是对于大型变换)。FFTW_EXHAUSTIVE
类似于FFTW_PATIENT
,但考虑了更广泛的算法,包括许多我们认为不太可能快速的算法,以产生最优的计划,但大大增加了规划时间。FFTW_WISDOM_ONLY
是一种特殊的计划模式,在这种模式下,只有在对给定问题有智慧时才创建计划,否则返回NULL计划。这可以与其他标志组合,例如FFTW_WISDOM_ONLY | FFTW_PATIENT
仅当在FFTW_PATIENT
或FFTW_EXHAUSTIVE
模式下创建的智慧可用时才创建计划。FFTW_WISDOM_ONLY
标志用于需要检测智慧是否可用的用户;例如,如果智能不可用,则可能希望分配新的阵列用于规划,使得用户数据不被重写。您还可以使用
std::fixed
来更容易地看到结果更接近您想要的结果。此外,由于您使用的是C++,因此使用
std::vector<std::complex<double>>
作为容器,而不是fftw_malloc
,并且仅在与FFTW库交互时转换为fftw_complex
。这样就不必手动释放分配的内存-或者像当前程序那样发生内存泄漏。重写为使用C++容器、不同的规划器标志和
std::fixed
: