简体   繁体   English

使用FFTW_MEASURE时,FFT输出为空白,但FFTW_ESTIMATE可以正常工作

[英]FFT output is blank when using FFTW_MEASURE, but works fine with FFTW_ESTIMATE

I'm having the following issue in my attempt to use fftw3. 我试图使用fftw3时遇到以下问题。 For some reason, whenever I do an FFT using FFTW_MEASURE instead of FFTW_ESTIMATE, I get blank output. 出于某种原因,每当我使用FFTW_MEASURE而不是FFTW_ESTIMATE进行FFT时,我得到空白输出。 Ultimately I'm trying to implement fft convolution, so my example below includes both the FFT and the inverse FFT. 最终我正在尝试实现fft卷积,所以下面的例子包括FFT和逆FFT。

Clearly I'm missing something... is anyone able to educate me? 很明显我错过了什么......是否有人能够教育我? Thank you! 谢谢!

I'm on Linux (OpenSUSE Leap 42.1), using the version of fftw3 available from my package manager. 我在Linux(OpenSUSE Leap 42.1)上,使用我的包管理器提供的fftw3版本。

Minimum working example: 最低工作示例:

#include <iostream>
#include <iomanip>
#include <cmath>
#include <fftw3.h>
using namespace std;


int main(int argc, char ** argv)
{
    int width = 10;    
    int height = 8;

    cout.setf(ios::fixed|ios::showpoint);
    cout << setprecision(2);

    double * inp = (double *) fftw_malloc(sizeof(double) * width * height);
    fftw_complex * cplx = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * height * (width/2 + 1));

    for(int i = 0; i < width * height; i++) inp[i] = sin(i);

    fftw_plan fft = fftw_plan_dft_r2c_2d(height, width, inp, cplx,  FFTW_MEASURE );
    fftw_plan ifft = fftw_plan_dft_c2r_2d(height, width, cplx, inp,  FFTW_MEASURE );

    fftw_execute(fft);

    for(int j = 0; j < height; j++)
    {
        for(int i = 0; i < (width/2 + 1); i++)
        {
            cout << cplx[i+width*j][0] << " ";
        }
        cout << endl;
    }
    cout << endl << endl;

    fftw_execute(ifft);

    for(int j = 0; j < height; j++)
    {
        for(int i = 0; i < width; i++)
        {
            cout << inp[i+width*j] << " ";
        }
        cout << endl;
    }

    fftw_destroy_plan(fft);
    fftw_destroy_plan(ifft);
    fftw_free(cplx);
    fftw_free(inp);

    return 0;
}

Just change between FFTW_ESTIMATE and FFTW_MEASURE. 只需在FFTW_ESTIMATE和FFTW_MEASURE之间切换。

Compiled with: 编译:

g++ *.cpp -lm -lfftw3 --std=c++11

Output with FFTW_ESTIMATE (first block is the real part of the FT, second block is after inverse FT): 使用FFTW_ESTIMATE输出(第一个块是FT的实部,第二个块是反FT后):

1.51 2.24 -1.52 -0.05 0.15 0.19 
0.23 0.15 1.77 1.19 0.54 0.41 
1.97 -0.15 -1.32 -2.51 -1.20 -3.38 
4.34 15.21 -24.82 -7.44 -4.16 -2.51 
-0.43 -0.06 1.55 2.93 -2.81 -0.42 
0.00 0.00 0.00 -nan 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 -nan 
0.00 0.00 0.00 0.00 0.00 0.00 


0.00 67.32 72.74 11.29 -60.54 -76.71 -22.35 52.56 79.15 32.97 
-43.52 -80.00 -42.93 33.61 79.25 52.02 -23.03 -76.91 -60.08 11.99 
73.04 66.93 -0.71 -67.70 -72.45 -10.59 61.00 76.51 21.67 -53.09 
-79.04 -32.32 44.11 79.99 42.33 -34.25 -79.34 -51.48 23.71 77.10 
59.61 -12.69 -73.32 -66.54 1.42 68.07 72.14 9.89 -61.46 -76.30 
-20.99 53.62 78.93 31.67 -44.70 -79.98 -41.72 34.89 79.43 50.94 
-24.38 -77.29 -59.13 13.39 73.60 66.15 -2.12 -68.44 -71.83 -9.18 
61.91 76.08 20.31 -54.14 -78.81 -31.02 45.29 79.96 41.12 -35.53

Output with FFTW_MEASURE (first block is the real part of the FT, second block is after inverse FT): 使用FFTW_MEASURE输出(第一个块是FT的实部,第二个块是反FT后):

0.00 0.00 0.00 0.00 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 0.00 
0.00 0.00 0.00 -nan 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 -nan 
0.00 0.00 0.00 0.00 0.00 0.00 


0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

The comment of @Paul_R. @Paul_R的评论。 is sufficient to solve the problem. 足以解决问题。 The input array can be modified as fftw_plan_dft_r2c_2d() is called. 可以在调用fftw_plan_dft_r2c_2d()修改输入数组。 Hence, the input array must be initialized after the creation of the fftw plan. 因此,必须在创建fftw计划初始化输入数组。

The documentation of the planner flags of FFTW details what is happening. FFTW的规划器标志文档详细说明了正在发生的事情。 I am pretty sure that you have already guessed the reason why FFTW_ESTIMATE preserve the input array and FTTW_MEASURE modifies it. 我很确定你已经猜到了FFTW_ESTIMATE保留输入数组并且FTTW_MEASURE修改它的原因。

Important: the planner overwrites the input array during planning unless a saved plan (see Wisdom) is available for that problem, so you should initialize your input data after creating the plan.*** The only exceptions to this are the FFTW_ESTIMATE and FFTW_WISDOM_ONLY flags, as mentioned below. 重要提示:计划程序在计划期间会覆盖输入数组,除非保存的计划(请参阅Wisdom)可用于该问题,因此您应该在创建计划后初始化输入数据。***唯一的例外是FFTW_ESTIMATE和FFTW_WISDOM_ONLY标志,如下所述。

... ...

  • FFTW_ESTIMATE specifies that, instead of actual measurements of different algorithms, a simple heuristic is used to pick a (probably sub-optimal) plan quickly. FFTW_ESTIMATE指定使用简单的启发式算法来代替不同算法的实际测量,以快速选择(可能是次优的)计划。 With this flag, the input/output arrays are not overwritten during planning. 使用此标志,在计划期间不会覆盖输入/输出数组。
  • FFTW_MEASURE tells FFTW to find an optimized plan by actually computing several FFTs and measuring their execution time. FFTW_MEASURE告诉FFTW通过实际计算几个FFT并测量它们的执行时间来找到优化的计划。 Depending on your machine, this can take some time (often a few seconds). 根据您的机器,这可能需要一些时间(通常是几秒钟)。 FFTW_MEASURE is the default planning option. FFTW_MEASURE是默认计划选项。

... ...

The documentation also tells us that the flag FFTW_ESTIMATE will preserve the input. 文档还告诉我们,标志FFTW_ESTIMATE将保留输入。 Yet, the best advise is to initialize the array once the plan is created. 然而,最好的建议是在创建计划后初始化阵列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM