Я работаю с пакетными 2D-БПФ, используя расширенный API-интерфейс компоновки данных FFTW.
Согласно FFTW Расширенный Комплекс DFT документация:
Переходя НОЛЬ для параметра nembed эквивалентно передаче 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}
,
Обратите внимание, что с помощью NULL
или же n
дает те же числовые результаты, но в другом порядке в памяти:
Версия 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
Решение:
Неуместный пример с embed != NULL
в приведенном выше примере решается путем установки inembed = {nRows, nCols}
а также onembed = {nRows, (nCols/2 + 1)}
,
Подробности:
Я решил это после очень внимательно читая документацию FFTW и получая некоторую помощь от Маттео Фриго. Вы можете повторить мои шаги здесь:
В соответствии с 4.4.2 Расширенные ДПФ для реальных данных в руководстве FFTW: If an nembed parameter is NULL, it is interpreted as what it would be in the basic interface.
Давайте предположим, что наши входные реальные данные имеют размерность nx * ny
,
Для базового интерфейса FFTW, 2.4 Многомерные ДПФ реальных данных объясняет следующее 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)]
Итак, когда мы используем простую FFTW r2c
интерфейс или использовать расширенный интерфейс с embed=NULL
, FFTW по умолчанию выше embed
параметры. Мы можем воспроизвести численные результаты из embed=NULL
используя вышеупомянутое embed
параметры.
Оказывается, что заявление Passing NULL for an nembed parameter is equivalent to passing n
исходит от FFTW комплекс-комплекс страница справочника. Но мы делаем преобразования реального в комплекс в приведенных выше примерах. Преобразования из реального в комплекс имеют другое соглашение, чем преобразования из сложного в комплексное для inembed
а также onembed
,
Других решений пока нет …