next up previous
Next: B. MATLAB で QR変換して遊んだときのガラクタ箱 Up: 応用数理実験 固有値問題 (2) 実対称行列の三重対角化 Previous: 関数 trid() の使用例

A. MATLAB で Householder 法プログラムを書いて遊ぶ

ガラクタ箱だけど、後で使おう。

naive_householder.m

function H=naive_householder(A)
[N N]=size(A);
for k=1:N-2
 b=A(k+1:N,k);
 B=A(k+1:N,k+1:N);
 s=-sign(b(1))*norm(b);
 v=b;
 v(1)=v(1)-s;
 v=v/norm(v);
 Q=eye(N-k,N-k)-2*v*v';
 B=Q*B*Q;
 b=zeros(N-k,1);
 b(1)=s;
 A(k+1:N,k)=b;
 A(k,k+1:N)=b';
 A(k+1:N,k+1:N)=B;
end
H=A;

householder.m

function H=householder(A)
[N N]=size(A);
for k=1:N-2
 b=A(k+1:N,k);
 b1=b(1);
 B=A(k+1:N,k+1:N);
 s=-sign(b1)*norm(b);
 w=b;
 w(1)=w(1)-s;
 norm_w=2*(s*s-b1*s);
 p=B*w/(norm_w/2);
 alpha=w'*p/norm_w;
 q=p-alpha*w;
 B=B-w*q'-q*w';
 b=zeros(N-k,1);
 b(1)=s;
 A(k+1:N,k)=b;
 A(k,k+1:N)=b';
 A(k+1:N,k+1:N)=B;
end
H=A;

householder_exp2.m

%format long
A=[1 1 1 1;
   1 2 2 2;
   1 2 3 3;
   1 2 3 4]
householder(A)

householder_exp2.m の実行結果

>> householder_exp2

A =

     1     1     1     1
     1     2     2     2
     1     2     3     3
     1     2     3     4


ans =

    1.0000   -1.7321         0         0
   -1.7321    7.6667    1.2472         0
         0    1.2472    0.9762   -0.1237
         0         0   -0.1237    0.3571

>> 

少し大きめの行列を作って、 それを householder() で三重対角化してみた。 ついでに固有値を計算して元の行列と変化がないことを確かめた (まあ相似変換が正しいことの状況証拠)。 そのうち三重対角行列の固有値の計算をするプログラムを書こう。

householder_exp3.m

format short
N=10
A=zeros(N,N);
for i=1:N
   t=i*ones(N-i+1,1);
   A(i:N,i)=t;
   A(i,i:N)=t';
end
A
H=householder(A)
e1=sort(eig(A))
e2=sort(eig(H))
norm(e1-e2)

householder_exp3.m の実行結果


next up previous
Next: B. MATLAB で QR変換して遊んだときのガラクタ箱 Up: 応用数理実験 固有値問題 (2) 実対称行列の三重対角化 Previous: 関数 trid() の使用例
Masashi Katsurada
平成17年8月22日