Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran FFTW:从实到复和从复到实2D变换器的问题_Fortran_Fft_Fortran90_Fftw_Ifft - Fatal编程技术网

Fortran FFTW:从实到复和从复到实2D变换器的问题

Fortran FFTW:从实到复和从复到实2D变换器的问题,fortran,fft,fortran90,fftw,ifft,Fortran,Fft,Fortran90,Fftw,Ifft,正如标题所述,我正在使用FFTW(3.2.2版)和Fortran 90/95对真实数据(实际上是一个随机数字段)执行2D FFT。我认为前进的一步是有效的(至少我得到了一些输出)。然而,我想通过执行IFFT来检查一切,看看是否可以重新构造原始输入。不幸的是,当我调用复杂的实际例程时,什么都没有发生,也没有得到错误输出,所以我有点困惑。以下是一些代码片段: implicit none include "fftw3.f" ! - im=501, jm=401, and lm=60 real*8

正如标题所述,我正在使用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和recov阵列进行差分来检查这一点,结果不是零。此外,recov阵列的最大值和最小值均为零,这似乎表明没有任何变化

我已经查阅了FFTW文档,并在下一页介绍了我的实现。我想知道这个问题是否与索引有关,至少这是我所倾向的方向。无论如何,如果有人能提供一些帮助,那就太好了


谢谢

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

对于大多数编译器(这显然不是一个标准),
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)
(或
Complex(kind=kind(0.d0))
,以提高可移植性,分别。

需要注意的一件事是,当进行FFT后再进行IFFT时,结果将按照相对于原始输入的常数因子进行缩放。比例因子的值取决于FFT和IFFT的定义/实现方式,但通常为N,其中N是FFT中的点数。当然,这里也可能有其他不相关的问题。我发现了这个问题——它与FFT调用完全无关。在我的代码(不是上面的示例)中,我将k设置为1D数组,但一直将其作为标量索引值进行访问。上面的代码应该没有任何错误。呜呜!为了让这对其他人仍然有用,我最终在网上找到了一些代码,其中包含了许多使用Fortran调用FFTW例程的非常有用的示例:@Jen在上面的代码中,由于混合了实*8和复*8变量,您正在失去精度:复*8对应于实*4,而不是实*8。用complex*16代替。Jen,我实际上甚至不能让那个示例代码工作。您是否在一开始就启用了任何东西以使其与gfortran一起工作?他还调用了一个当前版本中不存在的文件,因为只有一个.f包装而不是.f90。@Thomas James,我没有用gfortran尝试这个示例-我使用的是xlf。你确定你的编译步骤有正确的命令/语法吗?.f包装应该很好(替换.f90)。如果你愿意,我可以把我用来编译代码的Makefile发送给你——请告诉我。我试着把它贴在这里,但它不适合作为“评论”。你是对的,这就是问题所在。但是,您不应该建议kind=8是一件好事,而且它总是意味着8字节的组件。请看一些编译器会拒绝编译kind=8。谢谢。我的回答确实很不准确。希望这样更好,更好得多。