Fortran プログラミング (その3)


今日の内容

今日は Fortran の3回目(最終回)です。 今日は配列型の変数と処理の流れの判断及び分岐を中心に勉強します。

Fortran は教科書には記載されていません。練習問題のサンプルプログラムとその解説が教科書代わりです。これらを熟読すれば提出課題はできます。必ずよく読んで実行し、理解するようにしなさい。また以下のサイトが参考になるので、必要に応じて参照しなさい。


今日の演習

練習問題1

以下のサンプルプログラムはフィボナッチ数列の第1項から第20項までを出力するプログラムである。これを参考にして、配列型変数の用法を理解しなさい。

※フィボナッチ数列: a1 = 1, a2 = 1, an+2 = an+1 + an で表される数列。

01から18までの行番号がついている行がプログラム(ソースコード)である。 行番号および桁目盛は説明と見やすさを考慮してつけているので入力する必要はない。枠線で囲まれている部分の中だけを入力すること。

   123456789....
  +-----+--------------------------------
01|C     Fibonacci number 1 to 20
02|C
03|      IMPLICIT NONE
04|      INTEGER :: a(20)
05|      INTEGER :: i
06|C
07|      a(1)=1
08|      a(2)=1
09|      DO i=3, 20
10|       a(i)=a(i-1)+a(i-2)
11|      END DO
12|C
13|      DO i=1, 20
14|       WRITE(*,*) a(i)
15|      END DO
16|C
17|      STOP
18|      END

プログラムの説明

  1-2: 1桁目が C で始まる行はコメント行。

   3: 暗黙の型宣言の使用を無効にする。

   4: 整数型の1次元配列型変数 a を宣言する。
       この形式で、a(1) から a(20) までの20個の整数型変数が定義される。
       利用するときは、a(5) や a(i) 等として指定する。

       ※同じ型の大量のデータ系列を利用するときは、添字付の変数が便利である。
         添字付の変数を扱うには配列型変数を用いる。
         配列型変数を用いるためには、データの型、大きさ、添字の次元数を宣言する。

    5: 整数型変数 i(DOループの制御変数用)を宣言する。

  7-8: 変数 a(1), a(2) に値を代入。
 9-11: DOループを用いて逐次 a(3), a(4), a(5), ... , a(20) に値を代入。

13-15: DOループを用いて a(1), a(2), ... , a(20) を出力。

   17: 処理を終了する (STOP)。
   18: プログラムの終わりを示す (END)。

練習問題2

以下のサンプルプログラムは2つの3×3正方行列を入力し、その和を出力するプログラムである。これを入力し、適当な行列の和を計算せよ。

01から32までの行番号がついている行が入力するプログラム(ソースコード)である。 行番号および桁目盛は説明と見やすさを考慮してつけているので入力する必要はない。枠線で囲まれている部分の中だけを入力すること。

   123456789...
--+-----+--------------------------------------------------
01|C     sum of two 3-by-3 matrices
02|C
03|      IMPLICIT NONE
04|      REAL :: a(1:3,1:3), b(1:3,1:3), ans(1:3,1:3)
05|      INTEGER :: i, j
06|C
07|      WRITE(*,*) 'Input Matrix A,'
08|      DO i=1, 3
09|       DO j=1, 3
10|        WRITE(*,*) 'element', i , j, '?'
11|        READ(*,*) a(i,j)
12|       END DO
13|      END DO
14|C
15|      WRITE(*,*) 'Input Matrix B,'
16|      DO i=1, 3
17|       DO j=1, 3
18|        WRITE(*,*) 'element', i , j, '?'
19|        READ(*,*) b(i,j)
20|       END DO
21|      END DO
22|C
23|      WRITE(*,*) 'Sum of Matrices A and B is'
24|      DO i=1, 3
25|       DO j=1, 3
26|        ans(i,j)=a(i,j)+b(i,j) 
27|       END DO
28|       WRITE(*,*) ans(i,1), ans(i,2), ans(i,3)
29|      END DO
30|C
31|      STOP
32|      END

プログラムの説明

  1-2: 1桁目が C で始まる行はコメント行。

   3: 暗黙の型宣言の使用を無効にする。

   4: 実数型の2次元配列型変数 a, b, ans を宣言する。
       この形式で、a(1,1), a(1,2), a(1,3), a(2,1), ... , a(3,3) までの
       9個の実数型変数がそれぞれ定義される。
       利用するときは、a(2,2) や b(i,j) 等として指定する。

    5: 整数型変数 i, j(DOループの制御変数用)を宣言する。

    7: 行列A の入力を促す文を表示。
 8-13: DOループを用いて、2次元配列に値を入力。
       DOループが入れ子構造になっていることに注意!

15-21: 行列B についても上と同様に入力。

   23: 結果を表示する旨を出力。
24-29: DOループを用いて、行列の和を計算および結果出力。
 (26): それぞれの要素を計算。
 (28): ここで、1行分をまとめて表示する。

   31: 処理を終了する (STOP)。
   32: プログラムの終わりを示す (END)。

練習問題3

以下のサンプルプログラムは2次方程式 ax2+bx+c=0 の解の判別を行うプログラムである(ただし aは0でないとする)。これを入力し、実行させなさい。

01から30までの行番号がついている行が入力するプログラム(ソースコード)である。 行番号および桁目盛は説明と見やすさを考慮してつけているので入力する必要はない。枠線で囲まれている部分の中だけを入力すること。

プログラムの説明

  1-6: 1桁目が C で始まる行はコメント行。
       プログラムのはじめにコメント行を用いて、プログラムの内容、
       作者、日付などを記載しておくとよい。
       (プログラムも立派な著作物です。)

7,17,20: コメント行を用いたプログラム構造のメモ書き。

   8: 暗黙の型宣言の使用を無効にする。
   9: 4つの実数型変数 a,b,c,d を宣言する。
       必要ならコメント記号を用いて、変数などのメモをしておくとよい。

   11: 変数 a,b,c の値を標準入力(通常は端末)から読み込む。

12-15: 今日のポイント:IF 文

      ブロックIF 文の文法は、

      IF (条件式) THEN
        実行文 A(条件式が真のときに実行される)
      ELSE 
        実行文 B(条件式が偽のときに実行される)
      END IF

      となる。ただし、条件式が偽のときに実行する必要がないときは、
      ELSE と実行文 B は省略できる。

      主な条件式には次のようなものがある。

       (変数あるいは値) == (変数あるいは値)     (等しい)
                        /=                      (等しくない)     
                        >                       (より大きい)
                        >=                      (等しいか大きい)
                        <                       (小さい)
                        <=                      (等しいか小さい)
                 (条件) AND (条件)              (ともに正しい)
                        OR                      (どちらかが正しい)

      したがって、ここでは、
      もし(if) a が 0.0 に等しいならば、2次方程式にならないので
   「Not a quadratic equation!」(2次方程式でない)と出力して、
      プログラムを停止(STOP)する。
      
      補遺:実行文が1行で書けて、条件式が偽のとき実行する必要のない
            ときは、単純IF 文といって、次のように書くこともできる。
               IF (条件式) 実行文

   18: 判別式の値を計算し d に代入する。

21-27: ブロックIF 文による場合分け。

      IF (条件式) THEN
        複数の実行文
      ELSE IF (条件式) THEN
        複数の実行文
      ELSE
        複数の実行文
      END IF

      # 条件式を判定し、満たしていれば THEN 以降(ブロック)を実行し、
      # 満たさなければ次の条件式 (ELSE IF) を判定する。
      ブロック内には複数の文が書ける。ELSE IF や ELSE はなくてもよいが、
      END IF は必ず必要。

17,19,21: 結果を出力する。
      文字列は半角のシングルクォーテーション(')で囲む。

  29: 処理を終了する (STOP)。
  30: プログラムの終わりを示す (END)。

今日の提出課題

練習問題を踏まえて以下のプログラムを作成せよ。 プログラム、コンパイルのコマンドとシステムからのメッセージおよび実行結果を印刷して提出せよ。
(問題) 3つの実数 a,b,c を読み込んで、2次方程式 ax2+bx+c=0 の解を求めるプログラムを作成しなさい。 ただし、以下の指示を満たすこと。
  1. a=0 の場合は2次方程式にならないので、入力を再度促す。
  2. aが0でない場合は、判別式 D=b2-4ac を用いて、
    1. 虚数解の場合は”No real roots”と表示する。
    2. 重解の場合は解を一つだけ表示する。
    3. 2つの実数解が存在する場合には両方を表示する。

      この際に、以下に注意すること。

      • 実数 D の平方根は sqrt関数を用いて sqrt(D) で計算できる。
      • b>0およびb=0 の場合は x = (-b-SQRT(D))/(2.0*a) によって一方の解を求め、もう一方の解は解と係数の関係から求める。
      • b<0 の場合は x = (-b+SQRT(D))/(2.0*a) によって一方の解を求め、もう一方の解は解と係数の関係から求める。>

        なぜこのようにするのか考えて見よう。

  3. 答えの表示の方法を工夫してみよう。
    例えば、write(*,*) 'x =',x1,' and',x2 とすると
    x = 3.54800 and -2.74400 など
    と表示されます。
プログラムを用いて、以下の2次方程式の解を求めよ。
  (1) 2x2 + 4x + 3 =0
  (2) 6x2 + 9x + 1 =0
  (3) 3x2 + 4x - 5 =0

プリンタ出力の提出をもって出席とします。したがって、途中までしかできていない場合でも、プリンタに出力して提出しなさい。出力できない者は口頭で申し出ること。その場合、来週の演習時間までに完成させて演習開始時に提出すること。


おまけ

課題が終わってしまって時間に余裕がある人は、トライしよう。 提出する際は、必ず氏名と学生番号を明記して課題とは別紙にしなさい。(1つだけでも、両方でもよい。)期限は次回の演習が終わるまで。

BMI法は国際的に通じる信用できる肥満判定の尺度として近年広まってきています。BMIとは(Body Mass Index)の略で体重(kg)を身長(m)の2乗で割った指数です。 男女を問わず、この指数で22が適正体重とされ、統計的に病気にかかりにくいのだそうです。
身長、体重を入力するとBMIと適正体重を計算し表示するとともに、BMIが19.9未満ならば「やせすぎ」、それ以上23.9未満ならば「適正」、それ以上26.3未満で「太り気味」、それ以上ならば「肥満」と表示するプログラムを作成せよ。そのプログラムを用いて、BMIを計算せよ。なお、入力する身長体重は自分のものでもよいし親兄弟友人他人、架空の人物のものでもよい。
2つの3×3正方行列を入力すると、その積を出力するプログラムを作成せよ。また、そのプログラムを用いて、適当な行列の積を計算せよ。(入力した行列も、行列形式で出力させなさい。)

戻る