2

正如标题所述,我正在使用带有 Fortran 90/95 的 FFTW(版本 3.2.2)来执行真实数据的 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 和 recov 数组来检查这一点 - 它最终不为零。此外,recov 数组的最大值和最小值都为零,这似乎表明没有任何变化。

我查看了 FFTW 文档,并将我的实现基于以下页面http://www.fftw.org/fftw3_doc/Fortran-Examples.html#Fortran-Examples。我想知道这个问题是否与索引有关,至少这是我倾向于的方向。无论如何,如果有人可以提供一些帮助,那就太好了!

谢谢!

4

1 回答 1

1

不确定这是否是这里所有麻烦的根源,但您声明变量的方式可能是罪魁祸首。

对于大多数编译器(这显然甚至不是标准),Complex*8是单精度的旧语法:复数变量总共占用 8 个字节,在实部和虚部之间共享(4+4 个字节)。

[在 Vladimir F 对我的回答发表评论后编辑 1,有关详细信息,请参阅他的链接:] 根据我的经验(即我曾经使用过的系统/编译器),Complex(Kind=8)对应于双精度复数的声明(实部和虚部,两者都占用 8 个字节)。

在任何系统/编译器上,Complex(Kind=Kind(0.d0))都应该声明一个双精度复数。

简而言之,您的复杂数组的大小不合适。分别替换出现的andReal*8和(或 为了更好的可移植性)。Complex*8Real(kind=8)Complex(Kind=8)Complex(Kind=kind(0.d0))

于 2018-04-11T20:50:53.190 回答