2017-01-06 156 views
2

我正在使用MATLAB來做計算條件協方差和均值使用高斯混合模型,它總是與Schur complement有關。在Wiki中建議,如果矩陣C是奇異的,則可以使用C的廣義逆來計算Schur補。如何識別矩陣是奇異的工作精度在Matlab

在MATLAB中,pinv就是爲了這個目的。由於我的矩陣非常大(超過1000列)並且會導致尺寸爲> 1000*1000的協方差矩陣,因此使用eig代替svd來計算pinv可能會快得多。但是,由於它會在設定的閾值下截斷對應於小特徵值的特徵向量,因此可能會失去顯着的精度。

的另一種方法是使用rmdivide函數來計算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是「一般」非奇異和mrdvide是速度遠遠超過pinv,那麼你可以嘗試mrdivide再搭上警告切換到pinv

但是,在MATLAB中,我們無法使用try來捕捉警告。幸運的是,有undocumented solution趕上警告。

的基本思想是把warningerror爲特定的警告標識(在你的情況,MATLAB:singularMatrix),你將有,然後用trycatch

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);'。這樣,警告狀態就會重置爲操作之前的狀態,而不是強制它「開啓」。 –

+0

更改我的答案!謝謝 – Dohyun

+0

謝謝,這是一個好主意。但是我不喜歡'try ... catch ...'模式,因爲如果它被插入到具有大量迭代的循環中,這會顯着減慢計算速度。我爲自己的問題更新了自己的解決方案。我認爲這是更直接的。 – Elkan