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)
在子定义函数sinc的最后一部分,我假设问题存在,但我不确定它到底是什么。gfortran注意到我没有定义sinc和a,“结束函数”应该是“结束程序”?我试图将您的程序更新为符合标准的现代Fortran: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
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
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))