FORTRAN は、1950年代に開発された言語で、計算機言語としては、歴史が古い。進歩 の速い計算機に関しては、歴史が古いという事は、多くの場合、陳腐で劣る事を意味 する事が多い。事実、50年代或いはそれ以後開発された言語で、今日では使用されな くなった言語は非常に多い。そういった環境の中にあっても、FORTRAN は、色々な意 味で、優れた点を多く持った言語なので、様々な改良を加えられながら、今日まで、 科学計算用の標準的言語の一つとして、使われ続けている。その特徴としては、
FORTRAN を使って計算をしたい時には、FORTRAN の言語で書かれた一つのファイルを 先ず作らなければならない。こういったファイルをプログラムと呼ぶ。例として、球 の半径が与えられた時に、球の表面積と体積を求める計算を考えよう。そのためのプ ログラムの例は、第2章で、エディタを使ってのファイル作成練習で書い た、sphere.fである。念のため、下に掲げておこう 。
Program sphere Implicit NONE c constant: Real PI Parameter (PI=3.141593) c local variable: Real radius Real area, volume c begin: radius = 10.0 area = 4. * PI * radius**2 volume = area * radius /3. Write(*,*) 'radius:',radius Write(*,*) ' surface area =',area,' volume =',volume c end: Stop End
例.
a = 1.0 b = a + 1.0
演算 | FORTRAN | 例 |
加算 | x + y | |
減算 | x - y | |
掛算 | x * y | |
割算 | x/y | |
冪乗 | x**y | |
括弧 | (2.*(x + y))/(3.*(a + b)) |
Implicit NONE Parameter (PI=3.141593)がそうだ。最初の例は、そのプログラムで使用する変数は全て型宣言をしてから 使う事を宣言している。FORTRAN では、最初の文字によって、計算機が型を暗黙 のうちに解釈するという、便利なような恐ろしいような約束事がある。一見便利 なようなルールだが、プログラムを書き直したり、長いプログラムを書く時等、 使う変数をきちんと把握している方が、結局は便利である事の方が多い。 Implicit NONEをプログラムの頭で宣言しておくと、 型宣言していない変数をプログラム中で引用していたら、計算機が警告してくれる。
型 | FORTRAN | 大きさ |
整数型 | Integer | |
Integer*4 | ||
実数型 | Real | (有効数字7桁) |
Real*8 | (有効数字15桁) | |
複素数型 | Complex | (有効数字7桁) |
Complex*16 | (有効数字15桁) | |
論理型 | Logical | .true.(真)或いは .false.(偽) |
Logical*2 | ||
文字型 | Character*サイズ | サイズ分の長さの文字列 |
二番目の例のParameter文は、変数PIの値を指定している。式として 書いても同じ事だが、物理定数等このParameter文を用いて宣言すると、 値を直す時等、場所が決まっているから、便利である。
DIMENSIONの宣言は、良く使うであろう。 等を変数として、 使いたい時がある。この様な時、
DIMENSION y(10)の様に宣言すると、y(1), ... , y(10) が使えるようになる。引数が 二次元ならば、
DIMENSION y(i,j)の様にすれば良い。iとjは、それより前の Parameter文でサイズを宣言して おけば良い。
Write(*,*) 'radius:',radius Write(*,*) ' surface area =',area,' volume =',volumeが、WRITE文である。'radius:'はradius:と表示させる事を意味し、 カンマに続くradiusは、変数radiusの値を表示させる事を意味している。
if (code.eq.1) then ... else ... end if或いは次の様な更に細かい条件分岐も出来る。
if (code.gt.1) then ... else if (code.eq.1) then ... else ... end if
y = 0.0 Do i=1,10 y = y + a(i) End doiが10以下である限り繰り返すといった場合には、次の様なDo whileが便 利だ。
i = 1 Do while (i.le.10) y = y + a(i) i = i + 1 End do
Program sphere2 Implicit NONE c constant: Real RADIUS_INITIAL,MAX_RADIUS,DELTA_R Parameter(RADIUS_INITIAL=1.0,MAX_RADIUS=10.0) Parameter(DELTA_R=2.0) c local variable: Real radius Real area, volume c begin: radius = RADIUS_INITIAL Do while (radius .le. MAX_RADIUS) Call calculation(radius, area, volume) Write(*,*) 'radius:', radius Write(*,*) ' area =',area,' volume =',volume Write(*,*) radius = radius + DELTA_R End do Stop End Subroutine calculation(radius, area, volume) Implicit NONE c input: Real radius c output: Real area, volume c constant: Real PI Parameter (PI=3.141593) c begin: area = 4. * PI * radius**2 volume = area * radius /3. Return Endメインプログラムでは、半径を与えるだけで、計算はサブルーチンcalculation で行っている。そしてメインプログラムとサブルーチンとの間のやり取りは、メイン プログラム中のcall文で行う。その際、引数(radius,area,volume)は、 radius がメインプログラムから与えられ、areaとvolumeは、サブ ルーチンから計算の結果として、メインプログラムに返される。 それぞれの引数の型は、メインプログラムとサブルーチンの間で必ず一致させなけれ ばならない。但し、引数の名前は両者の間で異なっていても構わない。 この例に見るように、引数はメインプログラムからサブルーチンにも渡せるし、 逆にサブルーチンからメインプログラムにも渡せる。どちらからどちらに渡されてい るかは、一見して明らかな訳ではないので、上のサブルーチンcalculationの 例のように、コメントで注釈を附けておくと、便利である。 また、サブルーチンから、別のサブルーチンを呼ぶことも出来る。 サブルーチンはReturnとEndで終わるのが約束である。
Program sphere3 Implicit NONE c constant: Real RADIUS_INITIAL,MAX_RADIUS,DELTA_R c local variable: Real radius Real area, volume c begin: Write(*,*) 'Input RADIUS_INITIAL:' Read(*,*) RADIUS_INITIAL Write(*,*) 'Input MAX_RADIUS:' Read(*,*) MAX_RADIUS Write(*,*) 'Input DELTA_R:' Read(*,*) DELTA_R radius = RADIUS_INITIAL Do while (radius .le. MAX_RADIUS) Call calculation(radius, area, volume) Write(*,*) 'radius:', radius Write(*,*) ' area =',area,' volume =',volume Write(*,*) radius = radius + DELTA_R End do Stop End
Read(*,*)が、端末から変数を読み込ませるときに用いる文である。
Program sphere4 Implicit NONE c constant: Real RADIUS_INITIAL,MAX_RADIUS,DELTA_R c local variable: Real radius Real area, volume c file open: Open(Unit=2,File='Input.dat',Status='OLD') Open(Unit=3,File='Output.dat',Status='NEW') c begin: Read(2,*) RADIUS_INITIAL,MAX_RADIUS,DELTA_R radius = RADIUS_INITIAL Do while (radius .le. MAX_RADIUS) Call calculation(radius, area, volume) Write(3,*) 'radius:', radius Write(3,*) ' area =',area,' volume =',volume Write(3,*) radius = radius + DELTA_R End do Stop End
(*,*)のところが(2,*)となったため、入力は2番の論理装置から行なわれ る。その2番の論理装置がInput.datという名前の既製のファイルである事を 最初のOpen文が記述している。 Write文が、(3,*)であるから、出力は 3番の論理装置に対してなされる。 二つ目のOpen文は、同様に3番の論理装置がInput.datという名前の の新規のファイルである事を記述している。
Program sphere5 Implicit NONE c constant Integer N Parameter(N=2000) c local variable: Real radius Real area, volume integer i c file open: Open(Unit=2,File='Input.dat',Status='OLD') Open(Unit=3,File='Output.dat',Status='NEW') c begin: Do i=1,N Read(2,*,end=900) radius Call calculation(radius, area, volume) Write(3,*) 'radius:',radius,' area =',area,' volume =',volume End do 900 Write(*,*) 'number of data=', i-1 Stop Endこのプログラムで、N以上読み込みデータがあると、number of data として正しくない答えNを表示する。
FORTRAN | 意味 | FORTRAN | 意味 |
sqrt(x) | exp(x) | ||
log(x) | log10(x) | ||
sin(x) | asin(x) | ||
cos(x) | acos(x) | ||
tan(x) | atan(x) | ||
sinh(x) | cosh(x) | ||
tanh(x) | abs(x) | の絶対値 | |
int(x) | の整数部 | float(n) | 整数を実数に変換 |
max(x,y,z,...) | の最大値 | min(x,y,z,...) | の最小値 |
混合演算をしないように、と書いたが、実数xを整数に型変換するには、 int(x)を使い、整数xを実数に型変換するには、float(x)を 使う。
real function S(r) implicit NONE c constant: real PI parameter (PI=3.141593) c local variable: real r c begin: S=4.*pi*r**2 return end real function V(r) implicit NONE c constant: real PI parameter (PI=3.141593) c local variable: real r c begin: V=4./3.*pi*r**3 return endで定義して、メインプログラムからは、
Program sphere6 Implicit NONE c constant: Real RADIUS_INITIAL,MAX_RADIUS,DELTA_R c local variable: Real radius Real area, volume, S, V c begin: Write(*,*) 'Input RADIUS_INITIAL:' Read(*,*) RADIUS_INITIAL Write(*,*) 'Input MAX_RADIUS:' Read(*,*) MAX_RADIUS Write(*,*) 'Input DELTA_R:' Read(*,*) DELTA_R radius = RADIUS_INITIAL Do while (radius .le. MAX_RADIUS) Write(*,*) 'radius:', radius area =S(radius) volume=V(radius) Write(*,*) ' area =',area,' volume =',volume Write(*,*) radius = radius + DELTA_R End do Stop Endのように、外部関数を使う。FUNCTION 文は、メインプログラムの後ろにつけて、コン パイルするのが良いだろう 。
浦 昭二: FORTRAN入門(3訂版)(培風館)
森口繁一:JIS FORTRAN入門(第3版)上・下 (東大出版会)