Multiplication de deux matrices

Multiplication de deux matrices - C++ - Programmation

Marsh Posté le 19-02-2006 à 10:30:22    

Bonjour à tous,
 
J'ai fait une classe matrice et j'ai surchargé l'opérateur * afin de multiplier 2 matrices, le voilà :
 

Citation :

matrice matrice::operator*(const matrice &m1)
{
 matrice result(ligne,m1.colonne);
 
 if(colonne == m1.ligne) // si nb colonnes = nb lignes de l'autre matrice
 {
  for(int i=0;i<ligne;i++) //pour chaque ligne
  {
   for(int j=0;j<m1.colonne;j++) // pour chaque colonne
   {
    for(int k=0;k<colonne;k++) // produit scalaire
     result.mat[i][j] += mat[i][k]*m1.mat[k][j];
   }
  }
 }
 else
 {
  cout<<"Matrices incompatibles,operation impossible !"<<endl;
 }
 
   return result;
}


 
J'ai également surchargé l'opérateur << d'affichage qui marche très bien (je l'ai testé), mais quand je fais :

Citation :


cout<<"m1 * m2 = "<<(m1*m2)<< endl;
cout<<endl;*/


 
Rien ne s'affiche. J'ai essayé plusieurs choses, mais je n'arrive pas à comprendre pourquoi cela ne veut pas marcher !
 
Merci d'avance pour votre aide.

Reply

Marsh Posté le 19-02-2006 à 10:30:22   

Reply

Marsh Posté le 19-02-2006 à 11:29:35    

Pas mal de possibilités:

  • matrice::operator=(const matrice& ) n'est pas ou est mal définit. Le résultat de ta méthode étant un objet transitoire, je suppose que le compilo fait une copie temporaire de l'objet lors de l'opération (m1 * m2) et appelle l'opération de copie =
  • les coefficients de la matrice résultat ne sont pas initialisés à 0.
  • le nombre de lignes et de colonnes n'est pas initialisé


Pas assez de code pour tirer une conclusion. En debuggant, tu n'as pas trouvé ce qui cloche ?


Message édité par slash33 le 19-02-2006 à 11:37:03
Reply

Marsh Posté le 19-02-2006 à 11:36:25    

pas d'erreur en compilant.
J'ai fait une surcharge de l'opérateur = :
matrice &matrice::operator=(matrice &m1)
// Affectation d'une matrice à une autre
{
 int i,j;
 
 if(&m1 != this)
 {
  for(i=0;i<ligne;i++)
  {
   for(j=0;j<colonne;j++)
   {
    mat[i][j] = m1.mat[i][j];
   }
  }  
 }
 else
 {
  cout << "(matrice) Erreur d\'affectation !" << endl;
 }
 return *this;
}
 
et mon constructeur initialise à 0 :
matrice::matrice(int lig, int col)
// constructeur
{
 for (int i=0;i<lig;i++)
 {
  for (int j=0;j<col;j++)
  {
   mat[i][j]=0;
  }
 }
 
 ligne   = lig;
 colonne = col;
}
 
mais ce qui est bizzare cv'est que quand je fais un affichage dans ma fonction * juste avant le return, ça me met bien la matrice attendue.

Reply

Marsh Posté le 19-02-2006 à 11:38:25    

Essaies ça :
matrice &matrice::operator=(const matrice &m1)


Message édité par slash33 le 19-02-2006 à 11:38:32
Reply

Marsh Posté le 19-02-2006 à 11:39:47    

Y a un truc qui me chiffonne : comment est instancié le tableau qui conserve les coefficients ?
 
Là je pense que le compilo fait la chose suivante:

  • appel du constructeur matrice() -> par défaut sans paramètre
  • ce constructeur fixe la taille de la matrice à (0,0) voir pire...
  • appel à matrice::operator=(const matrice& m) mais avec une taille à 0,0 ça n'a aucun effet (car tu ne réalloue pas la grille de coefficients dans l'opérateur)
  • au final la matrice est inchangée avec une taille 0,0


Message édité par slash33 le 19-02-2006 à 11:46:32
Reply

Marsh Posté le 19-02-2006 à 11:45:29    

Quel est le type du (pseudo?) tableau à deux dimensions "mat" ?

Reply

Marsh Posté le 19-02-2006 à 11:49:40    

Sinon il existe ça prêt à l'usage:
http://www.boost.org/libs/numeric/ublas/doc/matrix.htm

Reply

Marsh Posté le 19-02-2006 à 12:02:15    

#define MAX_LIGNE 50
#define MAX_COLONNE 50
 
class matrice
{
 
private :
 int ligne;
 int colonne;
 int mat[MAX_LIGNE][MAX_COLONNE];

Reply

Marsh Posté le 19-02-2006 à 12:02:43    

en fait, je comprend pas car j'ai le même prob sur plusieurs fonctions et pourtant elles sont toutes simples

Reply

Marsh Posté le 19-02-2006 à 12:03:40    

du style j'ai aussi celle pour inverser 2 lignes d'une matrice qui fonctionne pas :  
void matrice::inverserLignes(int i,int j)
// inverse les lignes i et j de la matrice courrante
{
 int tmp = 0;
 
 for(int col=0;col<colonne;col++)
 {
  tmp         = mat[i][col];
  mat[i][col] = mat[j][col];
  mat[j][col] = tmp;
 }
}
 
quand je veux inverser les 2 dernières lignes de ma matrice :  
100
001
010
 
elle m'affiche
100
001
-84563147 -654878 -545485
 
du moins un truc dans le style


Message édité par Cat Mary le 19-02-2006 à 12:05:47
Reply

Marsh Posté le 19-02-2006 à 12:03:40   

Reply

Marsh Posté le 19-02-2006 à 13:02:04    

Oulà ! Ta solution présente plusieurs défauts:

  • La matrice n'est pas réellement dynamique
  • Aucun contrôle de débordement, tu peux accéder à une zone en dehors de l'espace mémoire défini pour mat.


Taz serait là il te dirait : vector<vector<double>>.
Bref il faut utiliser un adressage dynamique contrôlé.
 
Si c'est un travail professionnel (et non un exercice d'école), je te conseille d'utiliser une classe standard dont celle de boost qui fera parfaitement l'office:
http://www.boost.org/libs/numeric/ublas/doc/matrix.htm
 
Si tu persistes dans cette voie je te conseille d'accéder aux éléments de mat via un accesseur/mutateur approprié:
 

Code :
  1. // dans la déclaration de la classe matrice
  2. private: // usage interne
  3. double getAt(unsigned int, unsigned int) const
  4. // implémentation
  5. double matrice::getAt(unsigned int col, unsigned int lig) const
  6. {
  7.   if (col < MAX_COLONNE && lig < MAX_LIGNE)
  8.   {
  9.      // accès à un cofficient valide
  10.   }
  11.   else
  12.   {
  13.      // index non valide : lève une expeption spécifique
  14.      throw new illegal_index();
  15.   }
  16. }


Message édité par slash33 le 19-02-2006 à 13:10:18
Reply

Marsh Posté le 19-02-2006 à 13:04:48    

Non c'est un travail d'école, un projet en math

Reply

Marsh Posté le 19-02-2006 à 13:05:11    

pour rendre ma matrice dynamique, je dois faire comment?

Reply

Marsh Posté le 19-02-2006 à 13:10:38    

Taz dirait : mat doit être un vector<vector<double>>.


Message édité par slash33 le 19-02-2006 à 13:10:53
Reply

Marsh Posté le 19-02-2006 à 13:14:23    

Reply

Marsh Posté le 19-02-2006 à 13:18:12    

ok merci je vais essayer comme ça

Reply

Marsh Posté le 19-02-2006 à 19:28:29    

Fais un new matrice et retourne une référence sur l'objet matrice.


Message édité par el muchacho le 19-02-2006 à 19:30:06
Reply

Sujets relatifs:

Leave a Replay

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