next up previous contents index
suivant: La décomposition de Cholesky monter: Algorithmes d'algébre précédent: Le programme   Table des matières   Index

La décomposition LU d'une matrice

C'est l'interprétation matricielle de la méthode de Gauss.
Si A est une matrice carrée d'ordre n, il existe une matrice L triangulaire supérieure, une matrice L triangulaire inférieure, et une matrice P de permutation telles que :
P*A = L*U.
Supposons tout d'abord que l'on peut faire la méthode de Gauss sans échanger des lignes. Mettre des zéros sous la diagonale de la 1-ière colonne (d'ndice 0) de A, reviens à multiplier A par la matrice E0 qui a des 1 sur sa diagonale, comme première colonne :
[1, - A[1, 0]/A[0, 0],... - A[n - 1, 0]/A[0, 0]] et des zéros ailleurs.
Puis si A1 = E1*A, mettre des zéros sous la diagonale de la 2-ière colonne (d'ndice 1) de A1, reviens à multiplier A1 par la matrice E1 qui a des 1 sur sa diagonale, comme deuxième colonne :
[0, 1, - A1[2, 1]/A[1, 1],... - A[n - 1, 1]/A[1, 1]] et des zéros ailleurs.
On continue ainsi jusqu'à mettre des zéros sous la diagonale de la colonne d'indice n - 2, et à la fin la matrice U = En-2*...*E1*E0*A est triangulaire supérieure et on a L = inv(En-2*...*E1*E0).
Le calcul de inv(L) est simple car on a :
- inv(E0) des 1 sur sa diagonale, comme colonne d'indice 0 [1, + A[1, 0]/A[0, 0],... + A[n - 1, 0]/A[0, 0]] et des zéros ailleurs de même inv(Ek) est obtenue à partir de Ek "en changeant les moins en plus".
- la colonne d'indice k de inv(E0)*inv(E1)...inv(En-2) est égale à la colonne d'indice k de Ek.
Lorsqu'il y a à faire une permutation de lignes, il faut répercuter cette permutation sur L et sur U : pour faciliter la programmation on va conserver les valeurs de L et de U dans une seule matrice R que l'on séparera à la fin : U sera la partie supérieure et la diagonale de R L sera la partie inférieure de R, avec des 1 sur sa diagonale.
Voici le programme de séparation :
splitmat(R):={
  local L,U,n,k,j;
  n:=size(R);
  L:=idn(n);
  U:=makemat(0,n,n);
  for (k:=0;k<n;k++){
    for (j:=k;j<n;j++){
      U[k,j]:= R[k,j];
    }
  } 
  for (k:=1;k<n;k++){
    for (j:=0;j<k;j++){
      L[k,j]:= R[k,j];
    }
  }
return (L,U);
};

Le programme ci-dessous, decomplu(A), renvoie la permutation p que l'on a fait sur les lignes, L et U et on a: P*A = L*U.
Voici le programme de décomposition LU qui utilise splitmat ci-dessus :

//A:=[[5,2,1],[5,2,2],[-4,2,1]]
//A:=[[5,2,1],[5,-6,2],[-4,2,1]]
// utilise splitmat
decomplu(A):={
  local B,R,L,U,n,j,k,l,temp,p;
  n:=size(A);
  p:=seq(k,k,0,n-1);
  R:=makemat(0,n,n);
  B:=A;
  l:=0;
//on traite toutes les colonnes
  while (l<n-1) {
    if (A[l,l]!=0){
    //pas de permutations 
    //on recopie dans R la ligne l de A 
    //a partir de la diagonale
      for (j:=l;j<n;j++){R[l,j]:=A[l,j];}
      //on met des zeros sous la diagonale 
      //dans la colonne l
      for (k:=l+1;k<n;k++){
	for (j:=l+1;j<n;j++){
	  A[k,j]:=A[k,j]-A[l,j]*A[k,l]/A[l,l];
	  R[k,j]:=A[k,j];
	} 
	R[k,l]:=A[k,l]/A[l,l];
	A[k,l]:=0;
      }
    l:=l+1;
    }
    else {
      k:=l;
      while ((k<n-1) and (A[k,l]==0)) {
        k:=k+1;
      }
      //si (A[k,l]==0) A est non inversible, 
      //on passe a la colonne suivante
      if (A[k,l]==0) {
	l:=l+1;
      }
      else {
      //A[k,l]!=0) on echange la ligne l et k ds A et R
       for (j:=l;j<n;j++){
        temp:=A[k,j];
        A[k,j]:=A[l,j];
        A[l,j]:=temp;
       };
       for (j:=0;j<n;j++){
        temp:=R[k,j];
        R[k,j]:=R[l,j];
        R[l,j]:=temp;
       }
       //on note cet echange dans  p
       temp:=p[k];
       p[k]:=p[l];
       p[l]:=temp;
     }//fin du if (A[k,l]==0)
    }//fin du if (A[l,l]!=0)
  }//fin du while
  L,U:=splitmat(R);
  return(p,L,U);
};
On tape :
A:=[[5,2,1],[5,2,2],[-4,2,1]]
decomplu(A)
On obtient :
[0,2,1],[[1,0,0],[-4/5,1,0],[1,0,1]],
[[5,2,1],[0,18/5,9/5],[0,0,1]]
On verifie, on tape (car permu2mat(p)=P=inv(P)) :
[[1,0,0],[0,0,1],[0,1,0]]*[[1,0,0],[-4/5,1,0],[1,0,1]]*
[[5,2,1],[0,18/5,9/5],[0,0,1]]
On obtient bien [[5,2,1],[5,2,2],[-4,2,1]]
On tape :
B:=[[5,2,1],[5,-6,2],[-4,2,1]]
decomplu(B)
On obtient :
[0,1,2],,[[1,0,0],[1,1,0],[-4/5,-9/20,1]],
[[5,2,1],[0,-8,1],[0,0,9/4]]
On verifie, on tape :
[[1,0,0],[1,1,0],[-4/5,-9/20,1]]*[[5,2,1],[0,-8,1],[0,0,9/4]]
On obtient bien [[5,2,1],[5,-6,2],[-4,2,1]]
next up previous contents index
suivant: La décomposition de Cholesky monter: Algorithmes d'algébre précédent: Le programme   Table des matières   Index
Documentation de giac écrite par Renée De Graeve