〔戻る〕
Fortran(Formula Translation)は1950年代にJohn. W. Backus らによって開発されたプログラム言語であり, 科学技術計算において現在広く使われています. 1991年にISO(国際標準化機構)の国際規格として制定されたFortran 90では, それまでのFORTRAN 77規格を完全に包含しながら, 他のプログラム言語(C, C++, Pascal など)での経験にもとづいた機能を多数採り入れています. 追加されたおもな新機能は,配列演算・利用者データ型定義・ポインタ・ 動的記憶割付けなどです. 日本では1994年1月1日にJIS(日本工業規格) Fortran 90が制定されました. 現在のJIS Fortran規格は1998年10月20日付けで制定された Fortran 95です.
ここでは,LINEAR_SOLVEに利用した
Fortran 90の機能を簡単に紹介します.
プログラムの実行中に配列の大きさを決める動的配列割り当て機能があります.
配列は ALLOCATABLE属性を使って宣言し,
ALLOCATE文により配列の大きさを決定します.
不要になった配列は DEALLOCATE文によって解放します.
以下は,動的配列 vp, vs, vw,
ip, iq を宣言し,
何らかの方法で決定された nによって配列の大きさを割り当て,
サブルーチン GECP_Dに作業用配列として渡すプログラム例です.
real(kind(1D0)),dimension(:),allocatable :: vp,vs,vw ! 配列の宣言
integer(kind=4),dimension(:),allocatable :: ip,iq
:
allocate(vp(n),vs(n),vw(n),ip(n),iq(n)) ! 大きさの決定
:
call GECP_D(Z,k1,n,x,epsz,isw,ip,iq,vp,vs,vw,icon) ! 作業用配列の引き渡し
:
deallocate(vp,vs,vw,ip,iq) ! 配列の解放
:
|
引数が省略可能であるものを OPTIONAL属性によって宣言することで,
サブルーチンに省略値を渡すことができます.
利用者は自身でパラメータまたは手法を選択する必要のある場合にのみ引数を指定します.
その場合,キーワードを用いた引数を書くことができます.
利用者が引数を指定したかどうかの判断は組込み関数 PRESENTで
知ることができます.
function linear_solve_s(A,b,eps,sv,delta) result(x)
:
real(kind(1E0)),intent(in),optional :: eps
real(kind(1E0)),intent(out),optional :: sv
real(kind(1E0)),intent(in),optional :: delta
real(kind(1E0)) :: epsz=0.0E0,deltaz=1.0E-5
:
if(present(eps)) epsz=eps
if(present(delta)) deltaz=delta
:
call GECP_S(Z,k1,n,x,epsz,isw,ip,iq,vp,vs,vw,icon)
:
if(present(sv)) then
allocate(y(n),u(n))
:
|
linear_solve_s の引数 eps,
sv, delta が省略可能です.
利用者が引数を指定する場合にはキーワード引数として
以下の3つの例のように指定します.
x=linear_solve_s(A,b,eps=1.0E-5) |
x=linear_solve_s(A,b,sv=t) |
x=linear_solve_s(A,b,sv=t,delta=1.0E-3,eps=1.0E-2) |
組込み手続きの数学関数として利用できる ABS, MATMUL
などは引数の型や精度によらず同一の名前(総称名)で記述することができます.
利用者作成の手続きに対しても,
INTERFACE文を用いることにより複数の関数を同じ総称名として
呼び出せるようにできます.
次の例では,総称名 linear_solveにより,
単精度型・倍精度型・4倍精度型の関数を型と精度に応じてそれぞれ呼び出すように指定しています.
個別の関数副プログラム部分には,引数と結果の宣言を記述します.
interface linear_solve ! 総称名の指定
function linear_solve_s(A,b,eps,sv,delta) result(x) ! 単精度実数型
real(kind(1E0)),dimension(:,:),intent(in) :: A
real(kind(1E0)),dimension(:),intent(in) :: b
real(kind(1E0)),intent(in),optional :: eps
real(kind(1E0)),intent(out),optional :: sv
real(kind(1E0)),intent(in),optional :: delta
real(kind(1E0)),dimension(size(b)) :: x
end function linear_solve_s
function linear_solve_d(A,b,eps,sv,delta) result(x) ! 倍精度実数型
real(kind(1D0)),dimension(:,:),intent(in) :: A
real(kind(1D0)),dimension(:),intent(in) :: b
real(kind(1D0)),intent(in),optional :: eps
real(kind(1D0)),intent(out),optional :: sv
real(kind(1D0)),intent(in),optional :: delta
real(kind(1D0)),dimension(size(b)) :: x
end function linear_solve_d
function linear_solve_q(A,b,eps,sv,delta) result(x) ! 4倍精度実数型
real(kind(1Q0)),dimension(:,:),intent(in) :: A
real(kind(1Q0)),dimension(:),intent(in) :: b
real(kind(1Q0)),intent(in),optional :: eps
real(kind(1Q0)),intent(out),optional :: sv
real(kind(1Q0)),intent(in),optional :: delta
real(kind(1Q0)),dimension(size(b)) :: x
end function linear_solve_q
end interface
|
総称名として記述した関数副プログラムは,モジュールと呼ばれる副プログラムにまとめて記述することにより,他のプログラム単位から参照することができます.
module GECP
interface linear_solve ! 総称名の指定
:
end interface
end module GECP
|
USE文を用います.
〔戻る〕