3

FFTW 高度なデータ レイアウト API を使用して、バッチ処理された 2D FFT を使用しています。

FFTW Advanced Complex DFTのドキュメントによると:

nembedパラメータにNULLを渡すことは、 nを渡すことと同じです。

inembed = onembed = NULLただし、 vsを使用すると異なる結果が得られます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}


結果

NULLornを使用すると同じ数値結果が得られますが、メモリ内の順序が異なることに注意してください。

バージョン 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 

これは、この実験の実用的な実装です。

4

1 に答える 1

4

解決策:
上記の例の の 場違いな例は、とembed != NULLを設定することで解決されます。 inembed = {nRows, nCols}onembed = {nRows, (nCols/2 + 1)}


詳細:

FFTW のドキュメントを注意深く読み、Matteo Frigoの助けを借りて、この問題を解決しまし。ここで私の手順をたどることができます:

FFTW マニュアルの4.4.2 Advanced Real-data 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 に関する次の規則inembedと規則について説明しています。onembed

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)]

そのため、単純な FFTWr2cインターフェイスを使用するか、高度なインターフェイスをで使用するとembed=NULL、FFTW はデフォルトで上記のembedパラメータになります。embed=NULL上記のembedパラメータを使用して、数値結果を再現できます。


Passing NULL for an nembed parameter is equivalent to passing nこのステートメントは、FFTW complex-to-complexマニュアル ページからのものであることが判明しました。しかし、上記の例では実数から複素数への変換を行っています。実数から複素数への変換には、 および の複素数から複素数への変換とは異なる規則がinembedありonembedます。

于 2013-07-11T00:37:23.357 に答える