probleme inversion matrice

probleme inversion matrice - C - Programmation

Marsh Posté le 28-02-2016 à 14:32:04    

Bonjour,
je dois écrire un programme qui calcule l'inverse d'une matrice à partir de la resolution d'un systeme linéaire.
Mon code ne marche pas, je ne sais pas ou est le probleme.
Voici mon code:
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int n,k,drapeau;
  4. float *A,*x;int c,y;
  5. float *z,*m,*l;
  6. int *b;
  7. int num(int i,int j)
  8. {
  9.     return (i-1)*n+j-1;
  10. }
  11. //saisie de la matrice  
  12. void* saisie(int n,float *A)
  13. {   int i,j;
  14. printf("Donner A ligne/ligne\n" );
  15.     for(i=1;i<=n;i++)
  16.     {
  17.         for(j=1;j<=n;j++)
  18.         {
  19.             scanf("%f",&A[num(i,j)]);
  20.         }
  21.     }
  22. }
  23. //determination de la matrice identité
  24. void matr_id(int n)
  25. {
  26.     int i,j;
  27.     for(i=1;i<=n;i++)
  28.     {
  29.         b[num(i,i)]=1;
  30.     }
  31. }
  32. //Recherche du pivot
  33. int recherche_pivot(int k,float *A)
  34. {
  35.     int i,i0;
  36.     i=k;
  37.     i0=-1;
  38.     do
  39.     {
  40.         if(A[num(i,k)]==0)
  41.             i=i+1;
  42.     }while((A[num(i,k)]==0)&&(i!=n+1));
  43.     if(i!=n+1)
  44.         i0=i;
  45.     return i0;
  46. }
  47. //Permutation
  48. void permutation(int k,int i0,float *A,int *b)
  49. {
  50.     int j;float tampon;
  51.     for(j=1;j<=n;j++)
  52.     {
  53.         tampon=A[num(k,j)];
  54.         A[num(k,j)]=A[num(i0,j)];
  55.         A[num(i0,j)]=tampon;
  56.     }
  57.   matr_id(n);
  58.     for(j=1;j<=n;j++)
  59.     {
  60.        tampon=b[num(k,j)];
  61.         b[num(k,j)]=b[num(i0,j)];
  62.         b[num(i0,j)]=tampon;
  63.     }
  64. }
  65. //Elimination
  66. void elimination(int k,float *A,int *b)
  67. {
  68.     float r;int i,j;
  69.     for(i=k+1;i<=n;i++)
  70.     {
  71.         r=A[num(i,k)]/A[num(k,k)];
  72.         for(j=k;j<=n;j++)
  73.         {
  74.            A[num(i,j)]=A[num(i,j)]-r*A[num(k,j)];
  75.             b[num(i,j)]=b[num(i,j)]-r*b[num(k,j)];
  76.          
  77.         }
  78.      
  79.     }
  80. }
  81. //remontée
  82. void remontee(float *A,int *b,float *x)
  83. {
  84.     int i,j;float g;
  85.   x[num(n,n)]=b[num(n,n)]/A[num(n,n)];
  86.     i=n-1;
  87.     j=i+1;
  88.     while(i>=1)
  89.     {
  90.         x[num(i,j)]=b[num(i,j)];
  91.         g=x[num(i,j)];
  92.         while(j<=n)
  93.         {
  94.             g=g-A[num(i,j)]*x[num(i,j)];
  95.              g=g/A[num(i,i)];
  96.              j++;
  97.         }
  98.         i=i-1;
  99.     }
  100.     }
  101. //affichage du vecteur x
  102. void affiche_vecteur(float *x)
  103. {
  104.     int i,j;
  105.     for(i=1;i<=n;i++)
  106.     {
  107.         for(j=1;j<=n;j++)
  108.     {
  109.         printf("%f\n",x[num(i,j)]);
  110.     }
  111.     printf("\n" );
  112. }
  113. }
  114. int main()
  115. {
  116.     int i,j;
  117.     printf("Donner n\n" );
  118.     scanf("%d",&n);
  119.     y=n*n;
  120.     A=malloc(y*sizeof(float));
  121.    b=calloc(y,sizeof(int));
  122.  
  123.     x=malloc(y*sizeof(float));
  124.     drapeau=0;
  125.     saisie(n,A);
  126.     k=1;
  127.     do
  128.     {
  129.         c=recherche_pivot(k,A);
  130.         if(c==k)
  131.         {
  132.             elimination(k,A,b);
  133.             k=k+1;
  134.         }
  135.         else
  136.         {
  137.             if(c!=-1)
  138.             {
  139.                 permutation(k,c,A,b);
  140.                 elimination(k,A,b);
  141.                 k=k+1;
  142.             }
  143.             else
  144.                 drapeau=1;
  145.         }
  146.     }while((k!=n)&&(drapeau!=1));
  147.     if((k==n)&&(A[num(n,n)]!=0))
  148.     {
  149.         remontee(A,b,&x);
  150.         printf("La matrice est inversible\n" );
  151.        affiche_vecteur(&x);
  152.     }
  153.     else
  154.     {
  155.    
  156.         printf("La matrice n'est pas inversible\n" );
  157.     }
  158.    if(drapeau==1)
  159.         printf("La matrice n'est pas inversible." );
  160.     return 0;
  161. }
  162. Merci d'avance!

Reply

Marsh Posté le 28-02-2016 à 14:32:04   

Reply

Marsh Posté le 28-02-2016 à 16:28:04    

Déjà, enlève les déclarations de variables globales au début de ton programme.
 
Tu y verras plus clair.

Reply

Marsh Posté le 28-02-2016 à 19:17:54    

Si je les enleve et que je les mets dans le  main(),ça ne change rien...

Reply

Marsh Posté le 28-02-2016 à 19:37:28    

Passe un coup de debugger ...

Reply

Marsh Posté le 28-02-2016 à 20:15:00    

Déjà à la base, alloue des objets que tu peux utiliser comme de vrais tableaux C, an faisant A[i][j], plutôt que tes manips avec A[num(i,j)], ça rendra le code plus clair et évitera des appels en masse à num() quand le compilo peut faire cela pour toi.
Un exemple vite pour te donner des idées sur la manière de procéder.
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. float** BuildFloatArray2D(int x, int y)
  4. {
  5.     float** array = NULL;
  6.     if ( x > 0 && y > 0) {
  7.         array = (float **) malloc((x * sizeof(float*)) + (x*y * sizeof(float)));
  8.         for (int i = 0; i < x; ++i) {
  9.             array[i] = (float*)(array + x) + i * y;
  10.         }
  11.     }
  12.     return array;
  13. }
  14. int** BuildIntArray2D(int x, int y)
  15. {
  16.     int** array = NULL;
  17.     if ( x > 0 && y > 0) {
  18.         array = (int **) malloc((x * sizeof(int*)) + (x*y * sizeof(int)));
  19.         for (int i = 0; i < x; ++i) {
  20.             array[i] = (int*)(array + x) + i * y;
  21.         }
  22.     }
  23.     return array;
  24. }
  25. int USER_GetMatrixDimension()
  26. {
  27.     char buffer[256];
  28.     fprintf(stdout, "Veuillez donner la dimension de la matrice carree: " );
  29.     fflush(stdout);
  30.     fgets(buffer, sizeof(buffer), stdin);
  31.     return atoi(buffer);
  32. }
  33. float **USER_CreateMatrix(int n)
  34. {
  35.     char buffer[256];   // augmenter si necessaire
  36.     char *start, *end;
  37.     float **array = BuildFloatArray2D(n, n);
  38.     if (array) {
  39.         fprintf(stdout, "Veuillez donner la matrice ligne à ligne.\n" );
  40.         for (int i = 0; i < n; ++i) {
  41.             fprintf(stdout, "ligne %02d: ", i+1);
  42.             fflush(stdout);
  43.             fgets(buffer, sizeof(buffer), stdin);
  44.             start = buffer;
  45.             for (int j = 0; j < n; ++j) {
  46.                 array[i][j] = strtof(start, &end);
  47.                 start = end;
  48.             }
  49.         }
  50.     }
  51.     return array;
  52. }
  53. void DisplayMatrix(float **array, int n)
  54. {
  55.     for (int i = 0; i < n; ++i) {
  56.         for (int j = 0; j < n; ++j) {
  57.             fprintf(stdout, "%f\t", array[i][j]);
  58.         }
  59.         fprintf(stdout, "\n" );
  60.     }
  61. }
  62. /* int recherche_pivot(float **array, int n, int k) {
  63.     for (int i = k; i < n; ++i) {
  64. if (array[i][k]) return i;
  65.     }
  66.     return -1;
  67. } */
  68. int main()
  69. {
  70.     //
  71.     int n = USER_GetMatrixDimension();
  72.     if (n <= 0) {
  73.         fprintf(stderr, "Dimension incorrecte!\n" );
  74.         return EXIT_FAILURE;
  75.     }
  76.     float **A = USER_CreateMatrix(n);
  77.     if (A == NULL) {
  78.         fprintf(stderr, "Echec à la création de la matrice\n" );
  79.         return EXIT_FAILURE;
  80.     }
  81.     DisplayMatrix(A, n);
  82.     free(A);
  83.     return EXIT_SUCCESS;
  84. }


Comme je dois aller bouffer, j'ai pas le temps de faire un truc 100% clean et commenté. C'est du C99 (pour les boucles for avec variables déclarées dedans).
J'avais commencé à regarder comment coder recherche_pivot, c'est en commentaire.
 
A+,


Message édité par gilou le 28-02-2016 à 20:19:41

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-02-2016 à 21:16:31    

Bon, en regardant elimination,  
b[num(i,j)]=b[num(i,j)]-r*b[num(k,j)];
vous avez défini comme tant un array d'ints. Comme r est un float, il va y avoir de la troncature lors de la conversion de b[num(i,j)]-r*b[num(k,j)], un float, vers b[num(i,j)].
Est-ce sans danger pour la bonne marche de l'algo? j'en doute.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed