Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
4144 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Inversion de matrices : bug etrange

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Inversion de matrices : bug etrange

n°1319625
D_P_
p'tit gros
Posté le 06-03-2006 à 17:06:00  profilanswer
 

Bonjour,
j'ai ecrit le code suivant en C pour inverser de matrices de taille dim*dim. L'algo. (Gauss-Jordan) provient de ce que j'ai trouve sur le net.

Code :
  1. int inverseMatrix(double ** matrix, double ** inversedMatrix, int dim){
  2.   int i, j, k;
  3.   double ** tempMatrix = malloc(sizeof(*double)*dim); /* Allocation of matrix memory */
  4.   for(i=0 ; i<dim ; i++){
  5.     tempMatrix = malloc(sizeof(double)*dim*2);
  6.   }
  7.   for(i=0 ; i<dim ; i++){ /* initialization of matrix values */
  8.     for(j=0 ; j<dim ; j++){
  9.       tempMatrix[i][j] = matrix[i][j];
  10.       if (i==j) {
  11. tempMatrix[i][j+dim] = 1.0;
  12.       } else {
  13. tempMatrix[i][j+dim] = 0.0;
  14.       }
  15.     }
  16.   }
  17.   printf("tempMatrix:\n" );
  18.   for(i=0 ; i<dim ; i++){
  19.     for(j=0 ; j<dim*2 ; j++){
  20.       printf("%f  ", tempMatrix[i][j]);
  21.     }
  22.     printf("\n" );
  23.   }
  24.   for (i=0 ; i<dim ; i++){
  25.     if (tempMatrix[i][i]!=0){
  26.       for(j=0 ; j<2*dim ; j++){
  27.         tempMatrix[i][j] = tempMatrix[i][j]/tempMatrix[i][i];
  28.       }
  29.       for(k=0 ; k<dim ; k++){
  30. if (k!=i){
  31.   for (j=0 ; j<2*dim ; j++){
  32.     printf("tempMatrix[%i][%i] : %f\n", k, j, tempMatrix[k][j]);
  33.     tempMatrix[k][j] = tempMatrix[k][j] - (tempMatrix[k][i]*tempMatrix[i][j]);
  34.     printf("puis tempMatrix[%i][%i]-tempMatrix[%i][%i](%f)*tempMatrix[%i][%i](%f) : %f\n", k, j, k, i, tempMatrix[k][i], i, j, tempMatrix[i][j], tempMatrix[k][j]);
  35.   }
  36. }
  37.       }
  38.     } else {
  39.       for(i=0 ; i<dim ; i++){ /* free the allocated memory */
  40. free(tempMatrix[i]);
  41.       }
  42.       free(tempMatrix);
  43.       return 0;
  44.     }
  45.   }
  46.   printf("tempMatrix:\n" );
  47.   for(i=0 ; i<dim ; i++){
  48.     for(j=0 ; j<dim*2 ; j++){
  49.       printf("%f  ", tempMatrix[i][j]);
  50.     }
  51.     printf("\n" );
  52.   }
  53.   for (i=0 ; i<dim ; i++){ /* copy of the resulting matrix in the returned variable */
  54.     for(j=0 ; j<dim ; j++){
  55.       inversedMatrix[i][j] = tempMatrix[i][dim+j];
  56.     }
  57.   }
  58.   for(i=0 ; i<dim ; i++){ /* free the allocated memory */
  59.     free(tempMatrix[i]);
  60.   }
  61.   free(tempMatrix);
  62.   return 1;
  63. }


Ce code me donne toujours en sortie une matrice diagonale avec toutes les valeurs diagonales a 1. J'ai donc ajoute les printf pour voir ce qui se passe et voila : quand je fais [i]"tempMatrix[k][j] = tempMatrix[k][j] - (tempMatrix[k][i]*tempMatrix[i][j]);", ca me sort toujours 0.00 ou 1.00 mais jamais les bonnes valeurs (genre il me fait 0.355235 - (0.0000 * 1.0000) = 0.0 :heink: ).
Si quelqu'un a une idee... :sweat:


Message édité par D_P_ le 06-03-2006 à 18:36:32
mood
Publicité
Posté le 06-03-2006 à 17:06:00  profilanswer
 

n°1319674
bjone
Insert booze to continue
Posté le 06-03-2006 à 17:41:53  profilanswer
 

Code :
  1. double ** tempMatrix = malloc(sizeof(double)*2*dim*dim); /* Allocation of matrix memory */
  2. for(i=0 ; i<dim ; i++){
  3.    tempMatrix[i] = malloc(sizeof(double)*dim*2);
  4. }


 
1) quel est l'interêt d'avoir un pointeur par ligne ?
2) ton premier malloc est faux tu n'as alloues pas un bloc de pointeurs, mais toute une matrice
   => double ** tempMatrix = malloc(sizeof(double*)*dim)  
        là tu as un bloc mémoire maintenant des pointeurs pour chaque ligne
 
3) pourquoi des dim*2 ?
 
4) de toutes manières, sapu ce genre de trucs utilise juste un "double *matrix" en temporaire/paramètre.
 
5) j'ai pas regardé l'algo, mais c'est vraiment nécessaire de faire une matrice temporaire ?

n°1319700
skelter
Posté le 06-03-2006 à 18:07:45  profilanswer
 

il y a des bibliotèques en C pour manipuler des matrices, comme gsl

Message cité 1 fois
Message édité par skelter le 06-03-2006 à 18:07:53
n°1319706
D_P_
p&#039;tit gros
Posté le 06-03-2006 à 18:13:47  profilanswer
 

bjone a écrit :

Code :
  1. double ** tempMatrix = malloc(sizeof(double)*2*dim*dim); /* Allocation of matrix memory */
  2. for(i=0 ; i<dim ; i++){
  3.    tempMatrix[i] = malloc(sizeof(double)*dim*2);
  4. }


 
1) quel est l'interêt d'avoir un pointeur par ligne ?
2) ton premier malloc est faux tu n'as alloues pas un bloc de pointeurs, mais toute une matrice
   => double ** tempMatrix = malloc(sizeof(double*)*dim)  
        là tu as un bloc mémoire maintenant des pointeurs pour chaque ligne
 
3) pourquoi des dim*2 ?
 
4) de toutes manières, sapu ce genre de trucs utilise juste un "double *matrix" en temporaire/paramètre.
 
5) j'ai pas regardé l'algo, mais c'est vraiment nécessaire de faire une matrice temporaire ?


 
1) si je fais uniquement un

Code :
  1. double ** tableau = malloc(dim*dim*2*sizeof(double))

ca risque de me sortir une segmentation fault non ? En tout cas ca me le faisait sur une autre partie de prog ya pas longtemps, et la solution c'etait ca...
 
2) exact, j'ai corrige mais ca ne vient pas de la
 
3) ben pour inverser une matrice A de dimension n*n, je pose G=[A|I], puis j'applique Gauss pour obtenir G = [I|A^(-1)], et donc A^(-1)
 
4) bien mais moi, pas
 
5) ben je pense, cf. 3)
Cela dit, c'est pas le fait d'utiliser ou non une matrice temporaire qui devrait changer quoi que ce soit au resultat, non ? (hors performances)
 
Je pense pas que le probleme provienne d'une histoire d'allocation de tableau : le printf de la ligne 36 m'assure que je vais chercher les bonnes valeurs, mais le resultat de l'operation est faux ! Cela dit ca fait que 15 jours que je fais du C et je suis toujours sur le cul quand je vois d'ou proviennent mes erreurs :sweat:

Message cité 2 fois
Message édité par D_P_ le 06-03-2006 à 18:36:57
n°1319707
D_P_
p&#039;tit gros
Posté le 06-03-2006 à 18:15:33  profilanswer
 

skelter a écrit :

il y a des bibliotèques en C pour manipuler des matrices, comme gsl

C'est ce que j'avais cherche en premier, mais j'avais rien trouve qui me convenait. Je vais tester gsl pour voir.
 
Neanmoins, je suis quand meme curieux de voir d'ou vient ce bug  :heink: :whistle:

Message cité 2 fois
Message édité par D_P_ le 06-03-2006 à 18:16:33
n°1319709
skelter
Posté le 06-03-2006 à 18:20:56  profilanswer
 

D_P_ a écrit :

C'est ce que j'avais cherche en premier, mais j'avais rien trouve qui me convenait. Je vais tester gsl pour voir.


 
sur cette page il y a un code (get_inverse) qui tient en 10 lignes avec gsl, tu peux t'en inspirer

n°1319714
skelter
Posté le 06-03-2006 à 18:26:29  profilanswer
 

D_P_ a écrit :


Neanmoins, je suis quand meme curieux de voir d'ou vient ce bug  :heink: :whistle:


 
rien que cette allocation
 

Code :
  1. double ** tempMatrix = malloc(sizeof(double)*2*dim*dim); /* Allocation of matrix memory */
  2.     for(i=0 ; i<dim ; i++){
  3.       tempMatrix[i] = malloc(sizeof(double)*dim*2);
  4.     }


 
dans le premier malloc tu peux expliquer pourquoi 'sizeof(double)' au lieu de sizeof(double *) ? (ou mieux, 'sizeof *tempMatrix')
et pourquoi '*2' ?
 
aussi pourquoi tu parcours les colonnes jusqu'a dim*2 et des fois jusqu'a dim ?

n°1319717
D_P_
p&#039;tit gros
Posté le 06-03-2006 à 18:35:15  profilanswer
 

skelter a écrit :

rien que cette allocation
 

Code :
  1. double ** tempMatrix = malloc(sizeof(double)*2*dim*dim); /* Allocation of matrix memory */
  2.     for(i=0 ; i<dim ; i++){
  3.       tempMatrix[i] = malloc(sizeof(double)*dim*2);
  4.     }


 
dans le premier malloc tu peux expliquer pourquoi 'sizeof(double)' au lieu de sizeof(double *) ? (ou mieux, 'sizeof *tempMatrix')
et pourquoi '*2' ?
 
aussi pourquoi tu parcours les colonnes jusqu'a dim*2 et des fois jusqu'a dim ?


 
J'ai deja repondu a ces questions plus haut. Je vais editer le code pour virer les conneries.

n°1319719
bjone
Insert booze to continue
Posté le 06-03-2006 à 18:41:37  profilanswer
 

D_P_ a écrit :

1) si je fais uniquement un

Code :
  1. double ** tableau = malloc(dim*dim*2*sizeof(double))

ca risque de me sortir une segmentation fault non ? En tout cas ca me le faisait sur une autre partie de prog ya pas longtemps, et la solution c'etait ca...
 
2) exact, j'ai corrige mais ca ne vient pas de la
 
3) ben pour inverser une matrice A de dimension n*n, je pose G=[A|I], puis j'applique Gauss pour obtenir G = [I|A^(-1)], et donc A^(-1)
 
4) bien mais moi, pas
 
5) ben je pense, cf. 3)
Cela dit, c'est pas le fait d'utiliser ou non une matrice temporaire qui devrait changer quoi que ce soit au resultat, non ? (hors performances)
 
Je pense pas que le probleme provienne d'une histoire d'allocation de tableau : le printf de la ligne 41 m'assure que je vais chercher les bonnes valeurs, mais le resultat de l'operation est faux ! Cela dit ca fait que 15 jours que je fais du C et je suis toujours sur le cul quand je vois d'ou proviennent mes erreurs :sweat:


 
 
4) bien moi si, parceque justement ça évite tes bugs et c'est plus performant.
 
pour une matrice carré de dimension "dim" soit dim² éléments, soit tu fais:
 
type **LinePtrs=malloc( dim * sizeof( type * ) );  
for( int i=0 ; i < dim ; ++i )
   LinePtrs[i]=malloc( dim * sizeof(type) );  
 
soit:
 
type *Elements=malloc( dim*dim *sizeof(type) );

n°1319722
bjone
Insert booze to continue
Posté le 06-03-2006 à 18:45:47  profilanswer
 

oki pour le dim*2 vu que c'est le pivot de gauss.

mood
Publicité
Posté le 06-03-2006 à 18:45:47  profilanswer
 

n°1319724
D_P_
p&#039;tit gros
Posté le 06-03-2006 à 18:49:07  profilanswer
 

bjone a écrit :

4) bien moi si, parceque justement ça évite tes bugs et c'est plus performant.


ok pour la performance, pas pour les bugs. Je trouve plus lisible et facile a manipuler d'avoir un tableau a 2 dimensions que de faire des tab[i*dim+j] a foison. En quoi l'utilisation d'un tableau a deux dimensions serait plus propice aux bugs ?
 
 

bjone a écrit :


pour une matrice carré de dimension "dim" soit dim² éléments, soit tu fais:
 
type **LinePtrs=malloc( dim * sizeof( type * ) );  
for( int i=0 ; i < dim ; ++i )
   LinePtrs[i]=malloc( dim * sizeof(type) );  
 
soit:
 
type *Elements=malloc( dim*dim *sizeof(type) );


La-dessus on est d'accord.

n°1319730
bjone
Insert booze to continue
Posté le 06-03-2006 à 19:02:21  profilanswer
 

D_P_ a écrit :

ok pour la performance, pas pour les bugs. Je trouve plus lisible et facile a manipuler d'avoir un tableau a 2 dimensions que de faire des tab[i*dim+j] a foison. En quoi l'utilisation d'un tableau a deux dimensions serait plus propice aux bugs ?
 
 
 
La-dessus on est d'accord.


 
je parlais de -tes- bugs: confusion entre un tableau à 2 dimensions et un tableau de pointeurs. (enfin tableau n'est pas le bon terme)


Message édité par bjone le 06-03-2006 à 19:02:36
n°1319756
Emmanuel D​elahaye
C is a sharp tool
Posté le 06-03-2006 à 19:51:19  profilanswer
 

D_P_ a écrit :

1) si je fais uniquement un

Code :
  1. double ** tableau = malloc(dim*dim*2*sizeof(double))

ca risque de me sortir une segmentation fault non ?  


Oui, bien sûr. Tu as choisi une implémentation par tableau dynamique de tableaux dynamique. Ton implémentation (corrigée) est correcte.


Message édité par Emmanuel Delahaye le 06-03-2006 à 19:52:37

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Inversion de matrices : bug etrange

 

Sujets relatifs
Multiplication de deux matricesMatrices
[Sockets]Problème étrange[javascript] erreur de parseInt étrange
Les matrices facilement ?[JS] Bug très étrange... Comprends pas !
[VB.NET] Problème étrange...Aide svpProblème dans mon code, résultat étrange
Wanted : biblio c++ avec les matricesinversion MSB/LSB
Plus de sujets relatifs à : Inversion de matrices : bug etrange


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)