2017-01-06 9 views
2

Ich benutze MATLAB, um bedingte Kovarianz zu berechnen und meine mit Gaußschen Mischung Modell, die immer bezieht sich auf Schur complement. Es wird in Wiki vorgeschlagen, dass, wenn die Matrix C singulär ist, verallgemeinerte Umkehrung von C verwendet werden kann, um das Schur-Komplement zu berechnen.So identifizieren Sie Matrix ist singular zu Arbeitspräzision in Matlab

In MATLAB ist pinv für dieses Ziel. Da meine Matrix sehr groß ist (mehr als 1000 Spalten) und zu einer Kovarianzmatrix mit der Größe > 1000*1000 führt, kann es viel schneller sein, eig anstelle von svd zu verwenden, um die pinv zu berechnen. Dies kann jedoch eine bemerkenswerte Genauigkeit verlieren, da es Eigenvektoren schneidet, die kleinen Eigenwerten unter dem eingestellten Schwellenwert entsprechen.

Eine andere Möglichkeit ist rmdivide Funktion zu berechnen BC^(-1) als B/C, da die Umkehrung einer Matrix als ein Problem der kleinsten Quadrate betrachtet werden kann. In meinem Problem kann dies eine viel höhere Genauigkeit erreichen und viel schneller laufen als mit B*pinv(C). Ferner kann rmdivide mit einer einzelnen Matrix arbeiten, daher ist diese Methode vorzuziehen. In einigen Fällen kann jedoch die Warnung Matrix is singular to working precision auftreten, die NaNs ergibt, wenn rmdivide verwendet wird. Also, gibt es eine Möglichkeit zu identifizieren, wenn diese Warnung auftreten wird, kann ich stattdessen pinv verwenden?

aktualisieren

Zusätzlich zu @ Dohyun Antwort, was ich jetzt tue, ist die erzielten Ergebnisse zu überprüfen, auf die Tatsache gestützt, dass NaN in den Ergebnisse erzielt werden, wenn die Matrix singulär ist.

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 

Antwort

3

Wenn Ihre Matrix C ‚in der Regel‘ ist nicht singulär und mrdvide ist viel schneller als pinv, dann können Sie mrdivide versuchen und dann zu pinv wechseln fangen warnen.

In MATLAB können wir die Warnung jedoch nicht mit try abfangen. Glücklicherweise gibt es undocumented solution, um die Warnung zu erfassen.

Die Grundidee ist warning-error für spezifische Warnung ID drehen (in Ihrem Fall MATLAB:singularMatrix) Sie haben, und dann try und catch verwenden.

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! leichte Verbesserung: Es ist besser, 'ws = warning ('error', ...)' und dann am Ende 'warning (ws); '. Auf diese Weise wird der Warnungszustand auf den Zustand vor der Operation zurückgesetzt, anstatt ihn "an" zu zwingen. –

+0

Änderte meine Antwort! danke – Dohyun

+0

Danke, das ist eine gute Idee. Aber ich bevorzuge nicht "try ... catch ..." -Muster, da dies die Berechnung erheblich verlangsamen kann, wenn es in Schleifen mit großen Iterationen eingefügt wird. Ich habe meine eigene Lösung für meine Frage aktualisiert. Ich denke, es ist geradliniger. – Elkan