import numpy as np
from numpy.testing import assert_almost_equal
def pivot_gauss(M):
if len(M.shape) != 2 or M.shape[0] != M.shape[1]:
raise ValueError(
f"La fonction ne fonctionne que sur une matrice "
f"carrée mais shape est {M.shape}."
)
M = M.copy()
n = len(M)
I = np.eye(n)
for i in range(n):
p = i
while M[p, i] == 0:
p += 1
if p >= n:
continue
for k in range(p + 1, n):
indice = M[k, i] / M[p, i]
# La matrice M vérifie M[k,:i] == 0
M[k, i:] -= M[p, i:] * indice
# Mais pas la matrice de passage, c'est pourquoi
# il faut appliquer la même transformation sur toute la ligne
I[k, :] -= I[p, :] * indice
for i in range(n):
indice = M[i, i]
if indice != 0:
# La matrice M vérifie M[k,:i] == 0 (triangulaire supérieure)
M[i, i:] /= indice
# Mais pas la matrice de passage.
I[i, :] /= indice
return M, I
def test_pivot_gauss():
v, p = pivot_gauss(np.identity(2))
assert_almost_equal(np.identity(2), v)
assert_almost_equal(np.identity(2), p)
m = np.array([[1, 4], [2, 5]], dtype=np.float64)
v, p = pivot_gauss(m)
assert_almost_equal(v, p @ m)
assert_almost_equal(np.array([[1, 4], [0, 1]], dtype=np.float64), v)
m = np.array([[1, 4, 3], [2, 5, 9], [3, 1, 2]], dtype=np.float64)
v, p = pivot_gauss(m)
assert_almost_equal(v, p @ m)
assert_almost_equal(
np.array([[1, 4, 3], [0, 1, -1], [0, 0, 1]], dtype=np.float64), v
)
test_pivot_gauss()