5

我正在使用 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 个数字是什么意思?换句话说,我如何重新排序输出以获得二维矩阵?

  2. 我具体要做什么来创建这个“填充”?

4

2 回答 2

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

    double twoDarray[10][10];
    double *oneDarrayPointer = (double *)twoDarray;
    

    如果你的输入是 100(就像上面的例子一样),你的输出数组将是 51 个复数。这些数字的格式应由您的库描述,但可能是 102 doubles- 51 个条目乘以 2(实部/虚部)的数组。

    编辑:确认 -fftw_complex定义为:

    typedef double fftw_complex[2];
    

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

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

    double *inPlaceFFTPointer = malloc(sizeof twoDarray + 2*sizeof(double));
    memcpy(inPlaceFFTPointer, oneDarrayPointer, sizeof twoDarray);
    

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

于 2013-01-28T23:31:26.517 回答
2

你可以看看 FFTW3 中的真实到真实的转换,这正是你所要求的。这些不需要填充,并考虑到波数 0 和代表奈奎斯特频率的波数都只有一个实分量。看看这里:

FFTW3 实到实转换

对于内存中的布局:

FFTW3 实到实转换种类

于 2013-10-17T07:46:41.227 回答