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);
// ...
}
}
}