在互联网上,我发现这个程序演示了评估第一种和第二种椭圆积分(完整)
implicit none
real*8 e,e1,e2,xk
integer i, n
e=1.d-7
print *,' K K(K) E(K) STEPS '
print *,'------------------------------------------'
xk=0.d0
do i = 1, 20
call CElliptic(e,xk,e1,e2,n)
write(*,50) xk,e1,e2,n
xk = xk + 0.05d0
end do
print *,'1.00 INFINITY 1.0000000 0'
stop
50 format(' ',f4.2,' ',f9.7,' ',f9.7,' ',i2)
end
完成第一种和第二种椭圆积分。输入参数是xk,应该在0和1之间。技术使用高斯'算术几何平均数的公式。 e是收敛精度的度量。返回值是e1,第一种椭圆积分,e2,第二种椭圆积分。
Subroutine CElliptic(e,xk,e1,e2,n)
! Label: et
real*8 e,xk,e1,e2,pi
real*8 A(0:99), B(0:99)
integer j,m,n
pi = 4.d0*datan(1.d0)
A(0)=1.d0+xk ; B(0)=1.d0-xk
n=0
if (xk < 0.d0) return
if (xk > 1.d0) return
if (e <= 0.d0) return
et n = n + 1
! Generate improved values
A(n)=(A(n-1)+B(n-1))/2.d0
B(n)=dsqrt(A(n-1)*B(n-1))
if (dabs(A(n)-B(n)) > e) goto et
e1=pi/2.d0/A(n)
e2=2.d0
m=1
do j = 1, n
e2=e2-m*(A(j)*A(j)-B(j)*B(j))
m=m*2
end do
e2 = e2*e1/2.d0
return
end
我编译了它,但收到了以下错误:
gfortran -Wall -c&#34; gauss.f&#34; (nel direttorio:/ home / pierluigi / Scrivania) gauss.f:53.9:
50 format(' ',f4.2,' ',f9.7,' ',f9.7,' ',i2)
1
错误:名称中的字符无效(1) gauss.f:83.72:
if (dabs(A(n)-B(n)) > e) goto et
1
警告:删除功能:在(1)处分配GOTO声明 gauss.f:83.35:
if (dabs(A(n)-B(n)) > e) goto et
1
错误:(1)处的ASSIGNED GOTO语句需要INTEGER变量 gauss.f:48.18: 写(*,50)xk,e1,e2,n 1 错误:未定义(1)处的FORMAT标签50 编译失败。
有什么建议吗?
修改
我已经阅读了你的所有答案,谢谢你,我设法编译了程序。我还有另一个好奇心,我不知道是否要写另一个问题。与此同时,我修改了这个问题。在我的程序中,xk增加了0.05。现在我将该程序从包含以下内容的文件中读取数据:xk的最小值; xk的最大值;间隔的数量。我想:
open (10,file='data/test')
read (10,*) xkmi, xkma
read (10,*) nk
close (10)
lkmi = dlog(xkmi)
lkma = dlog(xkma)
ldk = (lkma-lkmi)/dfloat(nk-1)
此外,必须以将结果写入另一个文件的方式修改程序。如何更改程序的其余部分?非常感谢你。
答案 0 :(得分:2)
您的源代码文件扩展名为f
,我认为(请查看文档)告诉gfortran
该文件包含固定源格式。直到Fortran 90 Fortran仍被编写为穿孔卡片,并且线条的各种位置的位置仅限于某些列。第一个错误消息中的语句标签(例如50
)必须位于第1列到第6列中。两个解决方案:
f90
,也许是使用编译选项(查看文档)。正如您的编译器告诉您的那样,goto et
短语引发的错误是一个已删除功能的示例,其中goto
跳转到在运行时提供其标签的语句,即et
的值。告诉你的编译器(检查......)是否符合旧标准,或者使你的源更新。
修复这些错误,我怀疑,其他错误消息将消失。它们可能是由于编译器在错误之后没有正确解析源而引发的。
答案 1 :(得分:1)
因为文件的类型为&#34; .f&#34; gfortan将其解释为固定源布局。尝试使用编译器选项-ffree-form
编译自由格式布局,看看是否有效。这可能解释了关于&#34;无效字符&#34;的错误。该声明未被识别解释了&#34;格式未定义错误&#34;。 &#34;计算goto&#34;已过时但有效的Fortran。你可以忽略那个警告。如果您愿意,以后可以使代码现代化。对于剩余的错误,对于&#34;指定的转到&#34;,声明&#34; et&#34;作为整数。
答案 2 :(得分:1)
我会这样做
10 n = n + 1
! Generate improved values
A(n)=(A(n-1)+B(n-1))/2.d0
B(n)=dsqrt(A(n-1)*B(n-1))
if (dabs(A(n)-B(n)) > e) goto 10
并且可能像其他人所示的那样编译为自由格式源。标签et
似乎很奇怪且非标准,可能是罕见的供应商扩展。
您还可以使用exit
语句(Fortran 90)将上面的行更改为do-loop。
(改变后为我编制的程序)。
答案 3 :(得分:1)
我测试了子程序并与matlab进行了比较,结果并不相同。它与Abramowitz的书中使用的算法非常相似。这是我写的那个效果很好的,只是为了比较。
subroutine CElliptic(m,K,E)
implicit none
real*8 m,alpha,E,K,A,B,C,A_p,B_p,C_0,pi,suma
integer j,N
N=100
alpha=asin(sqrt(m))
pi = 4.d0*datan(1.d0)
A_p=1.0
B_p=cos(alpha)
C_0=sin(alpha)
suma=0.0
do j=1,N
A=(A_p+B_p)/2.0d0
B=dsqrt(A_p*B_p)
C=(A_p-B_p)/2.0d0
suma=suma+2**(j)*C**2
A_p=A
B_p=B
end do
K=pi/(2*A)
E=(1-1.d0/2.d0*(C_0**2+suma))*K
end Subroutine CElliptic
最好的问候
编