C 如何在转置的数据数组上使用fftw\u plan\u many\u dft?
我有一个以column major(Fortran风格)格式存储的2D数据数组,我想对每一行进行FFT。我希望避免转置数组(它不是正方形)。例如,我的数组C 如何在转置的数据数组上使用fftw\u plan\u many\u dft?,c,fftw,C,Fftw,我有一个以column major(Fortran风格)格式存储的2D数据数组,我想对每一行进行FFT。我希望避免转置数组(它不是正方形)。例如,我的数组 fftw_complex* data = new fftw_complex[21*256]; 包含条目[r0_val0,r1_val0,…,r20_val0,r0_val1,…,r20_val255] 我可以使用fftw\u plan\u many\u dft来制定计划,以解决数据数组中的21个fft中的每一个,如果它是行主数组,例如[r0
fftw_complex* data = new fftw_complex[21*256];
包含条目[r0_val0,r1_val0,…,r20_val0,r0_val1,…,r20_val255]
我可以使用fftw\u plan\u many\u dft
来制定计划,以解决数据
数组中的21个fft中的每一个,如果它是行主数组,例如[r0\u val0,r0\u val1,…,r0\u val255,r1\u val0,…,r20\u 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_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
。(我的数组是1D,有多少个)。但是,以下代码会导致seg。错误(编辑:步幅错误,请参阅下面的更新):
更新:
我在选择步幅时出错了。正确的呼叫是(正确的步幅是howmany
,而不是N
):
该函数的工作方式如文档所示。我在步幅上犯了一个错误,在本例中,它实际上应该是
howmany
。我已更新问题以反映这一点
我发现如果没有示例,FFTW的文档有点难以理解(我可能只是文盲……),因此我在下面发布了一个更详细的示例,比较了FFTW\u plan\u dft\u 1d
与FFTW\u plan\u many\u dft
的常用用法。综上所述,在存储在中被称为的连续内存块中的长度为N
的数组的数量的情况下,每个变换k
的数组元素j
*(in + j*istride + k*idist)
以下两段代码是等效的。在第一种方法中,从某个2D数组显式地进行转换,而在第二种方法中,使用fftw\u plan\u many\u dft
调用来执行所有操作
显式复制
int N,有多少个;
// ...
fftw_complex*数据=(fftw_complex*)fftw_malloc(N*多少个*sizeof(fftw_complex));
// ... 加载长度为N的数组数为多少的数据
int istride,idist;
// ... 如果数据为列主数据,则设置istride=howmany,idist=1
//如果数据为行主数据,则设置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_平面p=fftw_平面dft_1d(N,in,out,fftw_正向,fftw_度量);
对于(int k=0;k<多少;++k){
对于(int j=0;j
计划很多
int N,有多少个;
// ...
fftw_complex*数据=(fftw_complex*)fftw_malloc(N*多少个*sizeof(fftw_complex));
// ... 加载长度为N的数组数为多少的数据
int istride,idist;
// ... 如果数据为列主数据,则设置istride=howmany,idist=1
//如果数据为行主数据,则设置istride=1,idist=N
fftw_plan p=fftw_plan_many_dft(1,&N,数量,数据,NULL,数量,1,数据,NULL,数量,1,fftw_FORWARD,fftw_MEASURE);
fftw_执行(p);
我不确定这是否正确@Dylan。如果在
中更改数据数组,则必须使用新的输入数组再次运行fftw\u plan\u dft\u 1d
。虽然我不能确定它是否会给你一个书面错误,但我可以告诉你,文档明确警告你不要这样做(pdf手册第4页至3.2.2版)。@kalu我想你可能误解了手册。您是指以“如果要变换相同大小的不同数组”开头的句子吗?这是指使用不同的数组,而不是更改现有数组的内容。
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;
}
*(in + j*istride + k*idist)