Разлика между реален fft и комплексен fft с въображаема част от нула в fftw?

Имам истинска 2d матрица. Взимам неговия fft с помощта на fftw. Но резултатът от използването на реален до комплексен fft е различен от комплексен (с имагинерна част, равна на нула) до комплексен fft.

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

 0     1     2
 3     4     5
 6     7     8

резултат от реални към комплексни fft

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

Аз съм след резултата от сложно към сложно fft. Но fft от реално към сложно е много по-бързо и моите данни са реални. Правя ли програмна грешка или резултатът трябва да е различен?


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