2016-12-05 17 views
0

ich eine große Sparse Matrix, die ich arbeite, aber die Einfachheit halber habe ich es unten geschrieben, wie gezeigt:Solving singuläre Sparse Matrix MATLAB

row = [1,3]; 
col = [1,3]; 
val = [22,33]; 

B = sparse(row,col,val,3,3) 

22  0  0 
0  0  0 
0  0 33 

Diese Matrix singulär ist und nicht über eine inverse dass Ich kann für eine Lösung von verwenden:

[A]=[B][C] =>[B]\[A] = [C].

Um dies zu beheben, müssen alle Zeilen und Spalten, die nur 0 enthalten, entfernt werden. Im obigen Beispiel würde ich Zeile 2 und Spalte 2 entfernen, bevor ich die Sparse-Matrix erstelle.

Aber wenn ich das versuche, wird der von den Zeilen- und Spaltenvektoren (3,3) beschriebene Index außerhalb der Matrix-Dimensionen zeigen und mir einen Fehler geben. Was kann ich tun, um dieses Problem zu lösen?

Antwort

1

Sie könnten zunächst Ihre Matrix, die die Art und Weise aufzubauen, die Sie haben, und dann die leeren Zeilen und Spalten mit der

C = B(any(B, 2), any(B, 1)); 

Dies ist sehr effizient (raumweise) folgende entfernen any da auf eine Sparse Matrix angewendet ein spärliches Ergebnis liefert und der Indexierungsvorgang liefert über C die auch spärlich

Obwohl je nach Problem ist, wird dies nicht eine nicht-singuläre Matrix gewährleisten.

aktualisieren

Wenn Sie eine Zeile oder Spalte entfernen möchten, wenn sowohl die Zeile und entsprechende Spalte gleich Null sind (zu halten Ihre Matrix quadratisch)

tokeep = any(B, 2).' | any(B, 1); 

C = B(tokeep, tokeep); 
+0

Ist das nicht eine unglaublich ineffiziente Methode im Umgang mit Large-Sparse-Matrizen (1000000x1000000)? – Lobstw

+0

@Lobstw Nein, weil alle Zwischenwerte auch "spärlich" sind – Suever

+0

Vielen Dank für die Klärung. Dies führt jedoch nicht zu den erwarteten Ergebnissen für einen Fall wie: "[22 0 0; 44 0 0; 0 0 33]" Die 2. Zeile sollte nicht entfernt werden – Lobstw

0

Eine mögliche Lösung

row = [1,3]; 
col = [1,3]; 
val = [22,33]; 
[ur,~,u_row] = unique(row); 
[uc,~,u_col] = unique(col); 
B =sparse(u_row,u_col,val,numel(ur),numel(uc));