4

LAPACK を利用するために Fortran で古い C++ プログラムを再コーディングしようとしています (C++ には LAPACK++ があることは知っていますが、インストールするのに多くの問題があるため、あきらめました)。

私はもともとコンパイルに問題はありませんでしたが、それはすべての変数を として宣言したときでしたREAL。LAPACK を必要とするプログラムのセクションのコーディングを開始したとき、渡されるすべてのパラメーターは でDSYEVある必要があることがわかりましたDOUBLE PRECISION。そのため、すべてを倍精度に変更しようとしました (すべてのハードコードされた数値を対応する倍精度に変更することを含む、つまり 0.0 -> 0.0D0) コンパイルしようとすると、すべての関数とサブルーチンに対して次のエラーが発生します書いた:

    Error: Return type mismatch of function <function> at (1) (REAL(4)/REAL(8))

プログラム内のすべてが倍精度に変更されているため、これがどこから来たのかはわかりません。

たとえば、次のように宣言しました。

double precision :: alpha(3),d(3),zeta1,zeta2
double precision :: A1(3),A2(3),D1(3),D2(3)
double precision :: PI
PI = 3.14159265359D0
alpha = (/0.109818D0, 0.405771D0, 2.22766D0/)
d = (/0.444635D0, 0.535328D0, 0.154329D0 /)

do 10 i=1,3

A1(i) = alpha(i)*zeta1**2.0D0
A2(i) = alpha(i)*zeta2**2.0D0
D1(i) = d(i)*(2.0D0*A1(i)/PI)**(3.0D0/4.0D0)
D2(i) = d(i)*(2.0D0*A2(i)/PI)**(3.0D0/4.0D0)

10  continue

そして機能:

subroutine createS(S,A1,A2,D1,D2,r)
double precision A1(3),A2(3),D1(3),D2(3) 
double precision r
double precision S(2,2)
integer :: i,j
S(1,1) = 1.0D0
S(2,2) = 1.0D0
do 80 i=1,3
do 90 j=1,3

S(1,2) = S(1,2) + getS(A1(i),A2(j),r)*D1(i)*D2(j)

 90 continue
 80 continue
S(2,1) = S(1,2)
return
end

double precision function getS(a,b,r)
double precision :: PI
double precision a,b,r
double precision :: S
PI = 3.14159265359D0
S = (PI/(a+b))**1.5D0
S = S*dexp(-(a*b*r*r)/(a+b))
getS = S
return
end

そして、私はエラーが発生します

  HFSTO3G.f:85.28:

  S(1,2) = S(1,2) + getS(A1(i),A2(j),r)*D1(i)*D2(j)                 
                        1
  Error: Return type mismatch of function 'gets' at (1) (REAL(4)/REAL(8))

コンパイルにはgfortranを使用しています。それが問題でしょうか?私はプログラミングは初めてではありませんが、Fortran は初めてです。これを Fortran でプログラミングしないという選択肢はありません。

4

2 に答える 2

4

サブルーチンと関数をモジュールとuseそのモジュールに入れましたか? それ以外の場合は、サブルーチン createS で getS の暗黙的な型付けを単精度実数として取得している可能性がありますが、実際には倍精度が返されます。別の提案:implicit none宣言されていない変数を見つけるために常に使用します。ソース コードに含めるのを忘れた場合に備えてimplicit none、gfortran にはコンパイラ オプションが用意されています-fimplicit-none。暗黙の型付けは有害であり、レガシー コードをサポートするために Fortran で継続される可能性があります。

PSdouble precisionも時代遅れですが、暗黙の型付けよりもはるかにリスクが低くなります。gfortran の最新バージョンを使用している場合は、次を使用できます。

use ISO_FORTRAN_ENV
real (real64) ::

gfortran のマニュアルを参照してください。

編集: implicit nonegetS の型を real(4) (暗黙の型付けによる) から不明 (型が宣言されていない、暗黙の型付けが無効になっている) に変更しました。プロシージャをモジュールに配置すると、関数の戻り値と引数の型など、互いの型を「認識」します。これにより、このバグが修正されます。また、コンパイラが他のバグを見つけるのにも役立ちますが、呼び出しとプロシージャの引数の間の引数の一貫性をチェックできるようにします。例については、Fortranでのモジュール、サブルーチン、関数の正しい使用およびFortran 90 での 2 つのベクトルの外積の計算を参照してください。

于 2013-05-24T18:24:01.870 に答える