[English/日本語]

|次のページへ: 数値微分>

Lesson 0: Fortranの基礎について学ぼう

このページでは、Fortranを使ったプログラミングの基礎を学びます。具体的には、基本的なコードの書き方、コンパイルの方法、プログラムの実行方法に加え、数値計算の基礎となる四則演算やDOループ、IF文について学びます。

 最近では、プログラミングを効率的に学習するためにAIの支援を受けることも有用です。本サイトの解説記事「ChatGPTを活用したプログラミング学習効率化」も参考にしてください。


Lesson 0-1: コンパイルと実行

まず初めに、Fortranプログラムをコンピュータ上で実行するための基本的な手順について見てみましょう。Fortranのプログラムは次のような手順で実行することが出来ます。

  1. Fortran言語で.f90を拡張子に持つコードを書く。
  2. 準備したコードをコンパイルし、コンピュータが実行できる実行ファイルを作る。
  3. コンピュータ上で実行ファイルを実行する。

このFortranプログラム実行手順を学ぶために、ここでは"Hello world"プログラムと呼ばれる有名なプログラムのコードを書いて実行してみます。"Hello world"プログラムは、新しくプログラミングを学ぶときに用いられる典型的なプログラムで、最も有名なプログラムの一つです。(参考:Wikipedia)

1. Fortran言語で.f90を拡張子に持つコードを書く。

まず初めに、好きなエディター(Emacs, vim, メモ帳やサクラエディタなど)を使って、次のFortranコードを書き、ファイル名をlesson0_1.f90として保存してください

(lesson0_1.f90)

program main
	    
  write(*,*)"Hello world!!"

end program main

最初の行のprogram mainはプログラムの書き始めを示す文で、対となるend program mainという文までプログラムが上から順番に実行されていきます。ここで mainはプログラムの名前で、好きな名前を付けることが出来ます。簡単のため、ここではmainという名前を使っています。2行目のwrite(*,*)"Hello world!!"という文は"Hello world!!"という文字列を出力せよという命令文です。ここで使われているwriteは、様々な結果を出力する際に良く用いられる命令文です。

2. 準備したコードをコンパイルし、コンピュータが実行できる実行ファイルを作る。

上記のFortranコード (lesson0_1.f90) の準備が出来たら、次にこのコードをコンパイルし、コンピュータが実行できる実行ファイルを作ります。下記のコマンドを端末上で打ち込むことで、コンパイルを実行しコードから実行ファイルを作ることが出来ます:

gfortran lesson0_1.f90 -o hello

ここではgfortranコンパイラが利用されていますが、代わりに好きなコンパイラを使っても構いません。上記のコマンドにより、Fortranのソースファイル (lesson0_1.f90)がコンパイルされ、実行ファイル(hello)が作られます。実行ファイルの名前は、コンパイル時のオプション(-o)を使って指定することが出来、hello以外の好きな名前を使うことが出来ます。

3. コンピュータ上で実行ファイルを実行する。

上記の実行ファイル(hello)が準備できたら、次のその実行ファイルを、下記のコマンドを打ち込んで実行します:

./hello

その結果、端末上に次の文字列が出力されます:

Hello World!!

この出力結果は、上記のコードlesson0_1.f90の2行目の文write(*,*)"Hello world!!"によって出力されています。

ここで学んだFortranプログラミングについておさらいすると、次の3つのステップでFortranプログラムを実行することが出来ます: (i) Fortran言語で.f90の拡張子を持つコードを書く。 (ii) Fortranのソースコードをコンパイルし、実行ファイルを生成する。 (iii) 実行ファイルを実行し、結果を得る。これが一般的なFortranプログラミングのプロセスで、以降は、同様のプロセスを他のプログラム事例について繰り返し見ていきます。


Lesson 0-2: 基本的な演算(四則演算)

ほぼ全ての数値計算手法・コードは四則演算(和差積商)などの基礎的な数学演算の組み合わせによって実現されています。ここでは、このような基礎的な数学演算(四則演算、べき乗)について学びます。まず、次のサンプルプログラムを見てみましょう。

(lesson0_2.f90)

program main
  implicit none
  real(8) :: a,b,c,d,e,f,g

  a = 2.0d0
  b = 3.0d0

  write(*,*)"a=",a
  write(*,*)"b=",b

  c = a + b
  d = a - b
  e = a * b
  f = a / b
  g = a**b

  write(*,*)"a+b =",c
  write(*,*)"a-b =",d
  write(*,*)"a*b =",e
  write(*,*)"a/b =",f
  write(*,*)"a**b=",g

end program main

このプログラムでは、変数abに対して、四則演算(足し算、引き算、掛け算、割り算)に加えて、べき乗の計算を行っています。上記のLesson 0-1で見たのと同様に、このプログラムもprogram文から始まっており、end program文で終了しており、この二つの文で囲まれた範囲の命令が上から順番に実行されます。

このprogram文の次の行で、implicit none文を宣言しています。このimplicit none文を宣言すると、次に述べる暗黙の型宣言を無効化することが出来ます。暗黙の型宣言とは、Fortran言語の初期設定の変数型を利用するもので、変数名がi,j,k,lから始まる変数は整数型の変数として扱われ、それ以外の変数は実数型の変数として扱われます。この暗黙の型宣言を利用すると、プログラムに意図しないバグが入り込むリスクが増えるので、新たにプログラムを書くときは必ずimplicit none文を宣言し、この暗黙の型宣言を無効化するようにしておきましょう。

次に、implicit none文の下で、次のような文により変数(a-g)を定義しています:

real(8) :: a,b,c,d,e,f,g

ここで、変数の型がreal(8)によって定義されています。このreal(8)は倍精度実数と呼ばれる型で、おおよそ16桁の精度を持った実数として扱われます。上のプログラムの宣言文では、7つの変数(a,b,c,d,e,f,g)が倍精度実数型変数(real(8))として宣言されています。

この倍精度実数のほかにも、整数型integerや倍精度複素数complex(8)などの型を使うことが出来ます。

上記の変数の型宣言の後、次のようなコードを確認できます:

a = 2.0d0
b = 3.0d0

ここで, 2.0d0 は倍精度実数の数値, \(2.0\times 10^0\), を表しています。例えば、\(3.9\times 10^2\)という値の倍精度実数を使いたい場合、3.9d2と表現することが出来ます。上のコードでは、\(2.0\times 10^0\)という値を変数aに、\(3.0\times 10^0\)という値を変数bにそれぞれ代入しています。Fortran言語では、等号の記号(=)は等価性ではなく、代入操作の演算子として用いられます。

プログラム8,9行目では、変数a,bに代入した数値を画面に出力しています:

write(*,*)"a=",a
write(*,*)"b=",b

ここでは、write文を用いて変数の出力を行っています。このwrite文は上のLesson 0-1でも用いられています。上記の、Hello worldプログラムの例とは異なり、本例題では文字変数実数変数の出力が行われています。Fortranでは、文字列を表すために、ダブルクォーテーション(")で文字列を囲って表現することが出来ます。例えば上のコード(lesson0_2.f90)の例では、文字列a=は、コード内で"a="と表されています。この表現方法は、上記のHello worldプログラムでも使用されていました。本例題では、文字変数に加えて倍精度実数変数であるabも出力しています。

次に、実際に計算を行っている部分のコードについて見てみましょう。上のプログラムの11行目から15行目では、変数a,bを用いて四則演算やべき乗の計算を行っています。

c = a + b
d = a - b
e = a * b
f = a / b
g = a**b

ここでは、倍精度実数変数に対して基本的な数学演算が行われており、その計算結果を倍精度実数変数であるc,d,e,f,gに代入しています。Fortran言語では、+記号は加算(足し算)を表し、-記号は減算(引き算)を表し、*記号は乗算(掛け算)を表し、/記号は除算(割り算)を表します。また、**記号はべき乗を表します。これらの演算を行った後に、本例題ではwrite文を使ってその結果を出力しています。

次に、プログラムをコンパイルし実行してみましょう。コンパイルを行うために、ターミナル上で次のコマンドを実行してみます::

gfortran lesson0_2.f90 -o lesson0_2

また、コンパイルが終了した後、実行ファイルを次のように実行してみます。

./lesson0_2

すると、次のような計算結果が画面に出力されるはずです:

a=   2.0000000000000000
b=   3.0000000000000000
a+b =   5.0000000000000000
a-b =  -1.0000000000000000
a*b =   6.0000000000000000
a/b =  0.66666666666666663
a**b=   8.0000000000000000

これらの結果は、あなたが予測したものと一致しているでしょうか?また、上記のプログラムで倍精度実数変数abに代入する数を変えて、結果がどう変わるかを試してみましょう。


Lesson 0-3: 反復処理 (Doループ)

多くの数値計算法において、決められた手続きを繰り返し反復で実行することが必要となることがしばしばあります。Fortran言語では、そのような反復処理を行うためにdoループと呼ばれる機能が実装されています。本節では、このdoループの使い方について学んでいきます。

ここでは、doループを学ぶための例題として、\(1\)から\(10\)までの整数の和を計算するプログラムを考えます。この問題の答えは、次のような簡単な公式で求めることが出来ます: \[ S=1+2+3+\cdots+n = \frac{1}{2}n(n+1). \tag{1} \] この整数の和を、doループを使ったプログラムによって数値的に求めるために、次のようなプログラムを考えてみましょう。

(lesson0_3.f90)

program main
  implicit none
  integer :: i, n, sum

  n = 10
  sum = 0
  do i = 1, n
     sum = sum + i
  end do

  write(*,*)"calculated sum =",sum
  write(*,*)"expected   sum =",n*(n+1)/2
  
end program main

上のコードではまず3行目で、整数型変数i, n, sumを次のような文で定義しています:

integer :: i, n, sum

次に、コードの5行目で、1からいくつまでの整数の和を計算するかを表す整数nを与えています。ここでは、n10と設定しています。

さらに、6行目では和を計算した値を格納する変数sumに対し、sum=0によってゼロの値を入れることで初期化しています。変数は、宣言文で宣言されただけだと再現性のないランダムな値を持っていることがあります。したがって、必要に応じて、明示的にゼロ等の値を代入することで変数の初期化を行う必要があります。

次に7行目から、doループのブロックに移ります。doループのブロックはdo文から始まりend do文で終わります。doループは、doブロックの中にある手続きを繰り返し行います。コードで示されているように、do文は整数変数と一緒に用いられます:

do i = 1, n

ここで, iは整数型変数であり、doループの反復回数を制御するために用いられるループカウンターと呼ばれます。この行では、ループカウンターである整数iをまず1に初期化しています。do文とend do文に囲まれたdoブロック内の手続きが切り返し行われ、繰り返しのたびにループカウンターiが1ずつ増加していきます(i=i+1)。このループカウンターinを超えるまでdoブロックの手続きが繰り返され、inを超えた時点でdoループが修了します。上のプログラムでは、ループカウンターi1からnまで増加し、その間、整数型変数であるsumにループカウンターの値iが足し上げられていきます。ここでsum = sum + iは、もともとのsumの値にiを足したものを新たなsumの値に代入することを表しています。

それでは、上のプログラム(lesson0_3.f90)をコンパイルし実行してみましょう。次のような結果が得られるはずです。

 calculated sum =          55
 expected   sum =          55

ここで、calculated sumは上記のプログラムによって1から10までの数値を足した値が示されていますが、expected sumは上記の公式(\(1\))によって計算された値が示されています。したがって、ここではプログラムによって計算された和が正しく数学的に導かれた公式の値を再現していることが確認できます。


Lesson 0-4: 条件分岐 (IF文)

数値計算を実行する際に、与えられた条件ごとに異なる処理が必要となる場合があります。そのような場合にはif文を利用して、条件分岐を行うことが出来ます。このようなif文の機能を理解するために、次のFortranコードを見てみましょう。

(lesson0_4.f90)

program main
  implicit none
  real(8) :: a, b

  a = 2d0
  b = 3d0

  write(*,*)"a=",a
  write(*,*)"b=",b

  if(a == b)then
     write(*,*)"a==b"
  else if(a > b)then
     write(*,*)"a>b"
  else
     write(*,*)"a<b"
  end if

end program main

上記のプログラムでは、11行目のif(a == b)then文によってabが等しいかの判定を行い、abが等しい場合は、その下のwrite(*,*)"a==b"によって、"a==b"という文字列を画面に表示します。この場合、if文の他の処理は行われず、end if文まで移動して条件分岐の処理を終えます。

最初の条件文if(a == b)thenで与えられた条件に当てはまらなかった場合、次の条件文へと移動します。上のコードでは、else if(a > b)thenによってabよりも大きいかどうかの判定をおこなっており、abよりも大きい場合は、write(*,*)"a>b"文によって"a>b"という文字列を出力を行い、end if文まで移動します。このようにelse if (条件式) thenを用いることで、何重にも条件判定を行うことが出来ます。

ここまでの説明では、判定条件に合致した場合に処理が行われるものについて説明してきましたが、条件に当てはまらなかった場合の処理(例外処理)もプログラミングでは重要となります。上記のプログラムでは、if(a == b)then文やelse if(a > b)then文の後にelse文が続いていします。このelse文は、ここにたどり着くまでの条件判定でどれにも当てはまらなかった場合に行われる処理を記述します。上記のプログラムの例では、それまでの条件判定でabが等しくなく、さらにabよりも大きくないことも分かっているので、abよりも小さいことを表す"a<b"を画面に出力してif文の処理を終えています。

if文には様々な条件式を使うことが出来ますが、多くの場合は下記のような条件を知っていればプログラムを書くことが出来ます。

  1. a==b: abが等しい。
  2. a>b: abより大きい。
  3. a<b: abより小さい。
  4. a>=b: abより大きい、または等しい。
  5. a<=b: abより小さい、または等しい。
  6. a/=b: abが等しくない。


このページではFortranプログラミングの基礎について学びました。次のページではFortranを用いた数値微分について学びます。
Fortranで数値微分



|次のページへ: 数値微分>

[Fortranホームへ戻る]