Pivot de Gauss

[36]:
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()
[ ]:


Notebook on github