Rechercher : dans
Par :

Produit matriciel en C++

Dernière réponse le 14 nov 2009 à 16:00:37 do'urden, le 10 nov 2005 à 00:16:51 
 Signaler ce message aux modérateurs

Bonjour,

je dois faire, dans le cadre des études, un programme simulant l'algorithme de Jacobi.

Or cet algorithme demande de faire, à un moment donné, des produits matriciels.

Je me suis longtemps creusé les méninges pour trouver un moyen de réaliser ce produit dans une fonction mais je n'ai trouvé aucune solution.

Existerait-il une bibliothèque contenant une telle fonction ?

Mon problème est en fait que je ne vois pas du tout dans quel sens doit-on parcourir les deux matrices afin de multiplier 2 à 2 chaque variable et cela pour chaque ligne et colonne...

Meilleures réponses pour « produit matriciel en C++ » dans :
3D Secure / Verified by Visa / SecureCode: Qu'est-ce que c'est ? VoirDepuis octobre 2008, les banques et commerçants en ligne ont commencé à adopter le système 3DSecure pour les paiements sur Internet. Qu'est-ce que c'est ? 3DSecure est appelé "Verified by Visa" chez Visa, et "SecureCode" chez Mastercard. (Les logos...
[Langage C] C/C++ Erreur de segmentation VoirQu'est ce qu'une erreur de segmentation Vous êtes en train de développer une application sous Linux en C/C++. Tout va bien, ça compile, les oiseaux chantent. Donc vous lancez votre application pour la tester. Et vous obtenez l'un de ces deux...
La compilation et les modules en C et en C++ VoirCet article a pour vocation d'introduire les notions de bases de la compilation en C et en C++ et de la programmation modulaire. Il permet de mieux comprendre les messages d'erreur du compilateur. Les notions abordées ici sont indépendantes du...
Télécharger Visual C++ Express VoirVisual C++ Express est une version "gratuite" et allégée de Visual Studio ; l'utilisation requiert l'inscription sur le site de Microsoft. Cet environnement de développement permet de créer des application Win32 ou du .NET C.
Langage C++ - Les types de données VoirLes types de données Les données manipulées en langage C++, comme en langage C, sont typées, c'est-à-dire que pour chaque donnée que l'on utilise (dans les variables par exemple) il faut préciser le type de donnée, ce qui permet de connaître...
Les chaînes de caractères en C++ VoirQu'est-ce qu'une chaîne de caractères ? Une chaîne de caractères (appelée string en anglais) est une suite de caractères, c'est-à-dire un ensemble de symboles faisant partie du jeu de caractères, défini par le code ASCII. En langage C++, une...
Les structures en langage C VoirDifférence entre une structure et un tableau Un tableau permet de regrouper des éléments de même type, c'est-à-dire codés sur le même nombre de bits et de la même façon. Toutefois, il est généralement utile de pouvoir rassembler des éléments de...

1

mamiemando, le 10 nov 2005 à 02:37:05
  • +2

Bon allez une petite classe de matrice écrite rapidement par mes soins. Je te l'ai fait en template comme ca tu peux aussi bien travailler avec des matrices d'entiers que de double... Par ailleurs je t'ai défini les opérateurs * et + pour deux matrices (addition et multiplication interne du corps des matrices), ainsi que l'opérateur << (pour l'affichage).

Si tu veux définir les additions et multiplications externes (par un scalaire) tu as un modèle pour le faire.

#include <vector>
#include <cassert>
#include <iostream>

/**
 * \brief Une classe de matrice pleine
 */

template <class T> class matrix{
    protected:
        std::vector<std::vector<T> > data;
    public:

        /**
         * \brief Constructeur par defaut
         */
        matrix(){}

        /**
         * \brief Alloue en memoire une matrice
         * \param nb_lig Nombre de ligne
         * \param nb_col Nombre de colonne
         */
        matrix(std::size_t nb_lig,std::size_t nb_col){
            for(std::size_t lig=0;lig<nb_lig;++lig){
                std::vector<T> tmp;
                tmp.reserve(nb_col);
                for(std::size_t col=0;col<nb_col;++col){
                    tmp.push_back(0);//valeur par defaut
                }
                data.push_back(tmp);
            }
        }

        /**
         * \brief Destructeur
         */
        ~matrix(){}

        /**
         * \return Le nombre de ligne
         */
        inline std::size_t size1() const{
            return data.size();
        }

        /**
         * \return Le nombre de colonne
         */
        inline std::size_t size2() const{
            if (data.size()==0) return 0;
            return data[0].size();
        }

        /**
         * \brief Accesseur vers un element de la matrice
         * \param lig son numero de ligne
         * \param col son numero de colonne
         * \return la valeur stockee
         */
        inline T get(std::size_t lig,std::size_t col) const{
            assert(lig<size1());
            assert(col<size2());
            return data[lig][col];
        }

        /**
         * \brief Accesseur vers un element de la matrice
         * \param lig son numero de ligne
         * \param col son numero de colonne
         * \param val la valeur a stocker
         */
        inline void set(std::size_t lig,std::size_t col,T val){
            assert(lig<size1());
            assert(col<size2());
            data[lig][col]=val;
        }

};

/**
 * \brief Operateur << pour les matrices
 * \param o Le flux de sortie
 * \param m la matrice a ecrire
 */
template <class T>
std::ostream& operator << (std::ostream& o,const matrix<T> & m){
    for(std::size_t lig=0;lig<m.size1();++lig){
        for(std::size_t col=0;col<m.size2();++col){
            o<<m.get(lig,col)<<" ";
        }
        o<<std::endl;
    }
    return o;
}

/**
 * \brief Addition matricielle
 * \param m1 la premiere matrice
 * \param m2 la deuxieme matrice
 * \return la somme
 */
template <class T>
matrix<T> operator+ (const matrix<T> & m1,const matrix<T> & m2){
    assert(m1.size1()==m1.size1());
    assert(m1.size2()==m1.size2());
    std::size_t nb_lig=m1.size1();
    std::size_t nb_col=m1.size2();
    matrix<T> sum(nb_lig,nb_col);
    for(std::size_t lig=0;lig<nb_lig;++lig){
        for(std::size_t col=0;col<nb_col;++col){
            sum.set(lig,col,m1.get(lig,col)+m2.get(lig,col));
        }
    }
    return sum;
}

/**
 * \brief Multiplication matricielle
 * \param m1 la premiere matrice
 * \param m2 la deuxieme matrice
 * \return le produit
 */
template <class T>
matrix<T> operator* (const matrix<T> & m1,const matrix<T> & m2){

    assert(m1.size2()==m2.size1());
    std::size_t nb_lig=m1.size1();
    std::size_t nb_col=m2.size2();
    matrix<T> prod(nb_lig,nb_col);
    for(std::size_t lig=0;lig<nb_lig;++lig){
        for(std::size_t col=0;col<nb_col;++col){
            //calcul du terme (lig,col)
            T tmp=0;
            for(std::size_t i=0;i<m1.size2();++i){
                tmp+=m1.get(lig,i)*m2.get(i,col);
            }
            prod.set(lig,col,tmp);
        }
    }
    return prod;
}

int main(){
    matrix<int> m(3,4);
    matrix<int> n(3,4);
    matrix<int> p(4,5);
    std::cout<<"M est une matrice de dimension :";
    std::cout<<"("<<m.size1()<<";"<<m.size2()<<")"<<std::endl;

    for(std::size_t lig=0;lig<m.size1();++lig){
        for(std::size_t col=0;col<m.size2();++col){
            m.set(lig,col,10*lig+col); //initialisation de m
            n.set(lig,col,lig*col);    //initialisation de n
        }
    }

    for(std::size_t lig=0;lig<p.size1();++lig){
        for(std::size_t col=0;col<p.size2();++col){
            p.set(lig,col,lig*col);    //initialisation de n
        }
    }

    std::cout<<"M="<<std::endl<<m;
    std::cout<<"N="<<std::endl<<n;
    std::cout<<"P="<<std::endl<<p;
    std::cout<<"M+N="<<std::endl<<m+n;
    std::cout<<"M*P="<<std::endl<<m*p;
    return 0;
}


Bonne chance

Répondre à mamiemando

7

Dark, le 13 nov 2009 à 21:58:58

Super boulot ! merci beaucoup.

Répondre à Dark

8

Dark, le 13 nov 2009 à 22:31:27

En fait, elle n'est pas tout à fait générique car tu initialises les valeurs à 0 !

Donc si on décide de stocker des objets, celà ne fonctionnera pas...

Aurais-tu une facon de résoudre ce problème ?

Répondre à Dark

9

Dark, le 13 nov 2009 à 22:34:44

J'ai trouvé, il faut simplement faire ceci dans le constructeur :

tmp.resize(nbColonnes);
                
                //for(std::size_t colonne=0;colonne<nbColonnes;++colonne)
                //    tmp.push_back(0); // ajout colonne dans la ligne

Répondre à Dark

10

 mamiemando, le 14 nov 2009 à 16:00:37

Tu as raison. En fait idéalement il faudrait écrire :

      matrix(std::size_t nb_lig,std::size_t nb_col){
            for(std::size_t lig=0;lig<nb_lig;++lig){
                std::vector<T> tmp(nb_col,T());
                // on peut même écrire std::vector<T> tmp(nb_col);
                data.push_back(tmp);
            }
        }


Comme par défaut une valeur numérique est construite par défaut à 0, ça passe.

Merci pour tes remarques !

Répondre à mamiemando

2

Char Snipeur, le 10 nov 2005 à 10:06:10

Si A et B sont deux matrices de dimensions compatible pour pouvoir les multiplier, on a :
(A×B)(i,j)=A(i,k)×B(k,j)
en utilisant la notation d'enstein de somme sur les indices muets.
bonne chance Salutation !
Char Snipeur

Répondre à Char Snipeur

3

mamiemando, le 10 nov 2005 à 15:09:28

Tu peux aussi regarder du côté de la gsl (voire boost mais attention boost c'est chaud).

Bonne chance

Répondre à mamiemando

4

do'urden, le 10 nov 2005 à 19:29:45

Merci bien pour vos réponses, j'ai pu terminer mon programme grâce à cela :-)

Répondre à do'urden

5

jcl7, le 1 fév 2008 à 10:06:57

Voici un exemple simple de calcul matriciel en Visual c++ mode console. On peut l'adapter pour d'autres types de variables.
// creation de tableaux dynamiques
// Produit de matrices

#include <iostream>

using namespace std;

int **t1; // pointeur de pointeur
int taille_i1; // nbre de lignes
int taille_j1; // nbre de colonnes
int **t2; // pointeur de pointeur
int taille_i2;
int taille_j2;
int **t3; // pointeur de pointeur
int t[2][2];
int i;
int j;
int donnee;
int k;
void Free_Tab1(); // Liberer l'espace mémoire;
void Free_Tab2(); // Liberer l'espace mémoire;
void Free_Tab3(); // Liberer l'espace mémoire;


int main()
// 1ere matrice
{
cout << "---------- 1ere matrice -----------"<< "\n";
cout <<"Entrer le nombre de lignes "; cin>>taille_i1;
cout <<"Entrer le nombre de colonnes "; cin>>taille_j1; "\n";

/* Allocation dynamique */
t1 = new int *[taille_i1]; // pointeur vers tableau de pointeurs dynamique et initialisation du nombre de lignes
for( i = 0; i < taille_i1; ++i)
{
t1[i] = new int[taille_j1]; //parcours des lignes pour allouer chaque colonnes
}

/* Initialisation */
for(i = 0; i < taille_i1; ++i)
for(j = 0; j < taille_j1; ++j)
{
cout << "Entrer la valeur de la ligne " << i + 1 << " et de la colonne " << j + 1 << "\t";
cin >> donnee;
t1[i][j] = donnee;
}
// 2ieme matrice

cout << "\n" << "---------- 2ieme matrice -----------"<< "\n";
begin:
cout <<"Entrer le nombre de lignes: ";cin>>taille_i2;
if(taille_j1 != taille_i2)
{
cout << "Erreur !!!:le nbre de lignes de la 2ieme matrice doit etre egal" ;
cout << endl;
cout << "au nbre de colonnes de la 1ere matrice";
cout << endl;
goto begin;
}
cout <<"Entrer le nombre de colonnes : ";cin>>taille_j2; "\n";

/* Allocation dynamique */
t2 = new int *[taille_i2]; // initialisation du nombre de lignes
for(i = 0; i < taille_i2; ++i)
{
t2[i] = new int[taille_j2]; //parcours des lignes pour allouer de la memoire a chaque colonnes et
} // affecter une adresse à chaque t2

/* Initialisation */
for(i = 0; i < taille_i2; ++i)
for(j = 0; j < taille_j2; ++j)
{
cout << "Entrer la valeur de la ligne " << i + 1 << " et de la colonne " << j + 1 << "\t";
cin >> donnee;
t2[i][j] = donnee;
}


/* Affichage matrice 1 */
cout << "\n" << "---------- affichage 1ere matrice -----------"<< "\n";
for(i = 0; i < taille_i1; ++i)
{
for(int j = 0; j < taille_j1; ++j)
cout<<t1[i][j]<< " ";
cout << endl;
}

/* Affichage matrice 2 */
cout << "\n" << "---------- affichage 2ieme matrice -----------"<< "\n";
for(i = 0; i < taille_i2; ++i)
{
for(j = 0; j < taille_j2; ++j)
cout<<t2[i][j]<< " ";
cout << endl;
}


/* Allocation dynamique */
t3 = new int *[taille_i1]; // initialisation du nombre de lignes
for(i = 0; i < taille_i1; ++i)
{
t3[i] = new int[taille_j2]; //parcours des lignes pour allouer chaque colonnes
}


// Multiplication des matrices

j = 0;
for(i = 0; i < taille_i1; ++i)
{

for(j = 0; j < taille_j2; ++j)
{
t3[i][j] = 0;


for(int k = 0 ;k < taille_i2; ++k)

t3[i][j] = t3[i][j] + t1[i][k] * t2[k][j];

}
}


// affichage matrice calculée

cout << "\n" << "---------- affichage matrice calculée -----------"<< "\n";
for(i = 0; i < taille_i1; ++i)
{
for(j = 0; j < taille_j2; ++j)

cout << t3[i][j] << " ";
cout << endl;

}

return 0;
}

void Free_Tab1()
{
for(int i = 0; i < taille_i1; ++i)
delete[] t1[i];
delete t1;
}

void Free_Tab2()
{
for(int i = 0; i < taille_i2; ++i)
delete[] t2[i];
delete t2;
}

void Free_Tab3()
{
for(int i = 0; i < taille_i1; ++i)
delete[] t3[i];
delete t3;
}

Répondre à jcl7

6

3bk, le 3 mai 2008 à 11:05:06

Je ss en apprendi et je veux savoir comme faire une multiplication de 2 matrices en c de dimension N.

Répondre à 3bk
Collection CommentÇaMarche.net