fftshift/ifftshift C/C++源代码

Der*_*rek 14 c c++ matlab fft

有没有人知道是否有任何免费和开源的库以matlab中的方式实现这两个功能?

谢谢

Pav*_*ili 15

FFTHIFT/IFFTSHIFT是做CIRCSHIFT的一种奇特方式.您可以验证FFTSHIFT是否可以重写为CIRCSHIFT,如下所示.您可以在C/C++中定义宏以将FFTSHIFT转换为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) 
Run Code Online (Sandbox Code Playgroud)

IFFTSHIFT可以找到类似的等价物.

使用以下代码可以非常简单地实现循环移位(可以使用并行版本的课程进行改进).

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];
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后

#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))
Run Code Online (Sandbox Code Playgroud)

这是有点即兴完成的.如果有任何格式/语法问题,请耐心等待.


小智 5

通常,使用时域中的v(k)= v(k)*( - 1)**k来完成FFT的居中.出于数学原因和计算效率,频域中的移位是不良替代品.见第27页:http: //show.docjava.com/pub/document/jot/v8n6.pdf

我不确定为什么Matlab文档会像他们那样做,他们没有提供技术参考.


Ale*_*xei 5

可能此代码可能有所帮助.它仅对一个缓冲区内的1D阵列执行fftshift/ifftshift.偶数个元素的前后移位算法完全相同.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:也可以在Optolithium中找到任意点数的FFT库(包括ffthift操作) (在OptolithiumC/libs/fourier下)


Chr*_* A. 4

或者您可以通过用 C++ 键入并重新编码来自行完成type fftshift。Matlab 代码并没有那么复杂。

编辑:我注意到这个答案最近被否决了几次,并以负面的方式发表了评论。我记得有一次type fftshift比当前的实施更具启发性,但我可能是错的。如果我可以删除答案,我会的,因为它似乎不再相关。

是一个无需 circshift.

  • `fftshift` 是作为对 `circshift` 的调用来实现的,而 `circshift` 是一个内置函数,所以你看不到它是如何编码的。这是一个无用的答案。 (3认同)