Разница между реальным fft и комплексным fft с мнимой частью нуля в fftw?

У меня есть реальная 2d матрица. Я беру его с помощью fftw. Но результат использования действительного и сложного fft отличается от сложного (с мнимой частью, равной нулю) до сложного fft.

реальная матрица

 0     1     2
 3     4     5
 6     7     8

результат действительного сложного БПФ

36 -4.5+2.59808i  -13.5+7.79423i 
0  -13.5-7.79423i 0 
0  0              0 

Код:

int r = 3, c = 3;
int sz = r * c;
double *in = (double*) malloc(sizeof(double) * sz);
fftw_complex *out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * sz);
fftw_plan p = fftw_plan_dft_r2c_2d(r, c, in, out, FFTW_MEASURE);
for ( int i=0; i<r; ++i ){
    for ( int j=0; j<c; ++j ){
        in[i*c+j] = i*c + j;
    }
}
fftw_execute(p);

используя комплексную матрицу с мнимой частью нуля

сложная матрица

 0+0i     1+0i     2+0i
 3+0i     4+0i     5+0i
 6+0i     7+0i     8+0i

результат сложного к сложному fft

36               -4.5 + 2.59808i  -4.5 - 2.59808i 
-13.5 + 7.79423i 0               0 
-13.5 - 7.79423i 0               0  

Код:

int r = 3, c = 3;
int sz = r * c;
fftw_complex *out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * sz);
fftw_complex *inc = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * sz);
p = fftw_plan_dft_2d( r,c, inc, out, FFTW_FORWARD,FFTW_MEASURE);
for ( int i=0; i<r; ++i ){
    for ( int j=0; j<c; ++j ){
        inc[i*c+j][0] = i*c+j;
        inc[i*c+j][1] = 0;
    }
}
fftw_execute(p);

Мне нужен результат от комплекса к комплексу. Но реальный и сложный БПФ намного быстрее, и мои данные реальны. Я делаю ошибку программирования или результат должен быть другим?


person Saeid    schedule 03.07.2015    source источник


Ответы (1)


Как указано в документации FFTW.

Затем, после преобразования r2c, на выходе будет n0 × n1 × n2 × … × (nd- 1/2 + 1) массив из fftw_complex значений в порядке строк

Другими словами, результат вашего реального преобразования реальной матрицы из реального в сложное действительно таков:

 36            -4.5+2.59808i
-13.5+7.79423i  0
-13.5-7.79423i  0 

Вы можете заметить, что эти два столбца точно совпадают с первыми двумя столбцами вашего сложного преобразования. Отсутствующий столбец исключен из преобразования вещественного числа в сложное, поскольку он является избыточным из-за симметрии. Таким образом, полная матрица 3x3, включая отсутствующий столбец, может быть построена с использованием:

fftw_complex *outfull = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * sz);
int outc = (c/2+1);
for ( int i=0; i<r; ++i ){
    // copy existing columns
    for ( int j=0; j<outc; ++j ){
        outfull[i*c+j][0] = out[i*outc+j][0];
        outfull[i*c+j][1] = out[i*outc+j][1];
    }
    // generate missing column(s) from symmetry
    for ( int j=outc; j<c; ++j){
        int row = (r-i)%r;
        int col = c-j;
        outfull[i*c+j][0] =  out[row*outc+col][0];
        outfull[i*c+j][1] = -out[row*outc+col][1];
    }
}
person SleuthEye    schedule 06.07.2015