Fortran对用于评估椭圆积分的程序的警告

时间:2014-05-27 07:22:44

标签: fortran

在互联网上,我发现这个程序演示了评估第一种和第二种椭圆积分(完整)

  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)

此外,必须以将结果写入另一个文件的方式修改程序。如何更改程序的其余部分?非常感谢你。

4 个答案:

答案 0 :(得分:2)

您的源代码文件扩展名为f,我认为(请查看文档)告诉gfortran该文件包含固定源格式。直到Fortran 90 Fortran仍被编写为穿孔卡片,并且线条的各种位置的位置仅限于某些列。第一个错误消息中的语句标签(例如50)必须位于第1列到第6列中。两个解决方案:

  1. 确保标签位于(某些)列中。或者,更好
  2. 移动到免费源表单,可能是将文件扩展名更改为f90,也许是使用编译选项(查看文档)。
  3. 正如您的编译器告诉您的那样,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
最好的问候 编