Fix: Correct jacobi, gauss, cholesky

This commit is contained in:
Namu
2025-10-19 19:03:43 +02:00
parent b04a54cad7
commit 128e07d420
5 changed files with 133 additions and 96 deletions

72
ex2.py
View File

@@ -1,11 +1,29 @@
"""
Ici, on implémente gauss
"""
import numpy as np
from ex1 import resolve_up
from ex1 import resolve_up, resolve_down
def gauss(A: np.array, b: np.array) -> (np.array, np.array):
def est_symetrique_definie_positive(A) -> bool:
"""
Vérifie que A = A^t et que toutes les valeurs propres soit positive
:param A:
:return:
"""
# Symétrie (avec tolérance pour les flottants)
sym = np.allclose(A, A.T)
# Définie positive : toutes les valeurs propres > 0
valeurs_propres = np.linalg.eigvals(A)
definie_positive = np.all(valeurs_propres > 0)
return sym and definie_positive
def gauss(A, b):
"""
Pas de condition, mais pas optimal non plus.
:param A: Une matrice
:param b: Un vecteur
:return: A triangularisée et b modifié en conséquence.
"""
n = len(A)
for k in range(n): # k = pivot
for i in range(k+1, n): # i = ligne en dessous du pivot
@@ -13,24 +31,25 @@ def gauss(A: np.array, b: np.array) -> (np.array, np.array):
A[i, k:] -= g * A[k, k:] # row operation on A
b[i] -= g * b[k] # same row operation on b
return A, b # matrice triangularisé et le b modifié
return A, b # matrice triangularisée et le vecteur b modifié
def cholesky(A: np.array) -> np.array:
L = np.zeros(A)
L = np.sqrt(A[0, 0])
m = len(A)
# first column
for i in range(1, m):
L[i, 0] = A[i, 0] / L[0, 0]
# généralisation k = 2, ..., m
for k in range(1, m):
# diagonale
L[k, k] = np.sqrt(A[k, k] - np.sum(L[k, :k]**2))
for i in range(k+1, m):
for j in range(k-1):
L[i,k] = (A[i,k] - np.sum(L[i, j] * L[k, j])) / L[k, k]
def cholesky(A):
if not est_symetrique_definie_positive(A):
raise ValueError('Matrice non symétrique définie positive')
m = A.shape[0] # Taille de la matrice (m x m)
L = np.zeros_like(A, dtype=np.float32) # Matrice L initialisée à zéro
for j in range(m): # Parcourt chaque colonne j de 0 à m-1
for i in range(j, m): # Parcourt chaque ligne i de j à m-1
s = sum(L[i, k] * L[j, k] for k in range(j)) # Somme des produits L[i,k] * L[j,k] pour k < j
if i == j: # Élément diagonal
L[i, j] = np.sqrt(A[i, i] - s) # Calcul de la racine carrée pour la diagonale
else: # Élément hors diagonale
L[i, j] = (A[i, j] - s) / L[j, j] # Calcul des éléments hors diagonale
return L
@@ -47,8 +66,17 @@ if __name__ == '__main__':
A_triangle, b_gauss = gauss(A, b)
print(f"A triangulsarisée:\n {A_triangle}")
x = resolve_up(A, b_gauss)
x = resolve_up(A_triangle, b_gauss)
print(f"x={x}")
A = np.array([
[4, 1, 1, 1],
[1, 5, 2, 1],
[1, 2, 6, 2],
[1, 1, 2, 7]
])
L = cholesky(A)
print(f"L\n {L}")
print(f"L: {L}")
x = resolve_down(L, b)
print(f'x: {x}')