Fortran90(行列の積)

旧2-5. Fortran毎日学習
スポンサーリンク

行列の和

行列計算します。まずは行列の和から。
配列代入を使えば簡単です。

takk@deb9:~$ cat matrix-sum.f90
      program main
        integer a(2,2),b(2,2),c(2,2)
        data a /1,2, 3,4/
        data b /10,20, 30,40/

        write(*,*) 'a='
        write(*,*) (a(1,i),i=1,2)
        write(*,*) (a(2,i),i=1,2)

        write(*,*) 'b='
        write(*,*) (b(1,i),i=1,2)
        write(*,*) (b(2,i),i=1,2)

        c = a + b

        write(*,*) 'c=a+b'
        write(*,*) (c(1,i),i=1,2)
        write(*,*) (c(2,i),i=1,2)

        stop
      end
takk@deb9:~$

行列の差

引き算も同じ要領です。

takk@deb9:~$ cat matrix-sub.f90
      program main
        integer a(2,2),b(2,2),c(2,2)
        data a /11,22, 33,44/
        data b /10,20, 30,40/

        write(*,*) 'a='
        write(*,*) (a(1,i),i=1,2)
        write(*,*) (a(2,i),i=1,2)

        write(*,*) 'b='
        write(*,*) (b(1,i),i=1,2)
        write(*,*) (b(2,i),i=1,2)
        c = a - b

        write(*,*) 'c=a-b'
        write(*,*) (c(1,i),i=1,2)
        write(*,*) (c(2,i),i=1,2)

        stop
      end
takk@deb9:~$ gfortran matrix-sub.f90
takk@deb9:~$ ./a.out
 a=
          11          33
          22          44
 b=
          10          30
          20          40
 c=a-b
           1           3
           2           4
takk@deb9:~$

行列の積

では積はどうでしょう。a * bだけで済むのでしょうか。

takk@deb9:~$ cat matrix-mul.f90
      program main
        integer a(2,2),b(2,2),c(2,2)
        data a /1,2, 3,4/
        data b /10,20, 30,40/

        write(*,*) 'a='
        write(*,*) (a(1,i),i=1,2)
        write(*,*) (a(2,i),i=1,2)

        write(*,*) 'b='
        write(*,*) (b(1,i),i=1,2)
        write(*,*) (b(2,i),i=1,2)
        c = a * b

        write(*,*) 'c=a*b'
        write(*,*) (c(1,i),i=1,2)
        write(*,*) (c(2,i),i=1,2)

        stop
      end
takk@deb9:~$ gfortran matrix-mul.f90
takk@deb9:~$ ./a.out
 a=
           1           3
           2           4
 b=
          10          30
          20          40
 c=a*b
          10          90
          40         160
takk@deb9:~$

配列の要素どうしの積になってしまいました。
このような計算をしてほしかったのですが、配列代入だけではできないようです。
\[
\left(
\begin{array}{cc}
a1 & a2 \\
a3 & a4
\end{array}
\right)
\times \left(
\begin{array}{cc}
b1 & b2 \\
b3 & b4
\end{array}
\right)
= \left(
\begin{array}{cc}
a1 \times b1 + a2 \times b3 & a1 \times b2 + a2 \times b4 \\
a3 \times b1 + a4 \times b3 & a3 \times b2 + a4 \times b4
\end{array}
\right)
\]

行列の積

前回は行列の内積になってしまったので、通常の積をしてみます。この式でしたね。
\[
\left(
\begin{array}{cc}
a11 & a12 \\
a21 & a22
\end{array}
\right)
\times \left(
\begin{array}{cc}
b11 & b12 \\
b21 & b22
\end{array}
\right)
= \left(
\begin{array}{cc}
a11 \times b11 + a12 \times b21 & a11 \times b12 + a12 \times b22 \\
a21 \times b11 + a22 \times b21 & a21 \times b12 + a22 \times b22
\end{array}
\right)
\]
式をそのままプログラムしてみます。

takk@deb9:~$ cat matrix-mul.f90
      program main
        integer a(2,2),b(2,2),c(2,2)
        data a /1,2, 3,4/
        data b /10,20, 30,40/

        write(*,*) 'a='
        write(*,*) (a(1,i),i=1,2)
        write(*,*) (a(2,i),i=1,2)

        write(*,*) 'b='
        write(*,*) (b(1,i),i=1,2)
        write(*,*) (b(2,i),i=1,2)

        c(1,1) = a(1,1) * b(1,1) + a(1,2) * b(2,1)
        c(1,2) = a(1,1) * b(1,2) + a(1,2) * b(2,2)
        c(2,1) = a(2,1) * b(1,1) + a(2,2) * b(2,1)
        c(2,2) = a(2,1) * b(1,2) + a(2,2) * b(2,2)

        write(*,*) 'c=a*b'
        write(*,*) (c(1,i),i=1,2)
        write(*,*) (c(2,i),i=1,2)

        stop
      end
takk@deb9:~$

実行すると、

takk@deb9:~$ gfortran matrix-mul.f90
takk@deb9:~$ ./a.out
 a=
           1           3
           2           4
 b=
          10          30
          20          40
 c=a*b
          70         150
         100         220
takk@deb9:~$

行列の積をするmatmulという組み込み関数があるらしいので、使ってみます。

takk@deb9:~$ cat matrix-mul2.f90
      program main
        integer a(2,2),b(2,2),c(2,2)
        data a /1,2, 3,4/
        data b /10,20, 30,40/

        write(*,*) 'a='
        write(*,*) (a(1,i),i=1,2)
        write(*,*) (a(2,i),i=1,2)

        write(*,*) 'b='
        write(*,*) (b(1,i),i=1,2)
        write(*,*) (b(2,i),i=1,2)

        c = matmul(a,b)

        write(*,*) 'c=a*b'
        write(*,*) (c(1,i),i=1,2)
        write(*,*) (c(2,i),i=1,2)

        stop
      end
takk@deb9:~$

実行すると、

takk@deb9:~$ gfortran matrix-mul2.f90
takk@deb9:~$ ./a.out
 a=
           1           3
           2           4
 b=
          10          30
          20          40
 c=a*b
          70         150
         100         220
takk@deb9:~$

c=a*bの答えが同じになりました。

コメント

タイトルとURLをコピーしました