数値解析法及び演習 第五回

行列の掛け算とサブルーチン
  1. 今日の目標
  2. 二次元データの入出力
  3. 行列の掛け算
  4. サブルーチン
  5. 今日の宿題

[1] 今日の目標

  1. 二次元データを読む
  2. 行列の掛け算を行なう
  3. サブルーチンを使う

[2] 二次元データの入出力

[2.0]配列にデータを格納

1.D0
2.D0
3.D0
4.D0
5.D0

と縦に並んだデータをファイル(retsu.datとする)から読み, 配列a(5)に格納するプログラム例:

       implicit none 
       integer i
       real*8 a(5)
       open(1,file='retsu.dat')
       do i=1,5
         read(1,*) a(i)
	 write(6,*) a(i)
       enddo
       end
1.D0 2.D0 3.D0 4.D0 5.D0

と横に並んだデータをファイル(gyou.datとする)から読み, 配列a(5)に格納するプログラム例:

      implicit none 
      real*8 a(5)
      integer i

      open(1,FILE='gyou.dat')
      read(1,*) (a(i),i=1,5)
      write(6,*) (a(i),i=1,5)
      end

[2.1]二次元配列

配列の要素を指定する番号は複数あってもよい. 二つになると二次元配列となり, 三つになると三次元配列となる. FORTRANでは7次元の配列まで使用可能である.

二次元配列の宣言:
宣言文 配列名(寸法の下限:寸法の上限, 寸法の下限:寸法の上限)



例1
real*8 a(10,10) 

a(1,1)からa(10,10)まで要素を100個持つ倍精度実数型二次元配列を宣言



例2
integer i(2,-1:8)

i(1,-1)からi(2,8)まで要素を20個もつ実数型二次元配列を宣言

[2.2]二次元データの読み取り

以下の数値をファイル matrix.dat にコピーし, それぞれの数値を二次元配列a(2,3)に格納するプログラムを作成せよ. 確認のため画面に値を表示させること.

1.D0 2.D0 3.D0
4.D0 5.D0 6.D0

[3] 行列の掛け算

[3.1]行列を取り扱う際のポイント

二次元配列を使ったプログラム例:
      integer a(5,5),b(5,5),c(5,5),n
      
      n=0

      do i=1,5
         do j=1,5

            n=n+1

            a(i,j)=0
            b(i,j)=n

         enddo
      enddo

      do i=1,5
         do j=1,5
            c(i,j)=b(i,j)
         enddo
      enddo

      do i=1,5
         write(*,*) (a(i,j),j=1,5)
      enddo

      do i=1,5
         write(*,*) (b(i,j),j=1,5)
      enddo

      do i=1,5
         write(*,*) (c(i,j),j=1,5)
      enddo




      end

[3.2]行列の掛け算

hai1.dat
2.D0 3.D0 4.D0         
5.D0 6.D0 7.D0        
8.D0 9.D0 10.D0       
hai2.dat
1.D0 2.D0 3.D0 
4.D0 5.D0 6.D0
2.D0 4.D0 6.D0 
上の二つの3行3列の行列をそれぞれ hai1.dat,hai2.dat とする.
  1. ファイルから数値を読み込み,それぞれ配列a(3,3),b(3,3)に値を格納しなさい.
  2. それぞれの行列の対角和を求めなさい.
  3. この行列の掛け算を行い,結果を画面に出力するプログラムをつくりなさい.

[4] サブルーチン

プログラム中で同じ処理を何度も行いたい場合がよくある.そのたびごとに同 じプログラムを何度も書くのは馬鹿げている.同じ処理はサブルーチンとして 外部手続きとしておくと都合がよい.

サブルーチンを呼び出す側のプログラムは「主プログラム(main program)」と呼ばれる.サブルーチンは主プログラムのend文以降に,主プログラムと独立に次のように書く. subroutine文以下endまでがサブルーチンである.

c      main program
       implicit none
       real*8 d(10),f,g
       ......

       call S(f,g,d)

       ......
       end


       subroutine S(a,b,c)
       implicit none
       real*8 a,b,c(10)
       ......
       ......
       return
       end

サブルーチン文 S(a,b,c) サブルーチンの定義をおこなう
S サブルーチン名:英文字で始まる6文字以内の英数字
a,b,c 仮引数:使う変数は型宣言すること

call 文 call S(f,g,d) サブルーチンを呼び出す
f,g,d 実引数:仮引数と順序, 型を一致させる必要あり

サブルーチンはend文で終わらなければならない.サブルーチンから主プログラムに戻る場所では

       return
を書く.return文は何個あってもよい(endは一個:end文のみでreturn文がない場合はendで呼ばれた場所に戻る).それでは次のプログラム を入力して実行してみよう.

プログラム1
c     main program
      implicit none
      real*8 a,b,c

      a=1.D0
      b=2.D0
      call wa(a,b,c)
      write(6,*) c     
      end

c     subroutine

      subroutine wa(a,b,c)
      implicit none

      real*8 a,b,c

      c=a+b

      return
      end

呼ぶ方(call wa(a,b))と呼ばれる方(subroutine wa(a,b))の引数は順序,個数,型を一致させなければならない.逆に言うと,引数の個数,型が一致していれば名前は違っていてもよい.サブルーチンを使う場合は, サブルーチンとの変数, 配列のやりとりに注意すること.どれが入力でどれが出力かを頭にいれてプログラムを作成すること. 次のプログラムは何をするのか考えてみよう.

プログラム2
c     main program
      implicit none

      real*8 a,b,c,d,e

      a=1.D0
      b=2.D0
      d=3.D0
      e=4.D0
      call wa(a,b,c)
      write(6,*) c
      call wa(d,e,c)
      write(6,*) c
      
      end

      subroutine wa(a,b,c)
      implicit none
      real*8 a,b,c
      c=a+b
 
      return
      end


練習問題1

以下のプログラムを正しく修正せよ.
c     1-1
      implicit none
      real*8 a,b

      a=1.D0
      b=2.D0
      call wa(a,b)
      write(6,*) b
      
      end

      subroutine wa(a,b,c)
      implicit none
      real*8 a,b
      b=a+b
 
      return
      end

c     1-2
      implicit none
      real*8 a,b

      a=1.D0
      b=2.D0
      call wa(a,b)
      write(6,*) b
      
      end

      subroutine wa(a,b)
      implicit none
      integer a,b
      b=a+b
 
      return
      end

c     1-3
      implicit none
      real*8 a(2),b

      a(1)=1.D0
      a(2)=2.D0
      b=0.D0
      call wa(a,b)
      write(6,*) b
      
      end

      subroutine wa(a,b)
      implicit none
      real*8 a,b
      b=a(1)+a(2)
 
      return
      end

練習問題2

プログラム1-2を修正し, 二つの数の積を計算するサブルーチンを書き加えよ. これを用いて変数a,bの積(答えは2.D0)を算出せよ.

練習問題3

  1. n!を計算するサブルーチン subroutine fact(n,ans)(ansは答えの整数)を作成せよ.
  2. n個のものからm個のものを取り出す組み合わせの数 nCmを計算するサブルーチン subroutine comb(n,m,ans) を作成せよ.
  3. 二項定理によると,f=(x+y)**nは
    (x+y)**n=ΣnCm x**(n-m)y**m
    となる.nCmを求めるサブルーチンを用いてfを計算するプログラムを作成せよ.x=0.3,y=0.7,n=10として実行し,結果が1.0になることを確かめよ.

[5] 今日の宿題

練習問題3のプログラム, 答えを送ること. 〆切は11/13.


日程表へ戻る <<