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

时间:2013-06-03 21:13:57

标签: c++ c fft fftw

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

根据FFTW Advanced Complex DFT文档:

  

为nembed参数传递 NULL 相当于传递 n

但是,在使用inembed = onembed = NULLinembed = 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]);
}
使用inembed == onembed == NULL

FFTW计划

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 

这是working implementation of this experiment

1 个答案:

答案 0 :(得分:4)

解决方案:
通过设置embed != NULLinembed = {nRows, nCols},可以解决上述示例中包含onembed = {nRows, (nCols/2 + 1)}的不合适示例。


详细信息:

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

根据FFTW手册中的4.4.2 Advanced Real-data DFTsIf an nembed parameter is NULL, it is interpreted as what it would be in the basic interface.

假设我们的输入实际数据是维度nx * ny。 对于FFTW基本接口,2.4 Multi-Dimensional DFTs of Real Data解释了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=NULL参数重现embed的数值结果。


事实证明,Passing NULL for an nembed parameter is equivalent to passing n语句来自FFTW complex-to-complex手册页。但是,我们在上面的例子中正在做real-to-complex transforms。对于inembedonembed,实际到复杂的变换与复杂到复杂的变换有不同的约定。