2017-06-08 2 views
1

Ich muss eine kumulative Summe in MATLAB für eine Matrix von Nullen und Einsen für jede Zeile machen, aber ich muss es stoppen, wenn es keine mehr gibt. Beispiel, wenn ich mit beginnen:Wie wird eine kumulative Summe durchgeführt, aber werden in MATLAB Nullwerte beibehalten?

A = [0 0 0 0 0 1 1 1 1 1 0 0 0; 
    0 0 0 1 1 1 1 1 1 1 0 0 0; 
    0 0 0 0 0 0 0 1 1 0 0 0 0]; 

möchte ich das Ergebnis:

B = [0 0 0 0 0 1 2 3 4 5 0 0 0; 
    0 0 0 1 2 3 4 5 6 7 0 0 0; 
    0 0 0 0 0 0 0 1 2 0 0 0 0]; 

Wenn ich cumsum verwenden, wird es weiterhin die Werte addiert und ein anderes Ergebnis geben:

B = [0 0 0 0 0 1 2 3 4 5 5 5 5; 
    0 0 0 1 2 3 4 5 6 7 7 7 7; 
    0 0 0 0 0 0 0 1 2 2 2 2 2]; 

Bitte , wenn jemand einen Vorschlag hat, da ich etwas ähnliches nicht finden kann (ich habe mehrere ziemlich große Matrix).

+0

Diese Frage sollte auf Stack Overflow migriert werden, da sie auf Code basiert. – Jon

Antwort

4

Es gibt zwei mögliche Lösungen, je nachdem, wie Sie mit einem Fall umgehen möchten, in dem Sie mehr als eine Folge von Einsen pro Zeile haben (falls dies möglich ist). Wenn die kumulative Summe jedes Mal zurückgesetzt werden soll, wenn eine neue Folge von Einsen auftritt, verwenden Sie die komplexere Lösung. Wenn Sie für jede neue Folge von Einsen nicht die kumulative Summe zurücksetzen möchten, oder Sie immer nur pro Zeile eine Zeichenfolge haben, verwenden Sie die einfachere Lösung:

  • Einfache Lösung (eine Zeichenfolge oder keine cumsum Zurücksetzen): Sie können die kumulative Summe ausführen, dann A (insbesondere seine Verwendung negation) als logical index Einträge auf Null zu setzen zurück:

    B = cumsum(A, 2); 
    B(~A) = 0; 
    
    B = 
    
        0  0  0  0  0  1  2  3  4  5  0  0  0 
        0  0  0  1  2  3  4  5  6  7  0  0  0 
        0  0  0  0  0  0  0  1  2  0  0  0  0 
    
  • Komplexe Lösung (cumsum für jede Saite Reset): Lasst uns sagen Sie können mehr als eine Folge von Einsen pro Zeile, wie (man beachte die letzte Zeile) haben:

    A = 
    
        0  0  0  0  0  1  1  1  1  1  0  0  0 
        0  0  0  1  1  1  1  1  1  1  0  0  0 
        0  0  0  1  1  0  0  1  1  0  0  0  0 
    

    In diesem Fall haben wir die Werte der kumulativen Summe am Ende jeder Folge von Einsen nehmen, diejenigen, die in einer neuen Matrix platzieren, gelten cummax, dann subtrahieren unserer kumulative Summe:

    B = cumsum(A, 2); 
    index = find([zeros(size(A, 1), 1) diff(A, 1, 2)] == -1); 
    C = zeros(size(B)); 
    C(index) = B(index); 
    B = B-cummax(C, 2); 
    
    B = 
    
        0  0  0  0  0  1  2  3  4  5  0  0  0 
        0  0  0  1  2  3  4  5  6  7  0  0  0 
        0  0  0  1  2  0  0  1  2  0  0  0  0 
                   ^-- sum resets 
    

    die einfachere Lösung in diesem Fall anwenden würde stattdessen Ausbeute:

    B = 
    
        0  0  0  0  0  1  2  3  4  5  0  0  0 
        0  0  0  1  2  3  4  5  6  7  0  0  0 
        0  0  0  1  2  0  0  3  4  0  0  0  0 
                   ^-- no reset 
    
-1

Finden Sie die kumulative Summe von A und erhalten Positionen von Nullen in A und ersetzen Sie Null an diesen Positionen in der Cumsum.

A = [0 0 0 0 0 1 1 1 1 1 0 0 0; 
    0 0 0 1 1 1 1 1 1 1 0 0 0; 
    0 0 0 0 0 0 0 1 1 0 0 0 0]; 

B = cumsum(A,2) ; 
B(A==0) = 0 ;