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

| 我有一个以列为主(Fortran风格)格式存储的2D数据数组,我想对每一行进行FFT。我想避免转置数组(它不是正方形)。例如我的数组
fftw_complex* data = new fftw_complex[21*256];
包含条目
[r0_val0, r1_val0,..., r20_val0, r0_val1,...,r20_val255]
。 如果行较大,我可以使用a2ѭ制定计划来解决
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;
}
根据文档(FFTW手册的第4.4.1节),该功能的签名为
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);
并且我应该能够使用
stride
dist
参数设置索引。据我从文档中了解到的,要转换的数组中的条目索引为
in + j*istride + k*idist
,其中
j=0..n-1
k=0..howmany-1
。 (我的数组是一维的,其中有12个)。但是,以下代码将导致一个段。错误(编辑:步幅错误,请参见下面的更新):
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;
}
    
已邀请:
该功能按文档所述工作。我在步幅长度上犯了一个错误,在这种情况下实际上应该是
howmany
。我已经更新了问题以反映这一点。 我发现没有示例,很难理解FFTW的文档(我可能只是不识字...),因此我在下面发布了一个更详细的示例,将
fftw_plan_dft_1d
fftw_plan_many_dft
的通常用法进行了比较。回顾一下,如果将长度为15的12个数组存储在称为22的连续内存块中,则每个变换24的数组元素23分别为
*(in + j*istride + k*idist)
以下两段代码是等效的。在第一个中,显式地完成了从2D数组的转换,在第二个中,使用
fftw_plan_many_dft
调用就地完成了所有操作。 显式复制
int N, howmany;
// ...
fftw_complex* data = (fftw_complex*) fftw_malloc(N*howmany*sizeof(fftw_complex));
// ... load data with howmany arrays of length N 
int istride, idist;
// ... if data is column-major, set istride=howmany, idist=1
//    if data is row-major, set istride=1, idist=N

fftw_complex* in = (fftw_complex*) fftw_malloc(N*sizeof(fftw_complex));
fftw_complex* out = (fftw_complex*) fftw_malloc(N*sizeof(fftw_complex));
fftw_plan p = fftw_plan_dft_1d(N,in,out,FFTW_FORWARD,FFTW_MEASURE);
for (int k = 0; k < howmany; ++k) {
  for (int j = 0; j < N; ++j) {
    in[j] = data[j*istride + k*idist];
  }
  fftw_execute(p);
  // do something with out
}
计划很多
int N, howmany;
// ...
fftw_complex* data = (fftw_complex*) fftw_malloc(N*howmany*sizeof(fftw_complex));
// ... load data with howmany arrays of length N 
int istride, idist;
// ... if data is column-major, set istride=howmany, idist=1
//    if data is row-major, set istride=1, idist=N

fftw_plan p = fftw_plan_many_dft(1,&N,howmany,data,NULL,howmany,1,data,NULL,howmany,1,FFTW_FORWARD,FFTW_MEASURE);
fftw_execute(p);
    

要回复问题请先登录注册