Adloun

Remonter un système triangulaire, sans al.solve

Exercice d'entraînement · niveau 3 (difficile) · mathématiques approfondies (ECG 1re année), chapitre 11 — Informatique et algorithmique · Matrices et rang

Énoncé

Écrire une fonction remontee(U, B) qui résout lorsque est triangulaire supérieure à coefficients diagonaux non nuls, en n'employant que des boucles. Justifier la correction et compter les opérations, puis contrôler avec al.solve sur , .

Corrigé

Ce qu'on montre. Que la dernière équation d'un système triangulaire ne contient qu'une inconnue, et qu'on remonte ensuite ligne par ligne — c'est l'étape finale de toute résolution par le pivot.

Le principe. La -ième ligne de s'écrit Si l'on connaît déjà , alors s'en déduit : division licite puisque . On calcule donc les inconnues de la dernière vers la première.

Le programme.

import numpy as np
import numpy.linalg as al

def remontee(U, B):
    """Resout U X = B, U triangulaire superieure a diagonale non nulle."""
    n = np.shape(U)[0]
    X = np.zeros(n)
    for i in range(n - 1, -1, -1):     # de la derniere ligne a la premiere
        s = B[i]
        for j in range(i + 1, n):      # ce qui est deja connu
            s = s - U[i, j] * X[j]
        X[i] = s / U[i, i]
    return X

U = np.array([[2., 1., -1.],
              [0., 3.,  2.],
              [0., 0.,  4.]])
B = np.array([5., 8., 12.])
print(remontee(U, B))
print(al.solve(U, B))

La correction. L'invariant est : avant le tour d'indice , les cases contiennent les valeurs correctes. Il est vrai avant le premier tour (, aucune case à garantir). S'il est vrai avant le tour , la boucle interne calcule exactement , et la division par donne la valeur correcte de : l'invariant vaut avant le tour . Après le tour , toutes les cases sont correctes.

Le coût. Le tour effectue multiplications et une division. Au total C'est bien moins que la résolution d'un système quelconque, qui exige d'abord la triangularisation.

Le contrôle à la main. La troisième ligne donne , donc . La deuxième donne , donc . La première donne , donc et . Le programme affiche et al.solve affiche la même chose.

Vérification directe. ; ; . Les trois équations sont satisfaites.

Point délicat. range(n - 1, -1, -1) parcourt bien : la borne est exclue. Écrire range(n - 1, 0, -1) oublierait la première ligne, et la case X[0] resterait nulle — erreur silencieuse, car le programme ne signalerait rien.

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.