微分方程式の数値シミュレーションに 現われる連立1次方程式の係数行列は、 ほとんどの場合、 成分に 0 が多いです。 そのような行列をそ疎 (sparse) であると言います。 疎行列はその性質をうまく利用することで、効率的な計算が可能になり、 大規模な問題が解けるようになる可能性があります (今だと未知数の個数が億のオーダーの連立1次方程式が解けたりします)。
行列が疎であっても、 その逆行列は疎であるとは限らない (大抵の場合、疎ではない) ことに注意する必要があります。
MATLAB のコマンド・メモ (1) | ||||||||||||||||||
|
以下の例では、
について (実はある微分方程式を解く際に実際に現れる行列)、 連立1次方程式を解いたり、 逆行列を計算したりしています。
>> n=4 n = 4 >> 1:n ans = 1 2 3 4 >> (1:n)'*(1:n) ans = 1 2 3 4 2 4 6 8 3 6 9 12 4 8 12 16 >> eye(n,n) ans = 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 >> zeros(n,n) ans = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 >> ones(n-1,1) ans = 1 1 1 >> diag(ones(n-1,1),1) ans = 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 >> diag(ones(n-1,1),-1) ans = 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 >> a=2*eye(n,n)-diag(ones(n-1,1),1)-diag(ones(n-1,1),-1) a = 2 -1 0 0 -1 2 -1 0 0 -1 2 -1 0 0 -1 2 >> x=(1:n)' x = 1 2 3 4 >> b=a*x b = 0 0 0 5 >> ia=inv(a) ia = 0.80000 0.60000 0.40000 0.20000 0.60000 1.20000 0.80000 0.40000 0.40000 0.80000 1.20000 0.60000 0.20000 0.40000 0.60000 0.80000 >> ia*a ans = 1.00000 -0.00000 0.00000 0.00000 0.00000 1.00000 0.00000 0.00000 0.00000 0.00000 1.00000 0.00000 0.00000 0.00000 0.00000 1.00000 >> n=8;a=2*eye(n,n)-diag(ones(n-1,1),1)-diag(ones(n-1,1),-1) a = 2 -1 0 0 0 0 0 0 -1 2 -1 0 0 0 0 0 0 -1 2 -1 0 0 0 0 0 0 -1 2 -1 0 0 0 0 0 0 -1 2 -1 0 0 0 0 0 0 -1 2 -1 0 0 0 0 0 0 -1 2 -1 0 0 0 0 0 0 -1 2 >> inv(a) ans = 0.88889 0.77778 0.66667 0.55556 0.44444 0.33333 0.22222 0.11111 0.77778 1.55556 1.33333 1.11111 0.88889 0.66667 0.44444 0.22222 0.66667 1.33333 2.00000 1.66667 1.33333 1.00000 0.66667 0.33333 0.55556 1.11111 1.66667 2.22222 1.77778 1.33333 0.88889 0.44444 0.44444 0.88889 1.33333 1.77778 2.22222 1.66667 1.11111 0.55556 0.33333 0.66667 1.00000 1.33333 1.66667 2.00000 1.33333 0.66667 0.22222 0.44444 0.66667 0.88889 1.11111 1.33333 1.55556 0.77778 0.11111 0.22222 0.33333 0.44444 0.55556 0.66667 0.77778 0.88889 >>
が疎であっても、 の成分には つも 0 がないことを確認して下さい。
…あまりピンと来ないと思いますが、 これは実際上解決しないといけない壁なのです。
解決策はいくつかありますが、良く知られているのは、 逆行列の代わりに「LU分解」を使う、というものです。
任意の正則行列 に対して、
であれば、 であるから、
となり2、 , の掛け算は非常に簡単なので (付録 B.5.2 参照)、 , , が求まっていれば連立1次方程式は簡単に解ける。 (1), (2) を満たす , , を 求めることを を LU 分解するという。
MATLAB のコマンド・メモ (2) | ||||
|
>> [L u p]=lu(a) L = 1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 -0.50000 1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 -0.66667 1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 -0.75000 1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 -0.80000 1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 -0.83333 1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 -0.85714 1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 -0.87500 1.00000 u = 2.00000 -1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 1.50000 -1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 1.33333 -1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 1.25000 -1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 1.20000 -1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 1.16667 -1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 1.14286 -1.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 1.12500 p = 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 >> x=(1:n)' x = 1 2 3 4 5 6 7 8 >> b=a*x b = 0 0 0 0 0 0 0 9 >> u\(L\(p*b)) ans = 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 >>
を LU 分解したときの因子 , , が確かに 置換行列、下三角行列、上三角行列であることを確かめよう (このケースでは、 は単位行列である)。 , が疎行列であることも確かめよう。
今回は使わなかったが、よく使われるコマンドを紹介しておく。
MATLAB のコマンド・メモ (3) | ||||||||||||||||||||||
|
余裕があれば試してみよう | |
|