FFTW - 计算真实的2D FFT,特殊要求

tir*_*r38 5 c++ fft fftw

我正在使用FFTW3来计算c ++中的2D实数FFT.我已阅读手册但有一些问题.来自手册:http://www.fftw.org/fftw3_doc/One_002dDimensional-DFTs-of-Real-Data.html#One_002dDimensional-DFTs-of-Real-Data

为了换取这些速度和空间优势,用户牺牲了FFTW复杂变换的一些简单性.首先,输入和输出数组具有不同的大小和类型:输入是n个实数,而输出是n/2 + 1个复数(非冗余输出); 这也需要对输入阵列进行轻微的"填充"以进行就地变换.其次,默认情况下,逆变换(复数到实数)具有覆盖其输入数组的副作用.这些不便都不会给用户带来严重问题,但重要的是要了解它们.

  1. 我知道我需要将输入的2D矩阵转换为行级1D向量.但是输出是什么样的?n/2 + 1数字是什么意思?换句话说,如何重新排序输出以获得2D矩阵?

  2. 具体来说,我需要做些什么来创建这个"填充"?

Car*_*rum 2

  1. 如果您的输入已经在普通的 C++ 2D 数组中,您需要做的就是对其进行类型转换:

    double twoDarray[10][10];
    double *oneDarrayPointer = (double *)twoDarray;
    
    Run Code Online (Sandbox Code Playgroud)

    如果您的输入是 100(如上面的示例所示),您的输出数组将是 51 个复数。这些数字的格式应由您的图书馆描述,但可能是 102 doubles- 51 个条目乘以 2(实部/虚部)的数组。

    编辑:已确认 -fftw_complex定义为:

    typedef double fftw_complex[2];
    
    Run Code Online (Sandbox Code Playgroud)

    所以它们只是doubles代表复数的实部和虚部的连续对。

  2. 如果您不想就地执行此操作,则不必填充任何内容 - 只需分配适当大小的输出数组即可。如果您确实需要就地执行此操作,则您的输入缓冲区必须有空间容纳 2 个额外的双精度数与输入大小。假设上面的声明,你会想要类似的东西:

    double *inPlaceFFTPointer = malloc(sizeof twoDarray + 2*sizeof(double));
    memcpy(inPlaceFFTPointer, oneDarrayPointer, sizeof twoDarray);
    
    Run Code Online (Sandbox Code Playgroud)

    我不确定您是否需要确保0.0在最后两个条目中包含,但这很容易添加。

  • 来自您帖子中的链接:“在许多实际应用中,输入数据 in[i] 是纯实数,在这种情况下,DFT 输出满足“厄米”冗余:“out[i]”是“out”的共轭[ni]`。” 因此,如果您愿意,您只需要一半的输出即可生成所有输出。 (2认同)