文献に書いてあることを理解して要約すべきだと思うが… MATLAB 時代の良いことは試すことは簡単にできるということだ。
compare.m |
1 function compare(n) 2 a=rand(n,n); 3 %% qr() 4 fprintf('MATLAB の qr()\n'); 5 tic 6 [q0 r0]=qr(a); 7 toc 8 fprintf('||Q R-A||=%e\n\n', norm(q0*r0-a)); 9 %% 10 fprintf('普通の Gram-Schmidt\n'); 11 tic 12 [q1 r1]=GramSchmidt(a); 13 toc 14 fprintf('MATLABの関数の結果との差: %e %e\n', norm(q1-q0), norm(r1-r0)); 15 fprintf('||Q R-A||=%e\n\n', norm(q1*r1-a)); 16 %% 17 fprintf('修正 Gram-Schmidt\n'); 18 tic 19 [q2 r2]=ModifiedGramSchmidt(a); 20 toc 21 fprintf('MATLABの関数の結果との差: %e %e\n', norm(q2-q0), norm(r2-r0)); 22 fprintf('||Q R-A||=%e\n\n', norm(q2*r2-a)); 23 %% 24 fprintf('Givens 変換による QR 分解\n'); 25 tic 26 [q3 r3]=QR_Givens(a); 27 toc 28 fprintf('MATLABの関数の結果との差: %e %e\n', norm(q3-q0), norm(r3-r0)); 29 fprintf('||Q R-A||=%e\n\n', norm(q3*r3-a)); 30 %% 31 fprintf('Householde 変換による QR 分解\n'); 32 tic 33 [q4 r4]=qrhouse(a); 34 toc 35 fprintf('MATLABの関数の結果との差: %e %e\n', norm(q4-q0), norm(r4-r0)); 36 fprintf('||Q R-A||=%e\n\n', norm(q4*r4-a)); |
ここでは手抜きをして、 誤差と言うよりも残差を計算している。 そのうち誤差を計算できるようにしてみたいが、 分解の一意性がないのでこまったな…
qr() | Gram-Schmidt | ���� Gram-Schmidt | Givens | Householder | |
少なくともこの実験結果だけからは、 Gram-Schmidt の直交化法、修正 Gram-Schmidt の直交化法による結果は 他の方法による結果よりも精度が良さそうである。 MATLAB の qr() による結果はそれよりも悪い。 MATLAB の qr() による結果は Householder 法による結果に近い。
Gram-Schmidt の直交化法と 修正 Gram-Schmidt の直交化法による結果の差は少ない。 その二つの差よりも、 Givens 変換や Householder 変換を用いた方法との差の方がずっと大きい。 普通の Gram-Schmidt の直交化法ではうまく解けないような条件の悪い問題を作って、 それについて実験しないといけないのか? 考え込まされる結果である。