Vous êtes sur la page 1sur 5

TP 3 Analyse numrique

cole Hassania des travaux publics Casablanca

La fonction decomposition_LU
Nous commenons par dfinir une fonction decomposition_LU. Elle reoit la matrice A et sa dimension
n comme paramtres et nous renvoie la matrice A modifie de telle sorte qu'elle contienne les deux
matrice L et U.
float **decomposition_LU(float *A[],int n) {
int i,j,k;
float facteur;
for(k=0;k<n-1;k++) {
for(i=k+1;i<n;i++) {
facteur=A[i][k]/A[k][k];
A[i][k]=facteur;
for(j=k+1;j<n;j++) {
A[i][j]=A[i][j]-facteur*A[k][j];
}
}
}
return A;
}

Notons que notre fonction est de type float **, c'est--dire un pointeur sur pointeur, le type
correspondant un tableau deux dimensions en langage C.

Dclarations des variables et entres du programme


Nous dclarons les variables dont on aura besoin lors du programme principal.
float **A;
float *x,*y,*z,*b,*r;
float r_inf=0,aide=0;
int i,j,n;

La raison pour laquelle nous avons opt pour l'utilisation des pointeurs est le fait que ce sera
l'utilisateur qui prcisera la dimension de la matrice A, et de x,y,z,b et r par consquent. Nous aurons
ainsi la possibilit d'allouer l'espace ncessaire pour ces tableaux. Supposons que la dimension est
stocke dans une variable n.
x=(float *)malloc(n*sizeof(float));
y=(float *)malloc(n*sizeof(float));
z=(float *)malloc(n*sizeof(float));
b=(float *)malloc(n*sizeof(float));
r=(float *)malloc(n*sizeof(float));
A=(float **)malloc(n*sizeof(float *));
for (j=0;j<n;j++)
{
A[j]=(float *)malloc(n*sizeof(float));
}

Rsolution du systme
On commence par appeler la fonction decomposition_LU.
A=decomposition_LU(A,n);

Ceci effectue la dcomposition LU de la matrice A et stock L et U dedans pour conomise l'espace


mmoire.
Nous rsolvons ensuite le systme Ly = b puis Ux = y.
y[0]=b[0];
for(i=1;i<n;i++) {
y[i]=b[i];
for(j=0;j<i;j++)
y[i]=y[i]-A[i][j]*y[j];
}
x[n-1]=y[n-1]/A[n-1][n-1];
for(i=n-1;i>=0;i--) {
x[i]=y[i]/A[i][i];
for(j=0;j<i;j++)
x[i]=x[i]-(A[i][j]/A[i][i])*y[j];
}

Raffinement itratif
Nous commenons par calculer la nome infinie du rsidu de la solution que nous venons de trouver.
for(i=0;i<n;i++) {
for(j=0;j<n;j++)
aide=A[i][j]*x[j];
r[i]=b[i]-aide;
if(fabs(r[i])>r_inf)
r_inf=r[i];
}

Aprs, nous effectuons une itration du raffinement itratif.


/* On rsout Lx = r */
z[0]=r[0];
for(i=1;i<n;i++) {
z[i]=r[i];
for(j=0;j<i;j++)
z[i]=z[i]-A[i][j]*z[j];
}
/* On rsout Uy = x */
y[n-1]=z[n-1]/A[n-1][n-1];
for(i=n-1;i>=0;i--) {
y[i]=z[i]/A[i][i];
for(j=0;j<i;j++)
y[i]=y[i]-(A[i][j]/A[i][i])*z[j];
}
/* On prend la nouvelle solution */
for(i=0;i<n;i++)
x[i]=x[i]+y[i];

Notons qu'ici nous n'avons pas appel la fonction decomposition_LU pour rsoudre le systme
correspondant cette itration. Cet appel a t, en effet, dj fait et son rsultat existe toujours dans le
tableau A.

Le programme complet
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
float **decomposition_LU(float *A[],int n) {
int i,j,k;
float facteur;
for(k=0;k<n-1;k++) {
for(i=k+1;i<n;i++) {
facteur=A[i][k]/A[k][k];
A[i][k]=facteur;
for(j=k+1;j<n;j++) {
A[i][j]=A[i][j]-facteur*A[k][j];
}
}
}
return A;
}
int main() {
float **A;
float *x,*y,*z,*b,*r;
float r_inf=0,aide=0;
int i,j,n;
// Allocation dynamique de la mmoire pour la matrice A et les vecteurs x, y et b
printf("Quelle est la dimension de votre matrice carree ? ");
scanf("%d",&n);
x=(float *)malloc(n*sizeof(float));
y=(float *)malloc(n*sizeof(float));
z=(float *)malloc(n*sizeof(float));
b=(float *)malloc(n*sizeof(float));
r=(float *)malloc(n*sizeof(float));
A=(float **)malloc(n*sizeof(float *));
for (j=0;j<n;j++)
{
A[j]=(float *)malloc(n*sizeof(float));
}
// Remplissage de la matrice A et du vecteur b
for(i=0;i<n;i++) {
for(j=0;j<n;j++) {
printf("a(%d,%d) = ",i+1,j+1);
scanf("%f",&A[i][j]);
}
}
for(j=0;j<n;j++) {
printf("b(%d) = ",j);
scanf("%f",&b[j]);
}
// On effectue la dcomposistion LU
printf("\nLa matrice contenant la decomposition LU de A est \n");
A=decomposition_LU(A,n);
// On affice la matrice A modifie
for(i=0;i<n;i++) {
for(j=0;j<n;j++) {
printf("%10.2f",A[i][j]);
}
printf("\n");
}
// On rsout le systme Ly=b
y[0]=b[0];
for(i=1;i<n;i++) {
y[i]=b[i];
for(j=0;j<i;j++)
y[i]=y[i]-A[i][j]*y[j];

}
// On rsout le systme Ux=y
x[n-1]=y[n-1]/A[n-1][n-1];
for(i=n-1;i>=0;i--) {
x[i]=y[i]/A[i][i];
for(j=0;j<i;j++)
x[i]=x[i]-(A[i][j]/A[i][i])*y[j];
}
// On affiche la solution
printf("\nLa solution est x=");
for(i=0;i<n;i++)
printf("%.5f, ",x[i]);
printf("\n\n");
// Nous calculons la norme infinie du rsidu de ce rsultat
for(i=0;i<n;i++) {
for(j=0;j<n;j++)
aide=A[i][j]*x[j];
r[i]=b[i]-aide;
if(fabs(r[i])>r_inf)
r_inf=r[i];
}
printf("La norme infinie du residu de cette solution vaut : %f\n\n",r_inf);
// On procde au rafinement ittratif
/* On rsout Lx = r */
z[0]=r[0];
for(i=1;i<n;i++) {
z[i]=r[i];
for(j=0;j<i;j++)
z[i]=z[i]-A[i][j]*z[j];
}
/* On rsout Uy = x */
y[n-1]=z[n-1]/A[n-1][n-1];
for(i=n-1;i>=0;i--) {
y[i]=z[i]/A[i][i];
for(j=0;j<i;j++)
y[i]=y[i]-(A[i][j]/A[i][i])*z[j];
}
/* On prend la nouvelle solution */
for(i=0;i<n;i++)
x[i]=x[i]+y[i];
// On affiche la solution raffine
printf("\nLa solution est x=");
for(i=0;i<n;i++)
printf("%.5f, ",x[i]);
printf("\n\n");
for(i=0;i<n;i++) {
for(j=0;j<n;j++)
aide=A[i][j]*x[j];
r[i]=b[i]-aide;
if(fabs(r[i])>r_inf)
r_inf=r[i];
}
printf("La norme infinie du residu de cette solution vaut : %f\n\n",r_inf);
}

Conclusion
Nous constatons que la mthode du raffinement itratif n'apporte pas de prcision supplmentaire.
Nous pensons que ceci est d au fait qu'il n'existe pas de fonction dans le langage C qui nous permet
d'imposer des contraintes sur le nombre de chiffres significatifs utiliser. Toutefois, l'implmentation
de la mthode de Gauss avec dcomposition LU dans le langage C reste une belle exprience.