next up previous contents index
Next: Argument tableau pluridimensionnel d'une Up: No Title Previous: Tableaux à plusieurs dimensions

Résolution de systèmes linéaires

   

La méthode de Gauss transforme un système linéaire en un système triangulaire équivalent. L'idée est de résoudre la première équation en tex2html_wrap_inline5141 , puis d'éliminer tex2html_wrap_inline5141 des équations suivantes, ensuite de résoudre la seconde équation en tex2html_wrap_inline5626 , puis d'éliminer tex2html_wrap_inline5626 des équations suivantes, et ainsi de suite. Initialement, on a le système de N équations à N inconnues :

displaymath5616

Les fonctions implémentant cet algorithme vont opérer sur les tableaux globaux :

     

#define N 10
double a[N][N];   /* la matrice */
double b[N];      /* le membre droit */
double x[N];      /* la solution */

La première ligne, << # define N 10 >>, est une directive de (macro-)définition du préprocesseur ; celui-ci substituera << 10 >> à << N >> dans toutes les lignes suivantes du programme avant que le programme ne soit compilé. Une telle directive a dans ce cas précis l'intérêt de paramétrer la taille des tableaux, ce qui ne serait pas possible si N était une variable, même spécifiée const.

Pour décrire l'algorithme, on posera tex2html_wrap_inline5634 et tex2html_wrap_inline5636 . Après k itérations, on obtient le système :

displaymath5617

Les k premières équations ne seront plus modifiées. Il faut maintenant éliminer tex2html_wrap_inline5642 . On n'utilise pas nécessairement l'équation tex2html_wrap_inline5644 car il se peut que le coefficient tex2html_wrap_inline5646 soit nul ; on va donc chercher un indice l, avec tex2html_wrap_inline5650 , tel que tex2html_wrap_inline5652 ait la plus grande valeur absolue (pour minimiser les problèmes d'arrondi) :

int pivot(int k) {
/* cherche l'indice d'un pivot dans k..N-1 */
  int i;
  int l = k;
  double max = fabs(a[k][k]);
  for (i=k+1; i<N; i++) {
    if (fabs(a[i][k]) > max) {
      l = i;
      max = fabs(a[i][k]);
    }
  }
  printf("pivot(%d) = %d\n", k, l);
  return l;
}

Si la valeur du pivot est non nulle, on échange les équations tex2html_wrap_inline5644 et tex2html_wrap_inline5656 :

void echanger(int k, int l) {
/* échange les lignes k et l du système
   à partir de la colonne k */
  double temp;
  int j;
  for (j=k; j<N; j++) {
    temp = a[k][j];
    a[k][j] = a[l][j];
    a[l][j] = temp;
  }
  temp = b[k];
  b[k] = b[l];
  b[l] = temp;
}

Après cet échange, les k+1 premières équations ne seront plus modifiées. On a donc désormais tex2html_wrap_inline5660 . On peut donc éliminer tex2html_wrap_inline5642 de la ligne i ( tex2html_wrap_inline5666 ) en ajoutant cette ligne à tex2html_wrap_inline5668 fois la ligne k : on obtient ainsi les coefficients du système à l'issue de cette k+1-ème itération, par << pivotage >> :

displaymath5618

Ceci se transcrit en la procédure pivoter :

void pivoter(int k) {
/* élimine x_k des lignes k+1..N-1 */
  int i,j;
  for (i=k+1; i<N; i++) {
    double q = a[i][k]/a[k][k];
    b[i] = b[i] - q * b[k];
    for (j=k+1; j<N; j++) {
      a[i][j] = a[i][j] - q * a[k][j];
    }
  }
}

Si, à l'une des itérations, la valeur du pivot est nulle, c'est que le système n'est pas régulier, et la résolution s'arrête (c'est le rôle du break   dans la fonction gauss). Si le système est régulier (c'est-à-dire de rang N), il est transformé en un système triangulaire en N-1 itérations.

int gauss() {

/* si le système "a x = b" est régulier, le transforme en un 
   système triangulaire en N-1 itérations et retourne 1, 
   sinon retourne 0 */

  int k, l;
  int inversible;
  for (k=0; k<N-1; k++) {
    l = pivot(k);
    inversible = (fabs(a[l][k]) > DBL_EPSILON);
    if (inversible) {
      if (l > k) {
        echanger(k,l);
      }
      pivoter(k);
    } else break;
  }
  return inversible;
}

Il reste à résoudre un système triangulaire supérieur :

int systeme_triangulaire() {

/* calcule la solution x d'un système triangulaire supérieur 
   "a x = b" et retourne 1 s'il est régulier, 
    et retourne 0 sinon */

  int i, j;
  double v;
  for (i=N-1; i>=0; i--) {
    if (fabs(a[i][i])<EPS) {
      return 0;
    } else {
      v = b[i];
      for (j=i+1; j<N; j++) {
        v = v - a[i][j]*x[j];
      }
      x[i] = v/a[i][i];
    }
  }
  return 1;
}

La complexité de cet algorithme est en tex2html_wrap_inline5678 .


next up previous contents index
Next: Argument tableau pluridimensionnel d'une Up: No Title Previous: Tableaux à plusieurs dimensions

Rene Lalement
Mon Sep 30 18:22:54 MET 1996