fortran复杂到真正的fftw问题

时间:2015-03-28 20:10:03

标签: fortran fft fftw

我目前正在开展一个需要实现傅立叶变换和逆变换的项目。我正在测试我从在线示例修改的程序; print或write命令通常用于调试目的:

  program testit
  INCLUDE 'fftw3.f'
  double complex out!, in
  real in
  parameter (N=100)
  dimension in(N), out(N)
  integer*8 p,p2
  integer i,j
  real x
  real fact
  write(*,*)"stuff in data"
  OPEN(UNIT=12, FILE="input.txt", ACTION="write", STATUS="replace")
  OPEN(UNIT=20, FILE="dftoutput.txt", ACTION="write", STATUS="replace")
  x=0
  in = 0
  do i=1,N/2
    in(i)=1
  enddo
  do i=1,N
  write(*,"(f10.2,1x,f10.2)")in(i)
  WRITE(12,*)real(in(i))
  enddo
  write(*,*)"create plans"
  call dfftw_plan_dft_r2c_1d(p ,N,in,out,FFTW_ESTIMATE)
  call dfftw_plan_dft_c2r_1d(p2,N,in,out,FFTW_ESTIMATE)
  write(*,*)"do it"
  call dfftw_execute_dft_r2c(p,in,out)
  do i=1,N
    write(*,"(f12.4,1x,f12.4)")out(i)
    WRITE(20,*)abs(out(i))
  enddo
  write(*,*)"undo it"
  call dfftw_execute_dft_c2r(p2,in,out)
  fact=1.0/N
  do i=1,N
    write(*,)in(i)
    write(*,)out(i)
  enddo
  write(*,*)"clean up"
  call dfftw_destroy_plan(p,in,out)
  call dfftw_destroy_plan(p2,in,out)
  end program

真实到复杂的转型工作得很好。逆变换给出了错误的值,并以某种方式修改了输入和输出变量。我不知道问题是什么,我无法在网上找出任何答案。感谢帮助。

提前致谢!

Chad W. Freer

编辑:我也想知道fftw包中是否有来自matlab的fftshift()和ifftshift()的类似功能。

1 个答案:

答案 0 :(得分:1)

存在精度问题:在大多数计算机上,real指的是单精度32位浮点数。 real*8可用于指定双精度浮点数,以与double complexdfftw_...保持一致。

对于FFTW实数到复数变换,如果输入的大小为N real*8,则size of the outputN/2+1 double complex。由于输入是真实的,coefficients of negative frequencies (higher than N/2+1) are conjugate of positive frequencies,并且避免了它们的计算。

根据FFTW关于planner flags的文档,

  

FFTW_PRESERVE_INPUT指定不合适的变换不得更改其输入数组。这通常是默认值,除了c2r和hc2r(即复数到实数)变换,其中FFTW_DESTROY_INPUT是默认变换...

如果您希望将系数保存在傅里叶空间out中,请复制数组,或尝试使用FFTW_PRESERVE_INPUT。如果你有足够的记忆,第一个解决方案似乎是最好的方法。

FFTW函数的参数顺序始终为origin,destination。由于后向变换是从outin执行的:

call dfftw_plan_dft_c2r_1d(p2,N,out,in,FFTW_ESTIMATE)
...
call dfftw_execute_dft_c2r(p2,out,in)

这是一个基于你的代码,它执行向前和向后fft。它由gfortran main.f90 -o main -lfftw3 -lm -Wall编译:

program testit
INCLUDE 'fftw3.f'
double complex out!, in
real*8 in
parameter (N=100)
dimension in(N), out((N/2+1))
integer*8 p,p2
integer i
real x
real fact
write(*,*)"stuff in data"
OPEN(UNIT=12, FILE="input.txt", ACTION="write", STATUS="replace")
OPEN(UNIT=20, FILE="dftoutput.txt", ACTION="write", STATUS="replace")
x=0
in = 0
do i=1,N/2
  in(i)=1
enddo
do i=1,N
  write(*,"(f10.2,1x/)")in(i)
  WRITE(12,*)real(in(i))
enddo
write(*,*)"create plans"
call dfftw_plan_dft_r2c_1d(p ,N,in,out,FFTW_ESTIMATE)
call dfftw_plan_dft_c2r_1d(p2,N,out,in,FFTW_ESTIMATE)
write(*,*)"do it"
call dfftw_execute_dft_r2c(p,in,out)
do i=1,N/2+1
  write(*,"(f12.4,1x,f12.4/)")out(i)
  WRITE(20,*)abs(out(i))
enddo
write(*,*)"undo it"
call dfftw_execute_dft_c2r(p2,out,in)
fact=1.0/N
write(*,*)"input back, except for scaling"
do i=1,N
  write(*,"(f10.2,1x)")in(i)
enddo
write(*,*)"output may be modified by c2r...except if FFTW_PRESERVE_INPUT is set"
do i=1,N/2+1
  write(*,"(f10.2,1x,f10.2/)")out(i)
enddo
write(*,*)"clean up"
call dfftw_destroy_plan(p,in,out)
call dfftw_destroy_plan(p2,out,in)
end program

在向前fft in - > out和向后fft out - > in之后,in与其初始值相同,除了比例因子N