Les 115#115 premières équations ne seront plus modifiées. Il faut
maintenant éliminer 117#117. On n'utilise pas nécessairement l'équation
118#118 car il se peut que le coefficient 119#119
soit nul ; on va donc chercher un indice 120#120, avec 121#121, tel
que 122#122 ait la plus grande valeur absolue (pour minimiser les
problèmes d'arrondi). Si la valeur du pivot est non nulle, on échange
les équations
118#118 et
123#123.
Après cet échange, les 124#124 premières équations ne seront plus
modifiées. On a donc désormais
125#125. On peut donc
éliminer 117#117 de la ligne 107#107 (
126#126) en ajoutant cette
ligne à
127#127 fois la ligne 115#115 : on obtient ainsi les
coefficients du système à l'issue de cette 124#124-ème itération, par «
pivotage » :
public class Gauss { static int pivot(double[][] a, int k) { // cherche l'indice d'un pivot dans k..dim-1 int l = k; double max = Math.abs(a[k][k]); for (int i=k+1; i<dim; i++) { if (Math.abs(a[i][k]) > max) { l = i; max = Math.abs(a[i][k]); } } return l; } static void échanger(double[][] a, double[] b, int k, int l) { // échange les lignes k et l du système double[] ligne = a[k]; a[k] = a[l]; a[l] = ligne; double temp = b[k]; b[k] = b[l]; b[l] = temp; } static void pivoter(double[][] a, double[] b, int k) { // élimine x_k des lignes k+1..dim-1 for (int i=k+1; i<dim; i++) { double q = a[i][k]/a[k][k]; b[i] = b[i] - q * b[k]; for (int j=k+1; j<dim; j++) { a[i][j] = a[i][j] - q * a[k][j]; } } } public static boolean gauss(double[][] a, double[] b) { // si le système "a x = b" est régulier, le transforme // en un système triangulaire en dim-1 itérations et // retourne true, sinon retourne false boolean inversible = false; for (int k=0; k<dim-1; k++) { int l = pivot(k); inversible = (Math.abs(a[l][k]) > EPS); if (inversible) { if (l > k) { échanger(k,l); } pivoter(k); } else break; } return inversible; } public static double[] solutionTriangulaire(double[][] a, double[] b) { // calcule la solution x d'un système triangulaire // supérieur "a x = b" et retourne x s'il est régulier, // et déclenche une exception sinon double[] x = new double[dim]; for (int i=dim-1; i>=0; i--) { if (Math.abs(a[i][i])<EPS) { throw new ArithmeticException("système irrégulier"); } else { double v = b[i]; for (int j=i+1; j<dim; j++) { v = v - a[i][j]*x[j]; } x[i] = v/a[i][i]; } } return x; } }
La fonction solutionTriangulaire ne retourne un tableau solution que si le système est régulier ; sinon, elle déclenche une exception (voir § 5.3). L'utilisation de cet algorithme se fait de la façon suivante :
class GaussTest { public static void main(String[] args) { double[][] membreGauche = new double[][] { ... }; double[] membreDroit = new double[] { ... }; if (Gauss.gauss(membreGauche, membreDroit)) { double[] solution = Gauss.solutionTriangulaire(membreGauche, membreDroit); // ... } } }