1

mxn 行列を取得し、QR で分解するプログラムを作成しようとしています。

まだ終わっていませんが、問題が発生しました。ウィキペディアhttp://en.wikipedia.org/wiki/QR_decompositionに示されている例でプログラムを実行してみました

A=[12,-51,4;6,167,-68;-4,24,-41]

彼らが Q1、Q2 と呼んだもの...私は Qtemp と呼びました。Qtempを計算するたびに、ウィキペディアと同じ結果が得られることを確認するために印刷します。Q1 はしますが、Q2 はしません。

彼らの Q2 と私のものは同じ値ですが、符号が異なります。彼らが + を持っているところには - があり、彼らが - を持っているところには + があります。

これは私のコードです:

    Q=eye(m);
R=A;
for i=1:min(m-1,n)
    ei=zeros(n,1);
    ei(i,1)=1;
    x=A(:,i);
    for j=1:i-1
        x(j,1)=0;
    end
    u=x-norm(x)*ei;
    v=u/norm(u);
    Qtemp=eye(m)-2*(v*v');
    A=Qtemp*A;
    disp(Qtemp);
end

私は文字通り彼らのアルゴリズムをコピーしてコードに変換しましたが、それでも 2 番目の Qtemp の出力は良くありません。

4

1 に答える 1

1

各反復でブロックのサイズを縮小していないようです。mすべてが同じandの関数のようnです (コードで定義していません)。ウィキペディアのページで A' を定義し、それを使用して Q 2を構築する行を参照してください(下の 3 分の 2 だけ)。以下は、役立つかもしれない3行3列の行列のQR分解を実行するように適合された私のコードです。特に、2 番目のブロックは と でのみ機能することに注意してA(:,2)くださいq(2:3,:)

function [q,r]=qr3(A)

u = A(:,1);
u(1) = u(1)-(1-2*(u(1)<0))*norm(u); % Flip < to > to match sign convention of qr
u = u/norm(u);
u(~isfinite(u)) = sqrt(3)/3;
q = -2*(u*u');
q([1 5 9]) = q([1 5 9])+1;

u = q(2:3,:)*A(:,2);
u(1) = u(1)-(1-2*(u(1)<0))*norm(u); % Flip < to > to match sign convention of qr
u = u/norm(u);
u(~isfinite(u)) = sqrt(2)/2;
q(:,2:3) = q(:,2:3)*[1-2*u(1)^2 -2*u(1)*u(2);
                     -2*u(1)*u(2) 1-2*u(2)^2];
r = triu(q'*A);

qr上記のコードとウィキペディアで詳しく説明されているメソッドは、Matlab の関数とは異なる符号規則を使用しています。記号を反転する方法については、コード内の私のコメントを参照してください。

于 2013-08-04T22:08:07.947 に答える