Seite 1 von 1

meine ersten Matrix-Berechnungen in Python

Verfasst: Mittwoch 18. April 2007, 12:16
von Jemand
Hi,

ich habe mich jetzt daran gemacht, das Gaußsche Eliminationsverfahren in Python zu schreiben.
Als Vorlage habe ich einen Pseudocode benutzt, der mich so ungefähr durch den Algorithmus gebracht hat. Viele Probleme habe ich gelöst und habe jetzt auch eine Ausgabe, nur leider ist sie falsch. :)

Würde mich freuen, wenn mal jemand kurz drüberschauen könnte, ich hoffe ich habe mein Werk gut genug kommentiert.
Was vielleicht unverständlich sein könnte: im Pseudocode fangen die Angaben Zeilen/Reihen bei 1 an, bei Python in einer Liste aber bei 0, somit musste ich das abändern.

Aber schaut selbst:

Code: Alles auswählen

i := 1
j := 1
while (i <= m and j <= n) do
  Find pivot in column j, starting in row i:
  maxi := i
  for k := i+1 to m do
    if abs(A[k,j]) > abs(A[maxi,j]) then
      maxi := k
    end if
  end for
  if A[maxi,j] != 0 then
    swap rows i and maxi, but do not change the value of i
    Now A[i,j] will contain the old value of A[maxi,j].
    divide each entry in row i by A[i,j]
    Now A[i,j] will have the value 1.
    for u := i+1 to m do
      subtract A[u,j] * row i from row u
      Now A[u,j] will be 0, since A[u,j] - A[i,j] * A[u,j] = A[u,j] - 1 * A[u,j] = 0.
    end for
    i := i + 1
  end if
  j := j + 1
end while

Code: Alles auswählen

def gaus(matrix):
        (m, n) = (len(matrix), len(matrix[0]))  # Groesse der Matrix bestimmen
        i = 0
        j = 0
        # Index anpassen, denn 3+2 entspricht 0-2 und 0-1
        m -= 1
        n -= 1
        while i <= m and j <= n:
                maxi = i
                for k in range (i+1,m+1):
                        if matrix[k][j] > matrix[maxi][j]:
                                maxi = k
                if matrix[maxi][j] != 0:
                        # Reihen tauschen
                        line = matrix[i]
                        matrix[i] = matrix[maxi]
                        matrix[maxi] = line
                        # jede Spalte in Reihe i durch den Wer in [i][j] teilen
                        for spalte in range (0,n+1):
                                matrix[i][spalte] /= matrix[i][j]
                        # matrix[u][j]* Reihe i von Reihe u abziehen
                        for u in range (i,m+1):
                                for v in range (0,n+1):
                                        matrix[u][v] -= matrix[u][j]*matrix[i][v]
                        i = i+1
                j = j+1

matrix = [[2.0, 1.0, -1.0, 8.0],
        [-3.0, -1.0, 2.0, -11.0],
        [-2.0, 1.0, 2.0, -3.0]]

gaus(matrix)
print matrix
Freue mich schon auf kreative Ideen. :wink:

Verfasst: Mittwoch 18. April 2007, 13:57
von BlackJack
Also ich sehe mindestens in Zeile 20 ein Problem: `matrix[j]` wird zum Teilen benutzt, ändert sich aber im Laufe der Schleife zu 1, d.h. alle Elemente rechts davon werden grundsätzlich durch 1 geteilt.

Ein ähnliches Problem kann bei der Subtraktionsschleife zuschlagen.

Verfasst: Mittwoch 18. April 2007, 14:26
von Jemand
Hi,

So steht es ja auch im Pseudocode:

Code: Alles auswählen

divide each entry in row i by A[i,j] 
Now A[i,j] will have the value 1
Es ist auch Sinn des Algorithmus, dass die erste Zahl jeder Zeile, die ungleich 0 ist, eine 1 ist.

Trotzdem komme ich aber am Ende nicht zu einem sinnvollen Ergebnis.

Verfasst: Mittwoch 18. April 2007, 15:05
von Rebecca
Jemand hat geschrieben:Es ist auch Sinn des Algorithmus, dass die erste Zahl jeder Zeile, die ungleich 0 ist, eine 1 ist.
Schon. Du darfst aber nicht die anderen Zahlen in der Reihe durch matrix[j] teilen, weil das ja 1 wird. Stattdessen musst du durch den Wert teilen, den matrix[j] am Anfang hatte, bevor er zu 1 wurde.

Verfasst: Mittwoch 18. April 2007, 15:18
von Jemand
Rebecca hat geschrieben:
Jemand hat geschrieben:Es ist auch Sinn des Algorithmus, dass die erste Zahl jeder Zeile, die ungleich 0 ist, eine 1 ist.
Schon. Du darfst aber nicht die anderen Zahlen in der Reihe durch matrix[j] teilen, weil das ja 1 wird. Stattdessen musst du durch den Wert teilen, den matrix[j] am Anfang hatte, bevor er zu 1 wurde.


Ah, das Dunkle lichtet sich.

Ich hatte schon den Verdacht, dass ich die Listendaten nicht direkt nutzen kann, um sie zu multiplizieren, aber was ihr schreibt ist natürlich logisch.

Verfasst: Mittwoch 18. April 2007, 15:51
von mkesper

Code: Alles auswählen

i := 1
Habe ich noch nie in Python gesehen, erinnert mich an Pascal...

Verfasst: Mittwoch 18. April 2007, 16:55
von BlackJack
Das ist ja auch kein Python sondern der Algorithmus als "Pseudocode".

Verfasst: Mittwoch 18. April 2007, 20:28
von mkesper
:oops:

Verfasst: Donnerstag 19. April 2007, 09:07
von BlackJack
@Jemand: Beim suchen der Zeile mit dem vom Betrag her grössten Element in der entsprechenden Spalte, hast Du übrigens die `abs()`-Funktion vergessen.