fftshift/ifftshift C/C++ source code [closed] fftshift/ifftshift C/C++ source code [closed] c c

fftshift/ifftshift C/C++ source code [closed]


FFTHIFT / IFFTSHIFT is a fancy way of doing CIRCSHIFT. You can verify that FFTSHIFT can be rewritten as CIRCSHIFT as following.You can define macros in C/C++ to punt FFTSHIFT to CIRCSHIFT.

A = rand(m, n);mm = floor(m / 2);nn = floor(n / 2);% All three of the following should provide zeros.circshift(A,[mm, nn]) - fftshift(A)circshift(A,[mm,  0]) - fftshift(A, 1)circshift(A,[ 0, nn]) - fftshift(A, 2) 

Similar equivalents can be found for IFFTSHIFT.

Circular shift can be implemented very simply with the following code (Can be improved with parallel versions ofcourse).

template<class ty>void circshift(ty *out, const ty *in, int xdim, int ydim, int xshift, int yshift){  for (int i = 0; i < xdim; i++) {    int ii = (i + xshift) % xdim;    for (int j = 0; j < ydim; j++) {      int jj = (j + yshift) % ydim;      out[ii * ydim + jj] = in[i * ydim + j];    }  }}

And then

#define fftshift(out, in, x, y) circshift(out, in, x, y, (x/2), (y/2))#define ifftshift(out, in, x, y) circshift(out, in, x, y, ((x+1)/2), ((y+1)/2))

This was done a bit impromptu. Bear with me if there are any formatting / syntactical problems.


Normally, centering the FFT is done with v(k)=v(k)*(-1)**k inthe time domain. Shifting in the frequency domain is a poor substitute, formathematical reasons and for computational efficiency.See pp 27 of:http://show.docjava.com/pub/document/jot/v8n6.pdf

I am not sure why Matlab documentation does it the way they do,they give no technical reference.


Possible this code may help. It perform fftshift/ifftshift only for 1D array within one buffer. Algorithm of forward and backward fftshift for even number of elements is fully identical.

void swap(complex *v1, complex *v2){    complex tmp = *v1;    *v1 = *v2;    *v2 = tmp;}void fftshift(complex *data, int count){    int k = 0;    int c = (int) floor((float)count/2);    // For odd and for even numbers of element use different algorithm    if (count % 2 == 0)    {        for (k = 0; k < c; k++)            swap(&data[k], &data[k+c]);    }    else    {        complex tmp = data[0];        for (k = 0; k < c; k++)        {            data[k] = data[c + k + 1];            data[c + k + 1] = data[k + 1];        }        data[c] = tmp;    }}void ifftshift(complex *data, int count){    int k = 0;    int c = (int) floor((float)count/2);    if (count % 2 == 0)    {        for (k = 0; k < c; k++)            swap(&data[k], &data[k+c]);    }    else    {        complex tmp = data[count - 1];        for (k = c-1; k >= 0; k--)        {            data[c + k + 1] = data[k];            data[k] = data[c + k];        }        data[c] = tmp;    }}

UPDATED: Also FFT library (including fftshift operations) for arbitrary points number could be found in Optolithium (under the OptolithiumC/libs/fourier)