Lösen von Gleichungssystem

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
sparklingunicorn
User
Beiträge: 2
Registriert: Dienstag 17. März 2020, 10:34

Hallo,

ich habe als Aufgabe bekommen ein System von Gleichungen der Form Lx=b zu lösen. (L sollte eine nxn untere Dreiecksmatrix sein und b ein n-dimensionaler Vektor.) Ich sollte das ganze mit der "Forward Substitution" Methode lösen...
Ich habe leider keine Ahnung wie ich damit auch nur beginnen sollte und wäre um jede Hilfe dankbar.

Vielen Dank schon mal im Voraus!
Sirius3
User
Beiträge: 17779
Registriert: Sonntag 21. Oktober 2012, 17:20

Hast Du Dir den Algorithmus schon angeschaut? Wo hast Du konkret Probleme, diesen nach Python zu übersetzen?
Benutzeravatar
__blackjack__
User
Beiträge: 13163
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wenn man bei Wikipedia nach „forward substitution“ sucht, kommt man bei der Seite „Triangular matrix“ heraus: https://en.wikipedia.org/wiki/Forward_substitution

Und da verweist der Link zur deutschsprachigen Seite nach „Dreiecksmatrix“: https://de.wikipedia.org/wiki/Dreiecksmatrix

Das sind wie mir scheint zwei sinnvolle Einstiegspunkte ins Thema.

Allgemein: Zerlege das Problem in kleinere Teilprobleme und die auch wieder in kleinere Teilprobleme, solange bis die Teilprobleme so klein sind, das sie jeweils mit einer Funktion mit wenigen Zeilen Code lösbar sind. Teste jede Funktion bevor Du mit der nächsten fortfährst. Wenn eine Funktion nicht das tut was sie soll, kann man sie auch nicht in einer anderen Funktion verwenden die ein grösseres Teilproblem löst, womit diese Funktion dann auch nicht funktionieren kann.

Aus den Teillösungen lassen sich dann grössere Teillösungen erstellen, und am Ende ist dann das Gesamtproblem gelöst.

Bei den Tests nicht nur Testfälle bedenken die ein sinnvolles Ergebnis haben, sondern auch solche die nicht funktionieren. Also ein Teilproblem was gelöst werden will ist der Test ob es sich bei L tatsächlich um eine untere Dreiecksmatrix handelt oder nicht. Wenn ein L übergeben wird das dieser Anforderung nicht entspricht, sollte die Lösungsfunktion nicht irgendwie damit arbeiten und ein Ergebnis liefern, sondern eine Ausnahme auslösen. Auch wichtig ist das die Dimensionen von Matrix und Vektor zusammen passen. Einstiegspunkt könnte so eine Funktion sein:

Code: Alles auswählen

def solve(triangular_matrix, result_vector):
    if not is_lower_triangular_matrix(triangular_matrix):
        raise ValueError("matrix must be a lower triangular matrix")
    if ...:
        raise ValueError("matrix and vector dimensions do not match")
    ...
    return ...
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
sparklingunicorn
User
Beiträge: 2
Registriert: Dienstag 17. März 2020, 10:34

Hallo,

erst einmal Danke. Ich habe jetzt weiter gemacht, aber irgendwie bekomme ich nie den Output, den ich will.
Wo habe ich da meinen Denkfehler? Ich habe versucht es auf eine bestimme Matrix und einen bestimmten Vektor anzuwenden.
Danke nochmal!

Code: Alles auswählen


#!/usr/bin/env python3
import numpy as np
from scipy import linalg

def trinangular_matrix(n):
    L = np.tril(np.ones(n))
    return L

def vector(n):
    b = np.array[np.ones(n)]    
    return b

def is_lower_triangular_matrix(L):
    try:
        L = np.tril(np.ones(n))
        pass
    except:
        raise ValueError("Matrix must be a lower triangular matrix.")

def dimension_vector_and_matrix():
    try:
        m==n
        pass
    except:
        raise ValueError("Matrix and vector dimensions do not match.")
    
    
def tri_solve(L,b):
    n=3
    L=np.tril([2,0,0],[3,1,0],[4,2,1])
    b=np.array[2,3,3]
    
    with L_inverse == np.linalg.inv(L):
        try:
            x=L_inverse * b
            print(x)
        except:
            x != np.array[1.0,0.0,-1.0]
            raise ValueError("L*x is not equal to b.")
    
    return tri_solve

Benutzeravatar
__blackjack__
User
Beiträge: 13163
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@sparklingunicorn: Ich denke mal wenn *Du* das per „forward substitution“ lösen sollst, ist damit *nicht* gemeint das gar nicht selbst zu programmieren und irgendwas fertiges aus einer Bibliothek zu verwenden.

Ansonsten kann man mit Deiner Frage nicht so viel anfangen weil die reichlich unkonkret ist. Welche der gezeigten Funktionen macht denn nicht was Du erwartest? Das kann ja nur *eine* sein, denn man schreibt ja nicht an anderen Funktionen weiter wenn eine nicht funktioniert, denn dadurch repariert die sich ja nicht, sondern man hat am Ende nur noch mehr Funktionen die eventuell gar nicht funktionieren.

Aber da scheint mir in *jfast eder* Funktion irgend ein Unsinn zu stehen der auch ganz einfach und sofort bei versuchen die aufzurufen Ausnahmen kommen. Das sieht aus als würdest Du programmieren durch raten zu versuchen. Das funktioniert nicht.

Einbuchstabige Namen sind nicht gut. Namen sollen dem Leser vermitteln was der Wert bedeutet, das tut `L` oder `b` nicht. Zudem sind Grossbuchstaben für Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase). Alles andere klein_mit_unterstrichen. `L_inverse` ist eine Kombination die es gar nicht geben sollte.

Bei einer Funktion die `is_irgendwas()` heisst, erwartet der Leser das die `True` oder `False` zurück gibt, und nicht nichts oder eine Ausnahme auslöst.

Die ganzen sinnlosen ``pass``-Anweisungen sind, äh, sinnlos.

Keine nackten ``except``\s ohne konkrete Ausnahmen verwenden. Da werden dann *alle* Ausnahmen behandelt, auch die mit denen man gar nicht rechnet. Das macht die Fehlersuche unnötig schwer.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Antworten