【问题标题】:FFT output is blank when using FFTW_MEASURE, but works fine with FFTW_ESTIMATE使用 FFTW_MEASURE 时 FFT 输出为空白,但使用 FFTW_ESTIMATE 可以正常工作
【发布时间】:2015-12-11 17:55:20
【问题描述】:

我在尝试使用 fftw3 时遇到以下问题。出于某种原因,每当我使用 FFTW_MEASURE 而不是 FFTW_ESTIMATE 进行 FFT 时,我都会得到空白输出。最终我正在尝试实现 fft 卷积,所以下面的示例包括 FFT 和逆 FFT。

显然我错过了一些东西......有人可以教育我吗?谢谢!

我在 Linux (OpenSUSE Leap 42.1) 上,使用我的包管理器提供的 fftw3 版本。

最小工作示例:

#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;
}

只需在 FFTW_ESTIMATE 和 FFTW_MEASURE 之间切换即可。

编译:

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

使用 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

使用 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

【问题讨论】:

标签: c++ fftw


【解决方案1】:

@Paul_R 的评论。足以解决问题。输入数组可以修改为fftw_plan_dft_r2c_2d() 被调用。因此,输入数组必须在 创建 fftw 计划之后进行初始化。

documentation of the planner flags of FFTW 详细说明了正在发生的事情。我很确定您已经猜到了FFTW_ESTIMATE 保留输入数组而FTTW_MEASURE 修改它的原因。

重要提示:计划者在计划期间会覆盖输入数组,除非已保存计划(请参阅 Wisdom)可用于该问题,因此您应该在创建计划后初始化输入数据。*** 唯一的例外是 FFTW_ESTIMATE和 FFTW_WISDOM_ONLY 标志,如下所述。

...

  • FFTW_ESTIMATE 指定,不是对不同算法的实际测量,而是使用简单的启发式方法来快速选择一个(可能是次优的)计划。 使用此标志,输入/输出数组在规划期间不会被覆盖。
  • FFTW_MEASURE 告诉 FFTW 通过实际计算多个 FFT 并测量它们的执行时间来找到优化的计划。根据您的机器,这可能需要一些时间(通常是几秒钟)。 FFTW_MEASURE 是默认计划选项。

...

文档还告诉我们标志FFTW_ESTIMATE 将保留输入。然而,最好的建议是在创建计划后初始化数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    • 2014-06-27
    • 1970-01-01
    • 2023-03-18
    • 2023-04-07
    • 2014-07-06
    相关资源
    最近更新 更多