Reduzierte Reihenebenenform einer Matrix

8

Das Ziel dieser Herausforderung ist es, ein Programm zu erstellen, das eine Matrix aufnimmt und seine reduzierte Zeilenebenenform ausgibt.

Eine Matrix liegt in reduzierter Reihenebenenform vor, wenn sie alle folgenden Bedingungen erfüllt:

  1. Wenn es eine Zeile gibt, in der jeder Eintrag Null ist, liegt diese Zeile unter jeder anderen Zeile, die einen Eintrag ungleich Null enthält.
  2. Der Eintrag ganz links ungleich Null einer Zeile ist gleich 1.
  3. Der Eintrag ganz links ungleich Null einer Zeile ist der einzige Eintrag ungleich Null in seiner Spalte.
  4. Betrachten Sie zwei verschiedene Einträge ganz links ungleich Null, einen in Zeile i, Spalte j und einen in Zeile s, Spalte t. Wenn ja s>i, dann t>j.

Quelle

Der allgemeine Prozess zum Transformieren der Matrix ist:

  1. Behandeln Sie jede Zeile i nacheinander von 1 bis n und arbeiten Sie über die Spalten j von 1 bis m, wobei Sie jede Spalte aller Null-Einträge überspringen.
  2. Suchen Sie die nächste Spalte j mit einem Eintrag ungleich Null.
  3. Tauschen Sie ggf. Zeilen aus, damit das Pivot-Element A (i, j) ungleich Null ist.
  4. Machen Sie den Pivot gleich 1, indem Sie jedes Element in der Pivot-Reihe durch den Wert des Pivots dividieren.
  5. Machen Sie alle Elemente über und unter dem Pivot gleich 0, indem Sie ein geeignetes Vielfaches der Pivot-Reihe von jeder anderen Reihe subtrahieren.
  6. Wiederholen Sie dies für alle Zeilen.

Wenn Sie mehr über diesen Matrixtyp erfahren möchten, lesen Sie den Wikipedia- Artikel und ein Tool und einen Artikel (Schritte oben) , in denen die Schritte zum Transformieren der Matrix aufgeführt sind.

Die eigentliche Herausforderung lautet:

Die Eingabe kann auf beliebige Weise über STDIN oder ein gleichwertiges Verfahren erfolgen. Bitte erläutern Sie dies in Ihrer Antwort. Die Ausgabe ist die reduzierte Zeilenebenenform der Eingabe in derselben Form wie die Eingabe über STDOUT oder eine gleichwertige Form. Standard Lücken sind nicht erlaubt und externe Bibliotheken oder Funktionen , die diese Aufgabe übernehmen sind ebenfalls nicht erlaubt ( TI-BASIC‚s - rref(Befehl, zum Beispiel). Sie können ein vollständiges Programm oder eine vollständige Funktion schreiben. Dies ist Code Golf, niedrigste BYTES gewinnt. Viel Glück!

Beispiel Eingabe: [[2,1,1,14][-1,-3,2,-2][4,-6,3,-5]]

Beispielausgabe: [[1,0,0,1][0,1,0,5][0,0,1,7]]

GamrCorps
quelle
5
Sie müssen geben , eine gewisse Erklärung des Reduktionsprozesses hier, so dass diese Frage noch Sinn macht , wenn diese Verbindungen schlecht gehen.
Sparr
Eine Erklärung wurde hinzugefügt. Hoffe es ist detailliert genug.
GamrCorps
Dürfen wir "ref ()", lineare Gleichungslöser oder andere integrierte Funktionen verwenden, die das Problem fast lösen?
Lirtosiast
Solange es einen komplexeren Schritt gibt, der nur so etwas ist method(ref(matrix)), würde ich sagen,
mach

Antworten:

2

R 232 Bytes

function(M){p=1;R=nrow(M);C=ncol(M);for(r in 1:R){if(C<=p)break;i=r;while(M[i,p]==0){i=i+1;if(R==i){i=r;p=p+1;if(C==p)return(M)}};t=M[i,];M[i,]=M[r,];M[r,]=t;M[r,]=M[r,]/M[r,p];for(i in 1:R)if(i!=r)M[i,]=M[i,]-M[r,]*M[i,p];p=p+1};M}

Dies ist nur eine Implementierung des üblichen Gaußschen Eliminierungsalgorithmus.

Ungolfed:

rref <- function(M) {
    p <- 1
    R <- nrow(M)
    C <- ncol(M)
    for (r in 1:R) {
        if (C <= p)
            break
        i <- r
        while (M[i, p] == 0) {
            i <- i + 1
            if (R == i) {
                i <- r
                p <- p + 1
                if (C == p)
                    return(M)
            }
        }
        t <- M[i, ]
        M[i, ] <- M[r, ]
        M[r, ] <- t
        M[r, ] <- M[r, ] / M[r, p]
        for (i in 1:R)
            if (i != r)
                M[i, ] <- M[i, ] - M[r, ] * M[i, p]
        p <- p + 1
    }
    M
}
Alex A.
quelle
Ich denke, Sie können vielleicht M[c(i,r),]=M[c(r,i),]eher mit alst=M[i,];M[i,]=M[r,];M[r,]=t
MickyT