Cholesky Zerlegung

Lernziele

  • Sie können einen mathematischen Algorithmus in Python umsetzen.

  • Sie können mit Hilfe der Cholesky Zerlegung Lösungen linearer Gleichungssysteme berechnen.

  • Sie kennen die beiden verschiedenen Formen der Cholesky Zerlegung.

Theorie

Die LU-Zerlegung, welche im letzten Praktikum betrachtet wurde, kann prinzipiell auf beliebige Gleichungssysteme mit regulären Matrizen angewandt werden. In vielen Anwendungen treten jedoch Matrizen auf, die zusätzliche Struktureigenschaften haben. In vielen Fällen ist die Matrix {em positiv definit} und symmetrisch. In dem Fall kann der Rechenaufwand um einen Faktor 2 reduziert werden. Zu dem ist keine Pivotisierung notwendig. Die Cholesky-Zerlegung setzt diese Eigenschaftenvoraus und wird mit unter auch zum Testen ob eine Matrix positiv definit ist, benutzt.

Aufgabe

In einem ersten Schritt dieses Praktikums wird die Cholesky-Zerlgung implementiert und getestet.

  • Implementieren Sie die Cholesky-Zerlegung gemäss Algorithmus 2.5 im Skript. Benutzen Sie dazu die folgende Funktionsdefinition und Rückgabe:

    def mychol(A):
        # Vektor für die Diagonale
        d = np.zeros(A.shape[0])
        # Matrix für die untere Dreiecksmatrix
        L = np.zeros_like(A) # oder np.eye(A.shape[0])
    
        <snipp selber machen>
    
    return d,L
    

    Vorsicht bei der Anwendung: es wird davon ausgegangen, dass \(L\) eine normierte untere Dreiecksmatrix ist. Daher wird die Diagonale nicht mit 1 gefüllt, was abhängig vom Algorithumus für das Vorwärts- und Rückwärtseinsetzen auch nicht notwendig ist.

  • Testen Sie den Code in dem Sie

    • die Zerlegung,

    • das Residuum und

    • die Lösung testen.

    Letzteres benötigt die exakte Lösung. Sie können gemäss dem Skript unten vorgehen.

     1#Test Cholesky-Zerlegung
     2n = 7 # Dimension der Koeffizientenmatrix
     3for k in range(1000):
     4    A = np.array(np.random.rand(n,n))
     5    # positiv definite Matrix
     6    ATA = A.T@A
     7    x_ref = np.array(np.random.rand(n))
     8    # rechte Seite für gegebenes x berechnen
     9    b = ATA@x_ref
    10    # Lösen des Gleichungssystems
    11    d,L = mychol(ATA)
    12    z = <snipp, selber machen> # Vorwaertseinsetzen
    13    x = <snipp, selber machen> # Rückwärtseinsetzen
    14    # Test der Zerlegung
    15    assert( np.linalg.norm(ATA-L@np.diag(d)@L.T) < 1e-8)
    16    # Test des Residuums
    17    assert(np.linalg.norm(ATA@x-b) < 1e-8)
    18    try:
    19        assert( np.linalg.norm(x-x_ref)/np.linalg.norm(x_ref) < 1e-8)
    20    except:
    21        print('Vorsicht: relativer Fehler',np.linalg.norm(x-x_ref)/np.linalg.norm(x_ref))