Fortran 我对sinc的子函数定义有什么问题? 隐式无 字符*20,名称,名称 整数长度 实*8π,dt,m,n,θ 参数(长度=11900,dt=0.01d0,m=1,n=1,pi=3.1416 &,θ=0.2) 整数i 综合体*16立方英尺,系数,sgnl(1:长度) 实际*8吨(1:长度) 参数(cj=dcmplx(0,1)) 实时*8次,实时,图像 oflname=“filtered.data” fflname=“人工” 打开(11,文件名) i=1,长度 读取(11,*)时间、实时、图像 sgnl(i)=dcmplx(实sgnl,imag sgnl) t(i)=(i*dt-m)/(2**n) 结束循环 系数=0 i=1,长度 系数=系数 &+sgnl(i)*sinc(t(i))*exp(-cj*2*pi*t(i)) 结束循环 i=1,长度 sgnl(i)=sgnl(i) &-系数*sinc(t(i))*exp(-cj*2*pi*t(i)) &+coeff*sinc(t(i))*exp(-cj*2*pi*t(i)) &*exp(cj*θ) 结束循环 打开(12,文件名) i=1,长度 写(12,*)i*dt,sgnl(i) 结束循环 关闭(12) 实*8函数sinc(a) real*8::sinc,a 如果(abs(a)

Fortran 我对sinc的子函数定义有什么问题? 隐式无 字符*20,名称,名称 整数长度 实*8π,dt,m,n,θ 参数(长度=11900,dt=0.01d0,m=1,n=1,pi=3.1416 &,θ=0.2) 整数i 综合体*16立方英尺,系数,sgnl(1:长度) 实际*8吨(1:长度) 参数(cj=dcmplx(0,1)) 实时*8次,实时,图像 oflname=“filtered.data” fflname=“人工” 打开(11,文件名) i=1,长度 读取(11,*)时间、实时、图像 sgnl(i)=dcmplx(实sgnl,imag sgnl) t(i)=(i*dt-m)/(2**n) 结束循环 系数=0 i=1,长度 系数=系数 &+sgnl(i)*sinc(t(i))*exp(-cj*2*pi*t(i)) 结束循环 i=1,长度 sgnl(i)=sgnl(i) &-系数*sinc(t(i))*exp(-cj*2*pi*t(i)) &+coeff*sinc(t(i))*exp(-cj*2*pi*t(i)) &*exp(cj*θ) 结束循环 打开(12,文件名) i=1,长度 写(12,*)i*dt,sgnl(i) 结束循环 关闭(12) 实*8函数sinc(a) real*8::sinc,a 如果(abs(a),fortran,Fortran,在子定义函数sinc的最后一部分,我假设问题存在,但我不确定它到底是什么。gfortran注意到我没有定义sinc和a,“结束函数”应该是“结束程序”?我试图将您的程序更新为符合标准的现代Fortran: implicit none character*20 fflname,oflname integer length_sgnl real*8 pi, dt, m, n, theta parameter ( length_sgnl=11900

在子定义函数sinc的最后一部分,我假设问题存在,但我不确定它到底是什么。gfortran注意到我没有定义sinc和a,“结束函数”应该是“结束程序”?

我试图将您的程序更新为符合标准的现代Fortran:

  implicit     none
  character*20 fflname,oflname
  integer      length_sgnl
  real*8       pi, dt, m, n, theta
  parameter    ( length_sgnl=11900, dt=0.01d0, m=1, n=1, pi=3.1416
 &            ,theta=0.2 )
  integer      i     
  complex*16   cj, coeff ,sgnl(1 : length_sgnl)
  real*8       t(1 : length_sgnl)
  parameter    ( cj = dcmplx(0, 1) )
  real*8       time, real_sgnl, imag_sgnl



  oflname="filtered.data"
  fflname="artificial"
  open(11, file = oflname)
  do i=1, length_sgnl
     read(11, *) time, real_sgnl, imag_sgnl
     sgnl(i) = dcmplx(real_sgnl, imag_sgnl)
     t(i) = (i*dt - m) / (2**n)
  enddo


  coeff = 0
  do i=1, length_sgnl
     coeff = coeff 
 &        + sgnl(i) * sinc (t(i)) * exp (-cj*2*pi*t(i))
  enddo

  do i=1, length_sgnl
     sgnl(i) = sgnl(i) 
 &         - coeff * sinc (t(i)) * exp (-cj*2*pi*t(i))
 &         + coeff * sinc (t(i)) * exp (-cj*2*pi*t(i))
 &         * exp (cj*theta)
  enddo


  open(12, file = fflname)
  do i=1, length_sgnl
    write(12, *) i*dt, sgnl(i)
  enddo
  close(12)


  real*8     function sinc (a)
             real*8 :: sinc, a
             if (abs(a) < 1.0d-6) then
                sinc = 1
             else
                sinc = sin(pi*a) / (pi*a)
             end if
  end function           

  stop
  end
以下是我修复的语法错误:

  • 在定义sinc函数之前,添加了一个
    包含
    部分
    
  • 将连续字符(
    &
    )从连续行的开头移动到上一行的结尾
这些不是必需的更改,只是样式建议:

  • 使用内部模块
    iso_fortran_env
    获取
    real64
    变量,该变量允许您将变量定义为
    real(real64)
    ,而不是
    real*8
    ,因为前者是可移植的,而后者不是
  • 将变量类型的规范(例如,
    real
    )和
    参数
    合并为一行
  • 使用Fortran2008
    newunit
    参数来
    open
    ,而不是以单位数进行硬编码,因为如果您编写大型程序并使用现代编译器,这会为您节省一些麻烦
  • 确保您也关闭了输入文件
  • 声明您的sinc函数是纯的,因为它没有副作用
  • 为sinc函数使用了
    result
    符号,这样就不必在函数名前面指定类型
    real*8
  • program…end program
    的形式重写程序,而不是
    …stop end
编辑:

我还想指出的是,使用现代Fortran,数学本身可以用“数组表示法”和“基本函数”编写得更加精确。例如,如果定义sinc函数:

gfortran -std=f2008 -ffree-form sinctest.f
然后可以实际写为一行:

   coeff = 0
   do i=1, length_sgnl
      coeff = coeff &
            + sgnl(i) * sinc(t(i)) * exp(-cj*2*pi*t(i))
   end do
因此,我强烈建议您也研究一下现代数组表示法:)

编辑2:
试图强调哪些更改与修复错误相关,哪些更改只是样式建议(感谢Vladimir F)。

请添加编译器的确切消息。不过我要指出,您至少有两个问题:缺少
contains
语句
sinc
声明两次。你可能会在这两个问题上找到问题,也可以考虑熟悉FORTRAN的语法。你的答案很好,我只是想强调一下,问题的解决方案是什么(语法错误)以及什么只是风格建议。在这么多的信息中有点不知所措。谢谢你的建议-我已尝试相应地更新答案:)。非常感谢你的详细帮助和建议。情人节快乐!
   elemental function sinc(a) result(r)
     ! This function calculates sinc(a)=sin(pi*a)/(pi*a).
     real(real64), intent(in) :: a
     real(real64)             :: r

     if (abs(a) < 1.0e-6) then
       r = 1
     else
       r = sin(pi*a) / (pi*a)
     end if
   end function
   coeff = 0
   do i=1, length_sgnl
      coeff = coeff &
            + sgnl(i) * sinc(t(i)) * exp(-cj*2*pi*t(i))
   end do
coeff = sum(sgnl * sinc(t) * exp(-2*pi*cj*t))