2016-08-24 18 views
0

複雑な積分を計算する必要がありません。この目的のために、私は上司からFortran 77で書かれた古いプログラムを入手しました。主にDATA文の構文エラーに関連しています。これは、実際の積分を計算する機能を備えたコードの一部です:Fortran 90のDATA文の構文エラー

FUNCTION CAUSSA(F,A,B,EPS) 
    IMPLICIT DOUBLE PRECISION (A-H,O-Z) 
    external f 
    REAL :: W(12),X(12) 
    DATA CONST /1.0D-12/ 
    DATA W & 
1 /0.10122 85362 9037 , 0.22238 10344 5337 , 0.31370 66458 7788 ,& 
2 0.36268 37833 7836 , 0.02715 24594 1175 , 0.06225 35239 3864 ,& 
3 0.09515 85116 8249 , 0.12462 89712 5553 , 0.14959 59888 1657 ,& 
4 0.16915 65193 9500 , 0.18260 34150 4492 , 0.18945 06104 5506/

    DATA X & 
1 /0.96028 98564 9753 , 0.79666 64774 1362 , 0.52553 24099 1632 ,& 
2 0.18343 46424 9565 , 0.98940 09349 9165 , 0.94457 50230 7323 ,& 
3 0.86563 12023 8783 , 0.75540 44083 5500 , 0.61787 62444 0264 ,& 
4 0.45801 67776 5722 , 0.28160 35507 7925 , 0.09501 25098 3763/
    DELTA=CONST*DABS(A-B) 
    CAUSSA=0.d0 
    AA=A 
5 Y=B-AA 
    IF(DABS(Y) .LE. DELTA) RETURN 
2 BB=AA+Y 
    C1=0.5*(AA+BB) 
    C2=C1-AA 
    S8=0.d0 
    S16=0.d0 
    DO 1 I=1,4 
    U=X(I)*C2 
1 S8=S8+W(I)*(F(C1+U)+F(C1-U)) 
    DO 3 I = 5,12 
    U=X(I)*C2 
3 S16=S16+W(I)*(F(C1+U)+F(C1-U)) 
    S8=S8*C2 
    S16=S16*C2 
    IF(DABS(S16-S8).GT.EPS*DABS(S16)) GO TO 4 
    CAUSSA= CAUSSA+S16 
    A=BB 
    GO TO 5 
4 Y=0.5*Y 
    IF(DABS(Y) .GT. DELTA) GO TO 2 
    write(2,7) 
    write(5,7) 
7 FORMAT(1X,35HCAUSSA...TOO HIGH ACCURACY REQUIRED) 
    CAUSSA=0.d0 
    RETURN 
END 

コンパイルの結果は以下の通りです:

sample.f90:11: 

1 /0.10122 85362 9037 , 0.22238 10344 5337 , 0.31370 66458 7788 ,&  
1 
Error: Syntax error in DATA statement at (1) 
sample.f90:17: 

1 /0.96028 98564 9753 , 0.79666 64774 1362 , 0.52553 24099 1632 ,& 
1  
Error: Syntax error in DATA statement at (1) 

私はのgfortranバージョン4.4.7を使用しています。私はそれらの配列を書き直そうとしましたが、結果は常に同じです。この機能は統合には最適ではありませんが、まだ必要です。それがなければ、古いプログラムは崩壊しています。 私は何かアドバイスをいただきありがとうございます。

+0

コンパイルコマンドに '-ffixed-form'を追加することができます(またはファイル拡張子を' .f90'から '.f'に変更できます)。 –

+0

フリーフォームの文継続マーカー(行末に '&')を追加するだけで、誰かが固定フォームソースをフリーフォームソースに変えようとしているようです。これ以上有効にしないと、有効ではありません。固定形式のソースに戻ることはできませんか、フリーフォームに完全に変換する必要はありますか? – francescalus

+0

これは元のコードですか?元のものを投稿できない場合は、 – innoSPG

答えて

3

あなたはこのように自由形式のソースをコンパイルしたい場合、あなたはおそらく、私はラベルが継続行に違法であることをかなり確信しているので、彼らは を削除する必要があります

  1. を変更する必要があります二つのものがあります
  2. gfortranは、浮動小数点数のセクション間のスペースを誤って解釈するので、それらも削除する必要があります。

このような何か:

DATA W & 
    /0.10122853629037 , 0.22238103445337 , 0.31370664587788 ,& 
    0.36268378337836 , 0.02715245941175 , 0.06225352393864 ,& 
    0.09515851168249 , 0.12462897125553 , 0.14959598881657 ,& 
    0.16915651939500 , 0.18260341504492 , 0.18945061045506/

はおそらく[ノートは、ブラウザで書かれており、テストされていません]が正しくコンパイルする必要があります。

+0

私の推測では、継続行の1桁の数値ステートメントラベルは、実際にはOPの元のコードで、実際には列6にあり、継続マーカーになります。 SOのコードフォーマットは、パンチカードレイアウトのルールを尊重するものではありません。 –

+0

@HighPerformanceMark:それはおそらく正しいでしょう。しかし、問題は実際にOPのコードを固定形式から自由形式に再フォーマットすることに実際にあったかもしれないと思います。 – talonmies

+1

継続行を固定形式と自由形式の両方で使用するために頻繁に使用される方法は、継続する行に&at列73を追加し、継続行に&6を先頭に追加することです。フリーフォームの固定変換プログラムは、フォームを引用符で囲んだままにしてはいけません。 – tim18

0

元のコードが、フリーフォームと固定ソースの両方のフォーマットを誤って混在させていました。自由形式の行継続は、次の行の6列目の文字を入力するのではなく、末尾のアンパサンド文字&を使用して実行されます。固定ソース形式では、最初の6つの列はステートメントラベル用に予約されており、列1はコメント行を示すためにも使用されています。現代のコードでは、構造化された制御ステートメント(select caseまたはif-then-elseなど)ステートメントラベルを使用することは珍しいことです。したがって、最初の5つの列はほとんど使用されないので無駄になります。

ここ

は、自由形式と固定ソース形式で同じコードです:

program main 

    use ISO_Fortran_env, only: & 
     compiler_version, & 
     compiler_options 

    ! Explicit typing only 
    implicit none 

    ! Variable declarations 
    double precision :: a, b, eps, x 

    a = 1.0d0 
    b = 2.0d0 
    eps = epsilon(a) 
    x = caussa(my_func, a, b, eps) 

    print '(/4a/)', & 
    ' This file was compiled using ', compiler_version(), & 
    ' using the options ', compiler_options() 

contains 

    function my_func(arg) result (return_value) 
     ! Dummy arguments 
     double precision, intent (in) :: arg 
     double precision    :: return_value 

     return_value = arg * 42.0d0 

    end function my_func 

    function caussa(f,a,b,eps) 

     use ISO_Fortran_env, only: & 
      stderr => ERROR_UNIT 

     implicit double precision (a-h,o-z) 
     external f 
     integer :: i 
     real :: w(12),x(12) 
     data const /1.0d-12/ 
     data w & 
     /0.10122853629037, 0.22238103445337, 0.31370664587788 ,& 
     0.36268378337836, 0.02715245941175, 0.06225352393864 , & 
     0.09515851168249, 0.12462897125553, 0.14959598881657 , & 
     0.16915651939500, 0.18260341504492, 0.18945061045506/

     data x & 
     /0.96028985649753, 0.79666647741362, 0.52553240991632, & 
     0.18343464249565, 0.98940093499165, 0.94457502307323, & 
     0.86563120238783, 0.75540440835500, 0.61787624440264, & 
     0.45801677765722, 0.28160355077925, 0.09501250983763/

    delta=const*dabs(a-b) 
    caussa=0.d0 
    aa=a 
5 y=b-aa 
    if (dabs(y) <= delta) return 
2 bb=aa+y 
    c1=0.5*(aa+bb) 
    c2=c1-aa 
    s8=0.d0 
    s16=0.d0 
    do 1 i=1,4 
     u=x(i)*c2 
1  s8=s8+w(i)*(f(c1+u)+f(c1-u)) 
     do 3 i = 5,12 
      u=x(i)*c2 
3   s16=s16+w(i)*(f(c1+u)+f(c1-u)) 
      s8=s8*c2 
      s16=s16*c2 
      if (dabs(s16-s8)>eps*dabs(s16)) go to 4 
      caussa = caussa+s16 
      a = bb 
      go to 5 
4   y = 0.5*y 
      if (dabs(y) > delta) go to 2 
      write(2,7) 
      write(stderr,7) 
      ! 
      ! 7 format(1x,35hcaussa...too high accuracy required) 
      ! Hollerith format specifier is a Fortran 95 deleted feature 
      ! 
7    format(1x, 'caussa...too high accuracy required') 
      caussa=0.d0 

    end function caussa 

end program main 

ここで「重要な空白の概念は、自由形式で固定形式のバージョン

 PROGRAM MAIN 

     USE ISO_FORTRAN_ENV, ONLY: 
    1 COMPILER_VERSION, 
    2 COMPILER_OPTIONS 

C EXPLICIT TYPING ONLY 
     IMPLICIT NONE 

C VARIABLE DECLARATIONS 
     DOUBLE PRECISION :: A, B, EPS, X 

     A = 1.0D0 
     B = 2.0D0 
     EPS = EPSILON(A) 
     X = CAUSSA(MY_FUNC, A, B, EPS) 

     PRINT '(/4A/)', 
    1 ' THIS FILE WAS COMPILED USING ', COMPILER_VERSION(), 
    2 ' USING THE OPTIONS ', COMPILER_OPTIONS() 

     CONTAINS 

     FUNCTION MY_FUNC(ARG) RESULT (RETURN_VALUE) 
C DUMMY ARGUMENTS 
     DOUBLE PRECISION, INTENT (IN) :: ARG 
     DOUBLE PRECISION    :: RETURN_VALUE 

     RETURN_VALUE = ARG * 42.0D0 

     END FUNCTION MY_FUNC 

     FUNCTION CAUSSA(F,A,B,EPS) 

     USE ISO_FORTRAN_ENV, ONLY: 
    1 STDERR => ERROR_UNIT 
     IMPLICIT DOUBLE PRECISION (A-H,O-Z) 
     EXTERNAL F 
     INTEGER I 
     REAL :: W(12), X(12) 
     DATA CONST /1.0D-12/ 
     DATA W 
    1 /0.10122 85362 9037, 0.22238 10344 5337, 0.31370 66458 7788, 
    2 0.36268 37833 7836, 0.02715 24594 1175, 0.06225 35239 3864, 
    3 0.09515 85116 8249, 0.12462 89712 5553, 0.14959 59888 1657, 
    4 0.16915 65193 9500, 0.18260 34150 4492, 0.18945 06104 5506/
     DATA X 
    1 /0.96028 98564 9753, 0.79666 64774 1362, 0.52553 24099 1632, 
    2 0.18343 46424 9565, 0.98940 09349 9165, 0.94457 50230 7323, 
    3 0.86563 12023 8783, 0.75540 44083 5500, 0.61787 62444 0264, 
    4 0.45801 67776 5722, 0.28160 35507 7925, 0.09501 25098 3763/

     DELTA=CONST*DABS(A-B) 
     CAUSSA=0.D0 
     AA=A 
    5 Y=B-AA 
     IF(DABS(Y) .LE. DELTA) RETURN 
    2 BB=AA+Y 
     C1=0.5*(AA+BB) 
     C2=C1-AA 
     S8=0.D0 
     S16=0.D0 
     DO 1 I=1,4 
     U=X(I)*C2 
    1 S8=S8+W(I)*(F(C1+U)+F(C1-U)) 
     DO 3 I = 5,12 
     U=X(I)*C2 
    3 S16=S16+W(I)*(F(C1+U)+F(C1-U)) 
     S8=S8*C2 
     S16=S16*C2 
     IF(DABS(S16-S8).GT.EPS*DABS(S16)) GO TO 4 
     CAUSSA= CAUSSA+S16 
     A=BB 
     GO TO 5 
4 Y=0.5*Y 
     IF(DABS(Y) .GT. DELTA) GO TO 2 
     WRITE(2,7) 
     WRITE(STDERR,7) 
C 
C 7 FORMAT(1X,35HCAUSSA...TOO HIGH ACCURACY REQUIRED) 
C HOLLERITH FORMAT SPECIFIER IS A FORTRAN 95 DELETED FEATURE 
C 
    7 FORMAT(1X, 'CAUSSA...TOO HIGH ACCURACY REQUIRED') 
     CAUSSA=0.D0 
     RETURN 
     END FUNCTION CAUSSA 
     END PROGRAM MAIN 

です"が導入されました。 固定ソースでは、ほとんどのコンテキストでブランクは重要ではありませんでした。ここで今、空白なしで同等の文に続いて重大な空白を考えられるものを示す固定ソース文のサンプルです:私たちは

data w & 
/0.10122853629037, blah blah 
として

DATA W 
1 /0.10122 85362 9037, blah blah 

を書き直した方法を

DO N = 1, MAX ITER S 

DO N = 1, MAXITERS 

お知らせ