Gauß Eliminations Verfahren im Python

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
dugbug
User
Beiträge: 9
Registriert: Donnerstag 3. Juni 2010, 13:08

Hallo erstmal, bin hier neu in diesem Forum allerdings hat mich Python schon gehörig zur Verzweiflung gebracht :)


Wie sie sehen können muß man hier erst überprüfen ob die Eingangsparameter A,b hier die Vorrausetzungen erfüllen damit man das Gauß-Eliminationsverfahren anwenden kann.
Problem 1:
Mein Problem besteht jetzt darin das wenn ich wie hier, die Überprüfungen ob Matrix A singulär, quadratisch und ob sie von der Dimension zum Vektor b paßt, in Subprogramme mache, ich von dem Codeüberprüfungsprogramm unsere Uni für den Fall das A singulär ist (det A =0) eine Fehlermeldung bekommen:

CHECK FUNCTION: gaussSolve
Level 0: Vector Shapes
Function -> OK
Results -> OK
Level 1: Matrix Shapes
Function -> OK
Results -> OK
Level 2: Singular Matrix
Function -> OK
Results -> FAILED <-----------------------
Level 3: Numerics
Function -> OK
Results -> FAILED, Type Error


für die anderen Teile Vectorshapes und Matrix Dimension bekomm ich ein ok,
Jetzt ändere ich die Überprüfung ob Matrix A singulär ist einfach mit "if abs(det A)<0: retrun"ERROR_SINGULAR_Matrix" ohne def Funktion, dann passiert folgendes: Das UNI Codeüberprüfungsprogramm sagt:

CHECK FUNCTION: gaussSolve
Level 0: Vector Shapes
Function -> OK
Results -> OK
Level 1: Matrix Shapes
An undefined error occured! -> Check your code!->FAILED <-----------------------
Level 2: Singular Matrix
Function -> OK
Results -> OK <--------------------
Level 3: Numerics
Function -> OK
Results -> FAILED, Type Error


Ich kann mir das beim besten Willen nicht erklären wie so etwas zustande kommen kann.

Problem 2:

Da ich die Eingangsparameter A,b nicht verändern will speichere ich ihren inhalt mittels
C=A
t=b
trotzdem werden aber A und b verändert wie wenn sie ganz normal die schleifen etc durchlaufen würden.

hier mal mein Kode:

Code: Alles auswählen

# add more modules if necessary
import numpy 

# global precision, use this for "zero" within your code
prec = 1.0e-7 



 
def gaussSolve(A, b) :
    

   
     def checkMatsing(A):  #Ueberprueft ob detA=0
         answ=True   
         detA=numpy.linalg.det(A)
         if abs(numpy.abs(detA))<1.0e-7:
             answ=False
         return answ
         
     def checkVector(b):   #Ueberprueft ob b = (n,1) Vector
         answ=True
         n,m=b.shape
         if m!=1:
             answ=False
         return answ
         
     def checkMatsquares(A):  #Ueberprueft ob A=(n,n) Matrix
         answ=True
         n,m=A.shape
         if n!=m:
             answ=False
         return answ
      
     def checkMatShapes (A,b) : #Ueberprueft ob A,b von der Dimension zusammenpassen
         n,k1=A.shape
         k2,m=b.shape
         answ = True
         if n!=k2:
             answ=False
             
         return answ
      
  
     if checkMatsquares(A):
         return "ERROR MATRIX_DIMENSION"
         
     if checkMatShapes(A,b):       
         return "ERROR MATRIX_DIMENSION" 
         
     if checkVector(b):
         return "ERROR MATRIX_DIMENSION"
         
     if checkMatsing(A):
         return "ERROR SINGULAR_MATRIX"    
     
     
     
     C=A
     t=b   
     n,m=A.shape
     D=3.453
     
     for i in range(n-1):   
         D=C[i][i]
         h=i
         
         for j in range(h,n-1):
             t[j+1][0]=t[j+1][0]-C[j+1][h]/D*t[h][0]
             L=C[j+1][h]
             
             for k in range(h,n):
                 C[j+1][k]=C[j+1][k]-L/D*C[i][k]


     x=numpy.zeros((n,1),numpy.float64)
     i=n-1
     
     while i>=0:
         sum=0  
         
         for j in range(n):
             sum=sum+C[i][j]*x[j]
             
         x[i]=1/C[i][i]*(t[i]-sum)
         i=i-1
         
     return x
     
BlackJack

@dugbug: Ad 2) Mit ``x = y`` bindest Du nur das Objekt das an den Namen `y` gebunden ist zusätzlich an den Namen `x`. Beide Namen beziehen sich danach auf das selbe Objekt. Wenn Du eine Kopie haben möchtest, dann musst Du explizit eine erstellen. `numpy`-Arrays haben dafür zum Beispiel eine `copy()`-Methode.

Anmerkungen zum Quelltext: Wenn `prec` oben definiert wird, dann sollte der Wert sicher nicht im Programm noch einmal als literale "magische" Zahl auftauchen.

`answ` ist ein scheusslicher Name. Lesbarer wäre `answer`, dann braucht man nicht raten und die zwei zusätzlichen Buchstaben verbrauchen auch nicht mehr Strom oder so. ;-) In den meisten Fällen ist es bei Deinem Code aber sowieso reichlich umständlich das Ergebnis erst an einen Namen zu binden. Wenn aufgrund einer Bedingung die zu `True` oder `False` ausgewertet wird, ein Wahrheitswert zurückgegeben werden soll, dann braucht man da keine literalen `True` oder `False` sondern kann einfach das Ergebnis des logischen Ausdrucks als Rückgabewert verwenden. Falls nötig mit ``not`` negiert. Damit bleibt von den ganzen Testfunktionen jeweils nur eine Zeile -- und die Frage ob die wirklich in Funktionen stecken müssen:

Code: Alles auswählen

    def is_singular(A):
        return abs(numpy.linalg.det(A)) < prec

    def check_vector(b):
        return b.shape[1] == 1

    def is_square(A):
        return A.shape[0] == A.shape[1]

    def check_shapes(A, b):
        return A.shape[0] == b.shape[0]
dugbug
User
Beiträge: 9
Registriert: Donnerstag 3. Juni 2010, 13:08

ah ok, danke für die schnelle antwort mal schaun ob ich es jetzt richtig hinbekomme
Antworten