FFTW高级布局 – inembed = n和inembed = NULL给出不同的结果?

我正在使用FFTW高级数据布局API处理批量2D FFT。

根据FFTW高级复杂DFT文档:

为nembed参数传递NULL等同于传递n

但是,当使用inembed = onembed = NULL而不是inembed = onembed = n时,我会得到不同的结果。 什么可能导致结果不匹配?


我们举个例子……

建立

 int howMany = 2; int nRows = 4; int nCols = 4; int n[2] = {nRows, nCols}; float* h_in = (float*)malloc(sizeof(float) * nRows*nCols*howMany); for(int i=0; i<(nRows*nCols*howMany); i++){ //initialize h_in to [0 1 2 3 4 ...] h_in[i] = (float)i; printf("h_in[%d] = %f \n", i, h_in[i]); } 

FFTW计划使用inembed == onembed == NULL

 fftwf_plan forwardPlan = fftwf_plan_many_dft_r2c(2, //rank n, //dimensions = {nRows, nCols} howMany, //howmany h_in, //in NULL, //inembed howMany, //istride 1, //idist h_freq, //out NULL, //onembed howMany, //ostride 1, //odist FFTW_PATIENT /*flags*/); 

我还使用inembed = onembed = n = {nRows, nCols}运行了这个版本。


结果

请注意,使用NULLn会给出相同的数值结果,但内存顺序不同

版本1: inembed == onembed == NULL

 result[0][0,1] = 240, 0 result[1][0,1] = 256, 0 result[2][0,1] = -16, 16 result[3][0,1] = -16, 16 result[4][0,1] = -16, 0 result[5][0,1] = -16, 0 //this line and above match the other version result[6][0,1] = -64, 64 //this line and below don't match (data is in a different order) result[7][0,1] = -64, 64 result[8][0,1] = 0, 0 result[9][0,1] = 0, 0 result[10][0,1] = 0, 0 result[11][0,1] = 0, 0 result[12][0,1] = -64, 0 result[13][0,1] = -64, 0 result[14][0,1] = 0, 0 result[15][0,1] = 0, 0 result[16][0,1] = 0, 0 result[17][0,1] = 0, 0 result[18][0,1] = -64, -64 result[19][0,1] = -64, -64 result[20][0,1] = 0, 0 result[21][0,1] = 0, 0 result[22][0,1] = 0, 0 result[23][0,1] = 0, 0 result[24][0,1] = 0, 0 result[25][0,1] = 0, 0 result[26][0,1] = 0, 0 result[27][0,1] = 0, 0 result[28][0,1] = 0, 0 result[29][0,1] = 0, 0 result[30][0,1] = 0, 0 result[31][0,1] = 0, 0 

版本2: inembed = onembed = n = {nRows, nCols}

 result[0][0,1] = 240, 0 result[1][0,1] = 256, 0 result[2][0,1] = -16, 16 result[3][0,1] = -16, 16 result[4][0,1] = -16, 0 result[5][0,1] = -16, 0 result[6][0,1] = 0, 0 result[7][0,1] = 0, 0 result[8][0,1] = -64, 64 result[9][0,1] = -64, 64 result[10][0,1] = 0, 0 result[11][0,1] = 0, 0 result[12][0,1] = 0, 0 result[13][0,1] = 0, 0 result[14][0,1] = 0, 0 result[15][0,1] = 0, 0 result[16][0,1] = -64, 0 result[17][0,1] = -64, 0 result[18][0,1] = 0, 0 result[19][0,1] = 0, 0 result[20][0,1] = 0, 0 result[21][0,1] = 0, 0 result[22][0,1] = 0, 0 result[23][0,1] = 0, 0 result[24][0,1] = -64, -64 result[25][0,1] = -64, -64 result[26][0,1] = 0, 0 result[27][0,1] = 0, 0 result[28][0,1] = 0, 0 result[29][0,1] = 0, 0 result[30][0,1] = 0, 0 result[31][0,1] = 0, 0 

这是这个实验的一个有效实现 。

解:
通过设置inembed = {nRows, nCols}onembed = {nRows, (nCols/2 + 1)}来解决上例中embed != NULLinembed = {nRows, nCols}示例。


细节:

我仔细阅读了FFTW文档并从Matteo Frigo那里得到了一些帮助后解决了这个问题。 你可以在这里回溯我的步骤:

根据FFTW手册中的4.4.2高级实数据DFT : If an nembed parameter is NULL, it is interpreted as what it would be in the basic interface.

假设我们的输入实际数据的维数为nx * ny 。 对于FFTW基本接口, 2.4实数数据的多维DFT解释了以下用于2D实数到复数FFT的非inembedonembed约定:

 if out-of-place: inembed = [ny, nx] onembed = [ny, (nx/2 + 1)] if in-place: inembed = [ny, 2(nx/2 + 1)] onembed = [ny, (nx/2 + 1)] 

因此,当我们使用简单的FFTW r2c接口或使用embed=NULL的高级接口时,FFTW默认为上述embed参数。 我们可以通过使用上面的embed参数从embed=NULL重现数值结果。


事实certificate, Passing NULL for an nembed parameter is equivalent to passing n的语句Passing NULL for an nembed parameter is equivalent to passing n来自FFTW复杂到复杂的手册页。 但是,我们在上面的例子中进行了从实际到复杂的转换 。 实际到复杂的变换具有不同的约定,而不是复杂到复杂的变换,用于inembedonembed