2D FFT (IFFT) source code in C99


#include <math.h>
#include <complex.h>

#ifndef M_PI
#define M_PI      3.14159265358979323846
#endif
#define FFT2K     (2048)
#define Rotor(a)  (double _Complex)( cos(a) + I*sin(a) )

enum { FFT=DFT, IFFT=IDFT };

void FFT2k_TwoDimensionalC99( double _Complex **d, int flag ) { // ∵d[2048][2048]
#define elements  FFT2K
int     x, y, e;    // flag   IFFT(2*M_PI/e..), FFT(-2*M_PI/e..)
double  unit = (flag==IFFT) ? 2*M_PI/elements : -2*M_PI/elements;
double _Complex rotor[elements]; for(e=0;e<elements;e++) rotor[e]=Rotor(unit*e);

    for( y=0; y<elements; y++ ) {  // x軸方向の1次元FFT(IFFT)をy行分行う
        int     i, j, k, m, mh, ir;// ir:irev
        double _Complex  w, t;     // t: temp
        for( i=0, j=1; j<elements-1; j++ ) { // scrambler, for initial placement
            for( k=elements>>1; k>(i^=k); k>>=1 );
            if( j<i ){ t=d[y][j]; d[y][j]=d[y][i]; d[y][i]=t; } //exchange
        }
        for( mh=1; (m=mh<<1)<=elements; mh=m ) {
            for( ir=0, i=0; i<elements; i+=m ) {
                for( w=rotor[ir], k=elements>>2; k>(ir^=k); k>>=1 );//for next ir
                for( j=i; j<mh+i; j++ ) {
                         k  = j + mh;
                         t  = d[y][j] - d[y][k];
                    d[y][j] = d[y][j] + d[y][k];    // a ->- (a + b) ->- a
                    d[y][k] = t * w;                // b ->- (a-b)*w ->- b
        }   }   }
        if(flag==IFFT) for( i=0; i<elements; i++ ) d[y][i] /= elements;
    } // X_END
    for( x=0; x<elements; x++ ) {  // y軸方向の1次元FFT(IFFT)をx列分行う
        int     i, j, k, m, mh, ir;// ir:irev
        double _Complex  w, t;     // t: temp
        for( i=0, j=1; j<elements-1; j++ ) { // scrambler, for initial placement
            for( k=elements>>1; k>(i^=k); k>>=1 );
            if( j<i ){ t=d[j][x]; d[j][x]=d[i][x]; d[i][x]=t; } //exchange
        }
        for( mh=1; (m=mh<<1)<=elements; mh=m ) {
            for( ir=0, i=0; i<elements; i+=m ) {
                for( w=rotor[ir], k=elements>>2; k>(ir^=k); k>>=1 );//for next ir
                for( j=i; j<mh+i; j++ ) {
                         k  = j + mh;
                         t  = d[j][x] - d[k][x];
                    d[j][x] = d[j][x] + d[k][x];    // a ->- (a + b) ->- a
                    d[k][x] = t * w;                // b ->- (a-b)*w ->- b
        }   }   }
        if(flag==IFFT) for( i=0; i<elements; i++ ) d[i][x] /= elements;
    } // Y_END
}


////////////////////////////////////////////////////////////////////////
// How to use FFT2k_TwoDimensionalC99(...)  2019/04/01
//
void dft_TwoDimensional( COMPLEX **s, int lx, int ly, int flag ) {
int     w = lx>ly ? lx : ly;
COMPLEX **spreadsheet = NULL;

    double _Complex **ss = (double _Complex **)s;
    if( lx==2048 && ly==2048 ) return FFT2k_TwoDimensionalC99(ss,flag);
    if( (spreadsheet=(COMPLEX**)alloc2Darray(sizeof(COMPLEX),w,w)) ) {
       dft_TwoDimensionalWithTable( spreadsheet, w, s, lx, ly, flag );
       free(spreadsheet);
    } else dft_TwoDimensionalStandard( s, lx, ly, flag );
}