Cholesky-Zerlegung Schritt für Schritt¶
Wir wollen in diesem Beispiel einmal selber nachvollziehen, was die Cholesky Zerlegung Schritt für Schritt berechnet. Wir wollen dazu die Zerlegung der folgenden 4×4 Matrix berechnen
Wir legen die Matrix an:
A = numpy.array([[4, 2, 4, 4], [2, 10, 5, 2], [4, 5, 9, 6], [4, 2, 6, 9]])
und überprüfen, dass diese auch wirklich symmetrisch positiv definit ist, d.h. dass alle Eigenwerte größer 0 sind:
assert(numpy.all(numpy.linalg.eigvals(A) > 0))
dann legen wir eine leere Matrix L an:
L = numpy.zeros((4,4))
Wir erinnern uns, dass wir den Zusammenhang
Nach dieser Formel berechnen L11 (beachten Sie, dass Python die Indizierung bei 0 beginnt!):
print "compute diagonal entry 0"
L[0,0] = sqrt(A[0,0])
print L
und erhalten
Dann berechnen wir die restliche Spalte L21…L41:
# i = 1, k = 0
L[1,0] = 1.0/L[0,0] * A[1,0]
# i = 2, k = 0
L[2,0] = 1.0/L[0,0] * A[2,0]
# i = 3, k = 0
L[3,0] = 1.0/L[0,0] * A[3,0]
Wir können das auch einfacher schreiben als:
print "compute column 0"
L[1:4,0] = 1.0/L[0,0] * A[1:4,0]
print L
sodass direkt alle Einträge L21…L41 aufeinmal berechnet werden. Wir erhalten
Nun können wir für k=2 die zweite Spalte berechnen. Wir beginnen mit dem Diagonaleintrag:
print "compute diagonal entry 1"
L[1,1] = sqrt(A[1,1] - L[1,0]*L[1,0])
print L
und berechnen anschließend wieder die restliche Spalte:
# i = 2, k = 1
L[2,1] = 1.0/L[1,1] * (A[2,1] - L[2,0]*L[1,0])
# i = 3, k = 1
L[3,1] = 1.0/L[1,1] * (A[3,1] - L[3,0]*L[1,0])
oder wieder in kurzer Schreibweise:
print "compute column 1"
L[2:4,1] = 1.0/L[1,1] * (A[2:4,1] - L[2:4,0]*L[1,0])
print L
Analog berechnen wir zuerst L33 und dann den Rest der Spalte:
print "compute diagonal entry 2"
L[2,2] = sqrt(A[2,2] - (L[2,0]*L[2,0] + L[2,1]*L[2,1]))
wobei wir die Summe auch als Skalarprodukt auswerten können:
L[2,2] = sqrt(A[2,2] - numpy.dot(L[2,0:2],L[2,0:2].transpose()))
print L
sowie L32:
L[3,2] = 1.0/L[2,2] * (A[3,2] - L[3,0]*L[2,0] - L[3,1]*L[2,1])
und wieder die Summe Skalarprodukt:
print "compute column 2"
L[3,2] = 1.0/L[2,2] * (A[3,2] - numpy.dot(L[3,0:1],L[2,0:1].transpose()))
print L
Der letzte Eintrag ist wieder ein Diagonaleintrag:
print "compute diagonal entry 3"
L[3,3] = sqrt(A[3,3] - numpy.dot(L[3,0:3],L[3,0:3].transpose()))
print L