2017-01-06 43 views
2

MATLABを使用して、条件付き共分散を計算し、平均値がSchur complementになるガウス混合モデルを使用しています。 Wikiでは、行列Cが特異である場合、Cの一般化逆行列を使用してシュール補体を計算することができることが示唆されています。Matlabで行列が単精度から精度に変換される方法

MATLABでは、pinvがこの目的のためです。私の行列は非常に大きく(1000列以上)、サイズが> 1000*1000の共分散行列になるので、pinvを計算するのにsvdの代わりにeigを使うほうがはるかに高速です。しかしながら、これは、設定された閾値の下で小さな固有値に対応する固有ベクトルを切り捨てるので、顕著な精度を失う可能性がある。

もう1つの方法は、BC^(-1)B/Cと計算する関数を使用することです。これは、行列の逆行列が最小二乗問題とみなされるためです。私の問題では、これはより高い精度を得ることができ、B*pinv(C)を使用するよりもずっと速く実行できます。また、rmdivideは、ある特異行列を扱うことができるため、この方法が好ましい。しかし、場合によってはMatrix is singular to working precisionという警告が発生し、rmdivideを使用するとNaNsになります。だから、この警告がいつ発生するのかを特定する方法があるので、代わりにpinvを使用できますか?

更新

@ Dohyunの答えに追加

、私が今やっていることは行列が特異である場合NaN結果で得ることができるという事実に基づか、得られた結果を確認することです。

warning('off','MATLAB:singularMatrix') 
x = b/C; % in my codes, vector is obtained, I think matrix can also be checked in this way 
if isnan(sum(x)) 
    x = b*pinv(C); 
end 

答えて

3

あなたの行列Cは「通常」正則であるとmrdvidepinvよりもはるかに高速である、あなたはmrdivideを試し、その後pinvに切り替えることを警告キャッチすることができます。

しかし、MATLABではtryを使用して警告をキャッチできません。幸いにも、警告をキャッチするにはundocumented solutionがあります。

基本的な考え方は、あなたが持っているし、その後trycatchを使用します(あなたのケースでは、MATLAB:singularMatrix)特定の警告IDのためerrorwarningを回しています。

myWarn = warning('error','MATLAB:singularMatrix'); % turn singular matrix warning to error 
try 
    u = mrdivide(B,C); 
catch 
    u = B*pinv(C); 
end 
warning(myWarn); % return to warning 
+2

+1!わずかな改良: 'ws = warning( 'error'、...)'を使い、最後に 'warning(ws);'を使う方が良いでしょう。このようにして、警告状態は '' on''を強制するのではなく、操作の前の状態にリセットされます。 –

+0

私の答えが変更されました!おかげで、 – Dohyun

+0

ありがとう、これは良い考えです。しかし、試し回数が多いループに挿入すると、計算が大幅に遅くなるため、 'try ... catch ... 'パターンを使用することをお勧めしません。私は私の質問のために私自身の解決策を更新しました。私はもっ​​と真っ直ぐだと思う。 – Elkan

関連する問題