FFTW advanced layout – inembed = n et inembed = NULL donnent des résultats différents?

Je travaille avec des FFT 2D groupées à l’aide de l’API de présentation de données avancée FFTW.

Selon la documentation FFTW Advanced Complex DFT :

Passer NULL pour un paramètre nembed équivaut à passer n .

Cependant, inembed = onembed = NULL des résultats différents lorsque inembed = onembed = NULL vs. inembed = onembed = n . Qu’est-ce qui pourrait faire en sorte que les résultats ne correspondent pas?


Faisons un exemple …

Installer

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

Plan FFTW utilisant 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, //issortingde 1, //idist h_freq, //out NULL, //onembed howMany, //ossortingde 1, //odist FFTW_PATIENT /*flags*/); 

J’ai également exécuté une version de cela avec inembed = onembed = n = {nRows, nCols} .


Résultats

Notez que l’utilisation de NULL ou n donne les mêmes résultats numériques, mais dans un ordre différent en mémoire :

Version 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 

Version 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 

Voici une implémentation de travail de cette expérience .

Solution:
L’exemple embed != NULL avec embed != NULL dans l’exemple ci-dessus est résolu en définissant inembed = {nRows, nCols} et onembed = {nRows, (nCols/2 + 1)} .


Détails:

J’ai résolu ce problème après avoir lu très attentivement la documentation de la FFTW et obtenu de l’aide de Matteo Frigo . Vous pouvez retracer mes pas ici:

Selon 4.4.2 DFT de données réelles avancées dans le manuel FFTW: If an nembed parameter is NULL, it is interpreted as what it would be in the basic interface.

Supposons que nos données d’entrée réelles sont de dimension nx * ny . Pour l’interface de base FFTW, la DFT 2.4 multidimensionnelle de Real Data explique les inembed suivantes: inembed et onembed pour les onembed 2D réelles à complexes:

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

Ainsi, lorsque nous utilisons l’interface FFTW simple r2c ou l’interface avancée avec embed=NULL , FFTW utilise par défaut les parameters d’ embed ci-dessus. Nous pouvons reproduire les résultats numériques de embed=NULL en utilisant les parameters embed ci-dessus.


Il s’avère que l’instruction Passing NULL for an nembed parameter is equivalent to passing n provient de la page de manuel complexe à complexe FFTW . Mais, dans les exemples ci-dessus, nous effectuons des transformations du réel au complexe . Les transformations réelles en complexes ont une convention différente de celle des transformations complexes en complexes pour inembed et onembed .