数値計算講義 第6 回
行列の計算 (1) – ガウ スの消去法 – 2 次元配列の取り 扱い
カ ーネン コ
金 子
ア レ ク セイ晃
[email protected] [email protected]
http://www.kanenko.com/
巨大行列の計算は数値計算の大部分を 占める 1 巨大行列は微分方程式の離散化によ り 生ずる 例: 2 階線型常微分方程式の境界値問題
− d
2u
dx
2+ q(x)u = f on [a, b],
u(a) = u(b) = 0 a x
i−1x x
i i+1b
区間 [a, b] を N 等分し , h = b − a
N , x
i= a + hi, i = 0, 1, 2, . . . , N と 置く . 分点での値に u
i= u(x
i), q
i= q(x
i), f
i= f (x
i) と いう 記号を 用いる . 各点 x
iにおける 2 階微分を 2 階の中心差分で置き 換え る と ,
(
− u
i−1+ u
i+1− 2u
ih
2+ q
iu
i= f
i, i = 1, 2, . . . , N − 1, u
0= u
N= 0
こ れは未知数 u
iに関する 次のよ う な連立一次方程式と なる .
2
h2
+
q1−
h120 · · · 0
−
h12 h22+
q2−
h12. .. .. .
0 . .. . .. . .. 0
.. . . .. −
h12 h22+
qN−2−
h120 · · · 0 −
h12 h22+
qN−1
u
1u
2.. . u
N−2u
N−1
=
f
1f
2.. . f
N−2f
N−1
行列のプロ グラ ミ ン グ 2
ベク ト ルは1 次元配列である . こ れは簡単.
行列は2 次元配列である . FORTRAN では
DOUBLE PRECISION A(5,5) , X(5), Y(5) こ れは次と 同じ
IMPLICIT DOUBLE PRECISION (A-H,O-Z) DIMENSION A(5,5), X(5), Y(5)
C では
double a[5][5], x[5], y[5];
行列と ベク ト ルの掛け算 Y=AX は
DO 200 I=1,5 ! 外側のループで各成分につき 計算
Y(I)=0 ! 内側のループは級数の和の要領で
DO 100 J=1,5
Y(I)=Y(I)+A(I,J)*X(J) 100 CONTINUE
200 CONTINUE
FORTRAN では X(5) と 宣言する と X(1) ∼ X(5) が使え る が,
C では x[5] と 宣言し たと き に使え る のは x[0] ∼ x[4] と なる .
y
1y
2y
3y
4y
5
=
a
11a
12a
13a
14a
15a
21a
22a
23a
24a
25a
31a
32a
33a
34a
35a
41a
42a
43a
44a
45a
51a
52a
53a
54a
55
x
1x
2x
3x
4x
5
行列のメ モリ ーイ メ ージ 3
( 実験プロ グラ ム num6-1.f, num6-1.c)
2 次元配列と 言え ど も メ モリ ーの中ではリ ニアに並んでいる . し かし , FORTRAN と C では並び方に重大な差が生ずる .
−
FORTRAN で
DOUBLE PRECISION A(3,5) と 宣言し たと き は
A(1,1) A(2,1) A(3,1) A(1,2) A(2,2) A(3,2) A(1,3) A(2,3) ...
C で
double A[3][5];
と 宣言し たと き は
A[0][0] A[0][1] ... A[0][4] A[1][0] ... A[1][4] A[2][0] ...
並び方の違いは普通は気にし なく て よ いが, アク セススピード に関係する . ( 本日の課題 6-1 参照. )
ま た , 大き めに取っ た2 次元配列の一部だけを 使う と き は特に注意が必要.
配列の扱いに関する 注意 – 1 4
添え 字の範囲: C では 0 から サイ ズ −1 ま での範囲と なる . FORTRAN ではデフ ォ ールト で 1 から サイ ズま での範囲と なる が,
A(-1:1,0:4)
と 宣言すれば, 同じ 寸法で添字の範囲を −1 ≤ i ≤ 1, 0 ≤ j ≤ 4 にずら せる . 初期化: C では全要素に 0 がセッ ト さ れる が,
FORTRAN は必ず自分でク リ アする 必要がある .
配列名を 引数にする と , C 言語でも 参照渡し と なり , サブルーチン で引数の行列の基本変形など を する と ,
呼び出し たプロ グラ ムでその行列の内容が壊さ れる . 必要なら バッ ク アッ プを . メ イ ン と サブで配列の寸法が合っ て いないと 悲劇が起こ る .
main で
INTEGER A(3,4) を 宣言し , 0 に初期化し た後 CALL SUB(A) を する
sub で
INTEGER A(2,2) を 宣言し
A(1,1)=11; A(2,1)=21; A(1,2)=12; A(2,2)=22 と セッ ト
し たと き , メ イ ン に戻っ たと き の A の中身はど う なっ て いる か?
2 次元配列を 引数と し たと き の注意 num6-2.f, num6-2.c 5 A(1,1)=11 A(1,2)=12 A(1,3)=0 A(1,4)=0 A(2,1)=21 A(2,2)=22 A(2,3)=0 A(2,4)=0 A(3,1)=0 A(3,2)=0 A(3,3)=0 A(3,4)=0
と なっ て く れる こ と が期待さ れる が, 実際にやっ て みる と (num6-2.f) A(1,1)=11 A(1,2)=22 A(1,3)=0 A(1,4)=0
A(2,1)=21 A(2,2)=0 A(2,3)=0 A(2,4)=0 A(3,1)=12 A(3,2)=0 A(3,3)=0 A(3,4)=0 と なる . 何故か?
2 次元配列と 言え ど も , メ モリ ーには1 次元的に並んでいる こ と , サブルーチン への参照渡し は先頭のアド レ スだけである こ と . の2 点から , こ う なる こ と が理解でき る :
メ イ ン での並び方:
A(1,1) A(2,1) A(3,1) A(1,2) A(2,2) A(3,2) A(1,3) ...
サブでの並び方:
A(1,1) A(2,1) A(1,2) A(2,2)
同じ こ と を C でやっ たら ど う なる か? も う 分かる ね . (num6-2.c)
連立一次方程式を 解く 消去法 6
ではいよ いよ , 連立一次方程式を 解いて みよ う . 連立一次方程式
a
11x
1+ a
12x
2+ · · · + a
1nx
n= b
1, a
21x
1+ a
22x
2+ · · · + a
2nx
n= b
2,
.. .
a
n1x
1+ a
n2x
2+ · · · + a
nnx
n= b
nは, 行列表現で
(1)
a
11a
12· · · a
1na
21a
22· · · a
2n.. . .. . . .. ...
a
n1a
n2· · · a
nn
x
1x
2.. . x
n
=
b
1b
2.. . b
n
と なる . ど ち ら でも 同じ なので, 以下後者でやる . 要は, 行基本変形で
(2)
a
′11a
′12· · · a
′1n0 a
′22a
′2n.. . . .. ... ...
0 · · · 0 a
′nn
x
1x
2.. . x
n
=
b
′1b
′2.. . b
′n
の形 ( 上三角型 ) に帰着し , 下の方から 順に求めて 行く . (1) を (2) に帰着さ せる 計算を 前進消去と 呼ぶ.
(2) から x
n,. . . ,x
2, x
1を 求める 計算を 後退代入と 呼ぶ.
前進消去の際の注意 7 ピボッ ト ( 枢軸 ) 選択
純粋数学なら , (1) で a
116= 0 のと き , 各 i = 2, . . . , n に対し (1) の第1 行の a
i1a
11倍を 第 i 行から 引けば, 第1 列を 0 にでき る :
a
11a
12· · · a
1na
21a
22· · · a
2n.. . .. . . .. ...
a
n1a
n2· · · a
nnb
1b
2.. . b
n
= ⇒
a
11a
12· · · a
1n0 a
′22· · · a
′2n.. . .. . . .. ...
0 a
′n2· · · a
′nnb
1b
′2.. . b
′n
し かし , 数値計算では, たと い a
116= 0 であっ て も , a
i1, i = 1, . . . , n の中から 絶対値最大のも のを 探し 出し , その行を 第1 行と 入れ換え て から , 上の計算を する .
その理由は, 桁落ち の起こ る 可能性を なる べく 排除する ため.
例: 次のよ う な単精度の実行列は, そのま ま 行基本変形する と 8 1.000000 1.000000 −2.000000
1.000001 1.000000 −1.000000 2.000000 1.000000 −1.000000
1.000000 1.000000 0.000000
!
= ⇒ 1.000000 1.000000 −2.000000 0 −0.000001 1.000002 0 −1.000000 3.000000
1.000000
−0.000001
−2.000000
!
2 行目で桁落ち が起き て いる ので, 以後の精度が1 桁になっ て し ま う . 行の入れ換え を し て から やる と
2.000000 1.000000 −1.000000 1.000001 1.000000 −1.000000 1.000000 1.000000 −2.000000
0.000000 1.000000 1.000000
!
= ⇒ 2.000000 1.000000 −1.000000 0 0.4999995 −0.4999995 0 0.500000 −1.500000
0.000000 1.000000 1.000000
!
= ⇒ 2.000000 1.000000 −1.000000 0 0.500000 −1.500000 0 0.4999995 −0.4999995
0.000000 1.000000 1.000000
!
= ⇒ 2.000000 1.000000 −1.000000 0 0.500000 −1.500000
0 0 0.9999990
0.000000 1.000000 0.000001
!
相変わら ず x
3の値で桁落ち が生じ て おり , 有効数字1 桁になる が,
今度はそれが x
2や x
1の有効桁数に影響し ないので,
固定小数点の立場から 見て 3 変数一組での精度が保証さ れて いる .
( 例え ば, ベク ト ルの長さ など は精度が落ち な いで計算でき る . )
消去法のプロ グラ ムの書き 方 num6-3.f 9 SUBROUTINE SOLVE(A,B,X,N)
DOUBLE PRECISION A(N,N),B(N),X(N),FACTOR C 前進消去
DO 300 I=1,N IMAX=I
DO 50 K=I+1,N ! ピボッ ト 選択
IF (DABS(A(IMAX,I)).LT.DABS(A(K,I))) IMAX=K 50 CONTINUE
IF (IMAX.GT.I) CALL SWAP(A,B,I,IMAX,N) ! 行交換 DO 200 J=I+1,N
FACTOR=A(J,I)/A(I,I) DO 100 K=I+1,N
A(J,K)=A(J,K)-A(I,K)*FACTOR 100 CONTINUE
B(J)=B(J)-B(I)*FACTOR
200 CONTINUE ! A(J,I)=0, J>I はやる 必要無し 300 CONTINUE
C 後退代入
DO 600 I=N,1,-1 X(I)=B(I) DO 500 J=I+1,N
X(I)=X(I)-X(J)*A(I,J) 500 CONTINUE
X(I)=X(I)/A(I,I) 600 CONTINUE
RETURN END
a
11a
12· · · a
1na
21a
22· · · a
2n.. . .. . . .. ...
a
n1a
n2· · · a
nnb
1b
2.. . b
n
= ⇒
a
′11a
′12· · · a
′1n0 a
′22· · · a
′2n.. . . .. ... ...
0 · · · 0 a
′nnb
′1b
′2.. . b
′n
ピボッ ト に選んだ行を 先頭成分で割り 算し て から 他の行を 消去し て も よ い.
こ の場合は上三角行列の対角成分がすべて 1 に帰着さ れる .
同時に
bの成分も 割る ので, 割り 算の回数が減る わけではない.
計算量の見積も り 10
簡単のため , 行の入れ換え は無いも のと する . 前進消去は O(N
3):
比較 (N − 1) + (N − 2) + · · · + 1 = N (N − 1) 2 除算 (N − 1) + (N − 2) + · · · + 1 = N (N − 1)
乗算と 差 {(N − 1)
2+ (N − 2)
2+ · · · + 1} 2 + {(N − 1) + (N − 2) + · · · + 1}
= N (N − 1)(2N − 1)
6 + N (N − 1)
後退代入は O(N
2): 2
乗算と 差 (N − 1) + (N − 2) + · · · + 1 = N (N − 1) 除算 N 2
つま り , 前進消去の方が律速 ( 速度に対する 影響を 支配する ) であり ,
:::::::
全体で
::::::::O(N
3)
::::::::::
の計算量と なっ て いる . よ く ある 勘違い:
同じ 方法で O(N
3) で A の逆行列 C が求ま る . 方程式の解は
X = CB で計算すればよ いではないか?
行列と ベク ト ルの積の計算量は 11
乗算 N × N = N
2, 和 N × (N − 1) で O(N
2) である . DO 100 I=1,N
Y(I)=0
DO 100 J=1,N
Y(I)=Y(I)+A(I,J)*X(J) 100 CONTINUE
し かし , 実用でよ く 現れる 行列は , 非零成分が主対角線の近く だけに 存在する 帯状行列である こ と が多い . i.e. A(I, J) = 0 for |I − J | > b b はバン ド 幅と 呼ばれ , N に依存し ない定数 ( 普通, 空間の次元に依存 ).
こ の場合 , 前進消去・ 後退代入と も に計算量は O(N ) に減少する が , 逆行列は帯状行列になら ない ( 密行列 full matrix).
こ う いう 場合は , 逆行列を 掛ける 方が計算量が大き く な る .
a
11a
120 · · · 0 a
21a
22a
23. .. .. . 0 . .. ... ... 0
.. . . .. ... ... a
n−1,n0 · · · 0 a
n,n−1a
nnb
1b
2.. . .. . b
n
= ⇒
a
11a
120 · · · 0 0 a
′22a
23. .. .. . 0 . .. ... ... 0
.. . . .. ... ... a
n−1,n0 · · · 0 0 a
′nnb
1b
′2.. . .. . b
′n
帯状行列は正方配列ではなく 長方形の配列 A(N,-B:B) に格納する .
B はバン ド 幅で, 対称行列なら , A(N,0:B) でよ い.
LR 分解 (LU 分解 ) 12
前進消去は行列に左から 下三角型行列を 掛ける こ と で達成さ れる . LA = R は上三角型と なる ので, A = L
−1R, 従っ て A
−1= R
−1L
前進消去は右辺のベク ト ル
bに L を 掛ける 操作に相当,
後退代入はその結果 L
bに R
−1を 掛ける 操作に相当.
A が帯状行列なら , L, R は帯状の下, 上三角型行列と なる ので , こ の場合は A
−1でなく , L, R を 記憶し て 使え ば,
O(N ) で方程式が解ける .
三角型帯状行列も 逆行列を と る と , 同じ 三角型の密行列と なる ので,
R
−1を 記憶し て し ま う と , 積の計算量は O(N
2) になっ て し ま う . R を 記憶し , 後退代入で R
−1bを 計算し なければなら ない.
−
○ 上三角型行列の逆行列は, 上三角型
○ 下三角型行列の逆行列は, 下三角型
○ 対角型行列の逆行列は, 対角型
× 帯状行列の逆行列は, 帯状行列
× 上三角型帯状行列の逆行列は, 上三角型帯状行列
× 下三角型帯状行列の逆行列は, 下三角型帯状行列