如何在转置的数据数组上使用fftw_plan_many_dft?

时间:2011-05-16 18:31:49

标签: c fftw

我有一个以列主要(Fortran风格)格式存储的2D数据数组,我想对每个进行FFT。我想避免转置数组(它不是正方形)。例如,我的数组

fftw_complex* data = new fftw_complex[21*256];

包含条目[r0_val0, r1_val0,..., r20_val0, r0_val1,...,r20_val255]

我可以使用fftw_plan_many_dft制定一个计划来解决data数组中的21个FFT中的每一个,如果它是 - 主要的,例如[r0_val0, r0_val1,..., r0_val255, r1_val0,...,r20_val255]

int main() {
  int N = 256;
  int howmany = 21;
  fftw_complex* data = new fftw_complex[N*howmany];
  fftw_plan p;

  // this plan is OK
  p = fftw_plan_many_dft(1,&N,howmany,data,NULL,1,N,data,NULL,1,N,FFTW_FORWARD,FFTW_MEASURE);
  // do stuff...

  return 0;
}

根据文档(section 4.4.1 of the FFTW manual),该函数的签名是

fftw_plan fftw_plan_many_dft(int rank, const int *n, int howmany,
                              fftw_complex *in, const int *inembed,
                              int istride, int idist,
                              fftw_complex *out, const int *onembed,
                              int ostride, int odist,
                              int sign, unsigned flags);

我应该可以使用stridedist参数来设置索引。根据我从文档中可以理解的内容,要转换的数组中的条目被编入索引in + j*istride + k*idist,其中j=0..n-1k=0..howmany-1。 (我的数组是1D,其中有howmany个。但是,以下代码会产生seg。错误(编辑:步幅长度错误,请参阅下面的更新):

int main() {
  int N = 256;
  int howmany = 21;
  fftw_complex* data = new fftw_complex[N*howmany];
  fftw_plan p;

  // this call results in a seg. fault.
  p = fftw_plan_many_dft(1,&N,howmany,data,NULL,N,1,data,NULL,N,1,FFTW_FORWARD,FFTW_MEASURE);

  return 0;
}

更新

选择步幅时我犯了一个错误。正确的呼叫是(正确的步幅为howmany,而不是N):

int main() {
  int N = 256;
  int howmany = 21;
  fftw_complex* data = new fftw_complex[N*howmany];
  fftw_plan p;

  // OK
  p = fftw_plan_many_dft(1,&N,howmany,data,NULL,howmany,1,data,NULL,howmany,1,FFTW_FORWARD,FFTW_MEASURE);
  // do stuff  

  return 0;
}

1 个答案:

答案 0 :(得分:7)

该功能按照记录的方式工作。我用步幅长度做了一个错误,在这种情况下实际应该是howmany。我已更新问题以反映这一点。

我发现FFTW的文档在没有示例的情况下有点难以理解(我可能只是文盲......),所以我在下面发布一个更详细的例子,比较fftw_plan_dft_1dfftw_plan_many_dft的通常用法{1}}。回顾一下,对于长度为howmany的{​​{1}}数组,这些数组存储在引用为N的连续内存块中,每个转换的数组元素in {{ 1}}是

j

以下两段代码是等效的。在第一个中,从一些2D数组的转换是明确完成的,在第二个中,k调用用于完成所有内容。

明确复制

*(in + j*istride + k*idist)

计划许多

fftw_plan_many_dft