FFTW:真实到复杂以及复杂到真实 2D 变换的问题
正如标题所述,我正在使用 FFTW(版本 3.2.2)和 Fortran 90/95 来执行真实数据(实际上是随机数字段)的 2D FFT。我认为前进的一步正在发挥作用(至少我得到了一些输出)。然而,我想通过执行 IFFT 来检查所有内容,看看是否可以重新构建原始输入。不幸的是,当我将复杂的例程调用为真实的例程时,没有任何反应,也没有获得错误输出,所以我有点困惑。以下是一些代码片段:
implicit none
include "fftw3.f"
! - im=501, jm=401, and lm=60
real*8 :: u(im,jm,lm),recov(im,jm,lm)
complex*8 :: cu(1+im/2,jm)
integer*8 :: planf,planb
real*8 :: dv
! - Generate array of random numbers
dv=4.0
call random_number(u)
u=u*dv
recov=0.0
k=30
! - Forward step (FFT)
call dfftw_plan_dft_r2c_2d(planf,im,jm,u(:,:,k),cu,FFTW_ESTIMATE)
call dfftw_execute_dft_r2c(planf,u(:,:,k),cu)
call dfftw_destroy_plan(planf)
! - Backward step (IFFT)
call dfftw_plan_dft_c2r_2d(planb,im,jm,cu,recov(:,:,k),FFTW_ESTIMATE)
call dfftw_execute_dft_c2r(planb,cu,recov(:,:,k))
call dfftw_destroy_plan(planb)
上面的前进步骤似乎有效(r2c),但后退步骤似乎不起作用。我通过区分 u 和 receive 数组来检查这一点 - 最终结果不为零。此外,recov 数组的最大值和最小值均为零,这似乎表明没有任何更改。
我查看了 FFTW 文档,并基于以下页面实现了我的实现 http ://www.fftw.org/fftw3_doc/Fortran-Examples.html#Fortran-Examples。我想知道问题是否与索引有关,至少这是我倾向于的方向。无论如何,如果有人能提供一些帮助,那就太好了!
谢谢!
As the title states I'm using FFTW (version 3.2.2) with Fortran 90/95 to perform a 2D FFT of real data (actually a field of random numbers). I think the forward step is working (at least I am getting some ouput). However I wanted to check everything by doing the IFFT to see if I can re-construct the original input. Unfortunately when I call the complex to real routine, nothing happens and I obtain no error output, so I'm a bit confused. Here are some code snippets:
implicit none
include "fftw3.f"
! - im=501, jm=401, and lm=60
real*8 :: u(im,jm,lm),recov(im,jm,lm)
complex*8 :: cu(1+im/2,jm)
integer*8 :: planf,planb
real*8 :: dv
! - Generate array of random numbers
dv=4.0
call random_number(u)
u=u*dv
recov=0.0
k=30
! - Forward step (FFT)
call dfftw_plan_dft_r2c_2d(planf,im,jm,u(:,:,k),cu,FFTW_ESTIMATE)
call dfftw_execute_dft_r2c(planf,u(:,:,k),cu)
call dfftw_destroy_plan(planf)
! - Backward step (IFFT)
call dfftw_plan_dft_c2r_2d(planb,im,jm,cu,recov(:,:,k),FFTW_ESTIMATE)
call dfftw_execute_dft_c2r(planb,cu,recov(:,:,k))
call dfftw_destroy_plan(planb)
The above forward step seems to work (r2c) but the backward step does not seem to work. I checked this by differencing the u and recov arrays - which ended up not being zero. Additionally the max and min values of the recov array were both zero, which seems to indicate that nothing was changed.
I've looked around the FFTW documentation and based my implementation on the following page http://www.fftw.org/fftw3_doc/Fortran-Examples.html#Fortran-Examples . I am wondering if the problem is related to indexing, at least that's the direction I am leaning. Anyway, if any one could offer some help, that would be wonderful!
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不确定这是否是所有问题的根源,但声明变量的方式可能是罪魁祸首。
对于大多数编译器(这显然不是标准),
Complex*8
是单精度的旧语法:复数变量总共占用 8 个字节,在实部和虚部之间共享( 4+4 字节)。[在 Vladimir F 对我的答案发表评论后编辑 1,有关详细信息,请参阅他的链接:] 根据我的经验(即我曾经使用过的系统/编译器),
Complex(Kind=8)
对应于以下声明双精度复数(实部和虚部,均占用 8 个字节)。在任何系统/编译器上,
Complex(Kind=Kind(0.d0))
应该声明一个双精度复数。简而言之,您的复杂数组的大小不正确。将出现的
Real*8
和Complex*8
替换为Real(kind=8)
和Complex(Kind=8)
code> (或Complex(Kind=kind(0.d0))
以获得更好的可移植性)。Not sure if this is the root of all troubles here, but the way you declare variables may be the culprit.
For most compilers (this is apparently not even a standard),
Complex*8
is an old syntax for single precision: the complex variable occupies a total of 8 bytes, shared between the real and the imaginary part (4+4 bytes).[Edit 1 following Vladimir F comment to my answer, see his link for details:] In my experience (i.e. the systems/compiler I ever used),
Complex(Kind=8)
corresponds to the declaration of a double precision complex number (a real and an imaginary part, both of which occupy 8 bytes).On any system/compiler,
Complex(Kind=Kind(0.d0))
should declare a double precision complex.In short, your complex array does not have the right size. Replace occurences of
Real*8
andComplex*8
byReal(kind=8)
andComplex(Kind=8)
(orComplex(Kind=kind(0.d0))
for a better portability), respectively.