More Efficient ifftshift / fftshift in C++

matlablogo

Previously I touched upon ifftshift and fftshift in this post. https://kerpanic.wordpress.com/2016/01/15/matlab-circshift-equivalent-in-c-c/ . I’ve come to realize that there are better ways to implement fftshift and iftshift using simple memory swapping. Note that you have to pre-allocate the appropriate amount of memory for T*out before calling this function.

//-- Does 1D fftshift 
template<typename T>
inline void fftshift1D(T *in, T *out, int ydim)
{
 int pivot = (ydim % 2 == 0) ? (ydim / 2) : ((ydim - 1) / 2);
 int rightHalf = ydim-pivot;
 int leftHalf = pivot;
 memcpy(out, in+(pivot), sizeof(T)*rightHalf);
 memcpy(out+rightHalf, in, sizeof(T)*leftHalf);
}

//-- Does 1D ifftshift
//-- Note: T* out must already by memory allocated!!
template<typename T>
inline void ifftshift1D(T *in, T *out, int ydim)
{
 int pivot = (ydim % 2 == 0) ? (ydim / 2) : ((ydim + 1) / 2);

 int rightHalf = ydim-pivot;
 int leftHalf = pivot;
 memcpy(out, in+(pivot), sizeof(T)*rightHalf);
 memcpy(out+rightHalf, in, sizeof(T)*leftHalf);
}

 

Hope this helps! It is good as  a Matlab C++ equivalent.

If you want to do 2D you will have to fftshift first, transpose the matrix, then fftshift it again. Then transpose back to the original matrix form.

Also, a better circshift would be to use C++’s in-built std::rotate

template<typename T>
inline void circshift1D_IP(T *in, int ydim, int yshift)
{
 if (yshift == 0)
 return;

 if (yshift > 0) // shift right
 std::rotate(&in[0], &in[ydim - yshift - 1], &in[ydim - 1]);
 else if (yshift < 0) // shift left
 {
 yshift = abs(yshift);
 std::rotate(&in[0], &in[yshift], &in[ydim - 1]);
 }

 return;
}
Advertisements

One thought on “More Efficient ifftshift / fftshift in C++

Add yours

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

Up ↑

%d bloggers like this: