We don’t allow questions seeking recommendations for software libraries, tutorials, tools, books, or other off-site resources. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(10)
FFTHIFT / IFFTSHIFT 是一种执行 CIRCSHIFT 的奇特方法。
您可以验证 FFTSHIFT 是否可以重写为 CIRCSHIFT,如下所示。
您可以在 C/C++ 中定义宏,将 FFTSHIFT 转为 CIRCSHIFT。
IFFTSHIFT 可以找到类似的等效项。
循环移位可以通过以下代码非常简单地实现(当然可以使用并行版本进行改进)。
然后
这是临时完成的。如果有任何格式/语法问题,请耐心等待。
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.
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).
And then
This was done a bit impromptu. Bear with me if there are any formatting / syntactical problems.
这段代码可能会有所帮助。它仅对一个缓冲区内的一维数组执行 fftshift/ifftshift。偶数个元素的前向和后向 fftshift 算法完全相同。
更新:
另外,任意点数的 FFT 库(包括 fftshift 操作)可以在 Optolithium 中找到(在 OptolithiumC/库/傅立叶)
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.
UPDATED:
Also FFT library (including fftshift operations) for arbitrary points number could be found in Optolithium (under the OptolithiumC/libs/fourier)
通常,FFT 的居中通过 v(k)=v(k)*(-1)**k 完成
时域。频域移动是一个很差的替代品,对于
数学原因和计算效率。
参见第 27 页:
http://show.docjava.com/pub/document/jot/v8n6。 pdf
我不确定为什么 Matlab 文档会这样做,
他们没有提供技术参考。
Normally, centering the FFT is done with v(k)=v(k)*(-1)**k in
the time domain. Shifting in the frequency domain is a poor substitute, for
mathematical 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.
或者您可以通过键入
type fftshift
并用 C++ 重新编码来自己完成此操作。 Matlab 代码并没有那么复杂。编辑:我注意到这个答案最近被否决了几次,并以负面的方式发表了评论。我记得有一段时间
type fftshift
比当前的实现更具启发性,但我可能是错的。如果我可以删除答案,我会的,因为它似乎不再相关。这里是一个版本(由 Octave 提供),无需
圆周移位
。Or you can do it yourself by typing
type fftshift
and recoding that in C++. It's not that complicated of Matlab code.Edit: I've noticed that this answer has been down-voted a few times recently and commented on in a negative way. I recall a time when
type fftshift
was more revealing than the current implementation, but I could be wrong. If I could delete the answer, I would as it seems no longer relevant.Here is a version (courtesy of Octave) that implements it without
circshift
.我测试了此处提供的代码并制作了一个示例项目来测试它们。对于一维代码,可以简单地使用
std::rotate
我更喜欢使用
std::rotate
而不是 Alexei 的代码,因为它很简单。对于 2D 来说,情况变得更加复杂。对于偶数,它基本上是左右翻转和上下翻转。奇怪的是循环移位算法:
这里我通过一个接口实现了循环移位代码,仅使用一个数组进行输入和输出。对于偶数,仅需要一个数组,对于奇数,临时创建第二个数组并将其复制回输入数组。由于复制数组需要额外的时间,这会导致性能下降。
I tested the code provided here and made an example project to test them. For 1D code one can simply use
std::rotate
I prefer using
std::rotate
over the code from Alexei due to its simplicity.For 2D it gets more complicated. For even numbers it is basically a flip left right and flip upside down. For odd it is the circshift algorithm:
Here I implemented the circshift code with an interface using only one array for in and output. For even numbers only a single array is required, for odd numbers a second array is temporarily created and copied back to the input array. This causes a performance decrease because of the additional time for copying the array.
注意:提供了更好的答案,我只是将其保留在这里一段时间......我不知道什么。
尝试一下:
对于偶数维度的矩阵,您可以就地执行此操作,只需将相同的指针传递给输入和输出参数即可。
另请注意,对于一维数组,fftshift 只是 std::rotate。
Notice: There are better answers provided, I just keep this here for a while for... I do not know what.
Try this:
For matrices with even dimensions you can do it in-place, just passing the same pointer into in and out parameters.
Also note that for 1D arrays fftshift is just std::rotate.
您还可以使用 arrayfire 的
shift
函数替代 Matlab 的circshift
并重新实现其余代码。如果您对 AF 的任何其他功能感兴趣(例如通过简单更改链接器标志即可移植到 GPU),这可能会很有用。但是,如果您的所有代码都旨在在 CPU 上运行并且非常复杂,或者您不想使用任何其他数据格式(AF 需要 af::arrays),请坚持使用其他选项之一。
我最终更改为 AF,因为否则我必须将 fftshift 重新实现为 OpenCL 内核。
You could also use arrayfire's
shift
function as replacement for Matlab'scircshift
and re-implement the rest of the code. This could be useful if you are interested in any of the other features of AF anyway (such as portability to GPU by simply changing a linker flag).However if all your code is meant to be run on the CPU and is quite sophisticated or you don't want to use any other data format (AF requires af::arrays) stick with one of the other options.
I ended up changing to AF because I would have had to re-implement fftshift as an OpenCL kernel otherwise back in the time.
它会给出与 matlab 中的 ifftshift 等效的结果
It will give equivalent result to ifftshift in matlab
八度 使用 fftw 实施(i)快速移位。
Octave uses fftw to implement (i)fftshift.
您可以使用kissfft。它速度相当快,使用起来非常简单,而且免费。按照您想要的方式排列输出只需要:
a) 移位 (-dim_x/2, -dim_y/2, ...),具有周期性边界条件
b) FFT 或 IFFT
c) 向后移位 (dim_x/2, dim_y/2, ...) ,具有周期性边界条件
d) 尺度 ? (根据您的需要 IFFT*FFT 默认情况下会按 dim_x*dim_y*... 缩放函数)
You can use kissfft. It's reasonable fast, extremely simple to use, and free. Arranging the output like you want it requires only to:
a) shift by (-dim_x/2, -dim_y/2, ...), with periodic boundary conditions
b) FFT or IFFT
c) shift back by (dim_x/2, dim_y/2, ...) , with periodic boundary conditions
d) scale ? (according to your needs IFFT*FFT will scale the function by dim_x*dim_y*... by default)