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
+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. –
Änderte meine Antwort! danke – Dohyun
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