使用FFTW在2D矩阵上执行N个独立的1D FFT

时间:2016-02-21 17:45:51

标签: fftw

我有一个二维矩阵,每列对应一个独立信号。我将在每列上执行N 1D fft。在matlab中,将fft应用于2D矩阵就可以了。但是我用fftw将代码移植到c ++。我想知道是否有办法这样做。我通过将列大小设置为1并将行大小设置为4(总行数)来尝试以下代码,但它没有帮助。

#include <iostream>
#include <complex>
#include "fftw3.h"

using namespace std;

int main(int argc, char** argv)
{
  complex<double> data[4][2];
  data[0][0] = complex<double>(1,1);
  data[1][0] = complex<double>(2,1);
  data[2][0] = complex<double>(3,1);
  data[3][0] = complex<double>(4,1);

  data[0][1] = complex<double>(1,1);
  data[1][1] = complex<double>(1,2);
  data[2][1] = complex<double>(1,3);
  data[3][1] = complex<double>(1,4);

  cout << "original data ..." << endl;
  cout << data[0][0] << '\t' << data[0][1] << endl;
  cout << data[1][0] << '\t' << data[1][1] << endl;
  cout << data[2][0] << '\t' << data[2][1] << endl;
  cout << data[3][0] << '\t' << data[3][1] << endl;
  cout << endl << endl;

  fftw_plan plan=fftw_plan_dft_2d(4, 1,(fftw_complex*)&data[0][0], (fftw_complex*)&data[0][0], FFTW_FORWARD, FFTW_ESTIMATE);
  fftw_execute(plan);
  cout << "after fftw ..." << endl;
  cout << data[0][0] << '\t' << data[0][1] << endl;
  cout << data[1][0] << '\t' << data[1][1] << endl;
  cout << data[2][0] << '\t' << data[2][1] << endl;
  cout << data[3][0] << '\t' << data[3][1] << endl;
  return 0;
}

上面的代码取第一行和第二行并将它们重新整形为2x2矩阵然后执行2D fft。

到目前为止,我想到的唯一方法如下。假设我有NxM(N行,M列),我为M 1D fftw创建M fftw计划。我连续执行M fftw以获得结果。但在实际应用中,矩阵非常大,M是如此之大。这样做是非常低效的。有什么好主意吗?感谢。

1 个答案:

答案 0 :(得分:1)

对于现在遇到这个问题的人来说,FFTW 开发人员已经为这个操作实现了例程,这比循环遍历每一列并进行单独的转换要快。您当然不想进行 2D 变换(如问题所示),这在数学上与逐行 1D 变换不同。

您问题的关键在于fftw_plan_many_dftHere is a link to the full documentation.

这是一个示例(从上面的链接修改),说明了您正在寻找的内容。

#include "fftw3.h"

int main() {

    fftw_complex *A; // array of data
    A = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*10*3);
    
    // ...
    
    /* Transform each column of a 2d array with 10 rows and 3 columns */
    int rank = 1; /* not 2: we are computing 1d transforms */
    int n[] = {10}; /* 1d transforms of length 10 */
    int howmany = 3;
    int idist = 1;
    int odist = 1;
    /* distance between two elements in the same column */
    int istride = 3;
    int ostride = 3;
    
    int *inembed = n, *onembed = n;
    
    /* forward, in-place, 1D transform of each column */
    fftw_plan p;
    p = fftw_plan_many_dft(rank, n, howmany, A, inembed, istride, idist, A, onembed, ostride, odist, FFTW_FORWARD, FFTW_ESTIMATE);

    
    // ...
    
    /* run transform */
    fftw_execute_dft(p, A, A);
    
    
    // ...
    
    /* we don't want memory leaks */
    fftw_destroy_plan(p);
    fftw_free(A);

}