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
+1!わずかな改良: 'ws = warning( 'error'、...)'を使い、最後に 'warning(ws);'を使う方が良いでしょう。このようにして、警告状態は '' on''を強制するのではなく、操作の前の状態にリセットされます。 –
私の答えが変更されました!おかげで、 – Dohyun
ありがとう、これは良い考えです。しかし、試し回数が多いループに挿入すると、計算が大幅に遅くなるため、 'try ... catch ... 'パターンを使用することをお勧めしません。私は私の質問のために私自身の解決策を更新しました。私はもっと真っ直ぐだと思う。 – Elkan