IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

Produit de matrices


Sujet :

C++

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 9
    Points : 6
    Points
    6
    Par défaut Produit de matrices
    Bonjour,

    J'ai besoin de résoudre un problème utilisant les moindres carrés.
    J'ai utilisé la bibliothèque GSL avec la décomposition QR et ça donne un faux résultat. Je me suis penché sur les moindres carrés récursifs mais la méthode que je connais implique pourvoir faire au moins un produit de matrices.

    J'ai pensé recréer une classe matrice et vecteur afin de le faire facilement.
    Tout se passe bien mais lorsque je fais le produit, un message d'erreur de windows : "Optimisation.exe a cessé de fonctionner".

    je sais que le produit se fait bien jusqu'au bout (en y allant à cout de stp::cout) mais c'est la sortie de la fonction qui gène.

    Voici les sources.
    Fichier Optimisation.cpp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #include <iostream>
    #include "Matrice.h"
    #include "Vecteur.h"
    #include "Optimisation.h"
     
    using namespace std;
     
     
    Matrice prod_mat(Matrice m1, Matrice m2)
    {
        Matrice m3 ;
        int i,j,k ;
        float temp ;
     
        int dim1 = m1.nligne() , dim2 = m1.ncol();
        int dim3 = m2.ncol() , dim4 = m2.ncol();
        m2.creat_mat(dim1,dim4);
        cout << "(ligne1,col1) = ("<< dim1<<","<<dim2<<") et (ligne2,col2)= ("<< dim3<<","<<dim4<<")"<<endl ;
     
        if(!(dim2 == dim3))
        {cout <<"produit mat impossible, dimension non corresp"<<endl;
        }
        else
        { cout << " dim2 = dim3 " <<endl ;
            for(i = 0; i < dim1; i++)
            {    for(j = 0; j < dim4; j++)
                {
                temp = 0;
                for(k=0; k < dim2 ; k++) 
                {
                    temp += m1.access(i,k)*m2.access(k,j);
                }
                m3.modify(i,j,temp);
                }
            }
        }
        //m3.print();
        return m3;
    }
    Voici le contenu de la classe Matrice :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #ifndef MATRICE_H_
    #define MATRICE_H_
     
    class Matrice
    {
    public:
        Matrice();
        ~Matrice();
        void creat_mat(int n,int m);    // fait une allocation mémoire de toutes les cases
        void init_mat(int n,int m, float val);
        void print(); 
        int nligne(); // Renvoie le nombre de lignes.
        int ncol(); // Renvoie le nombre de colonnes    
    //    void resize(int ligne, int col);     // Reinitialise en supprimant le contenu
    //    void assign(int ligne, int col, const int val); // Reinitialise et assigne val a chaque case
        float access(int , int ); // acceder a un element mat(i,j)
        void modify(int , int , float ); // modifier un élément mat(i,j)    
    private:
        float * *tab ;
        int dim_l ;
        int dim_c ;
        //bool prod_ok ;
    };
     
    #endif /*MATRICE_H_*/
    La fonction de creation d'une matrice (qui alloue la place mémoire et rajoute les dimensions) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    void Matrice::creat_mat(int n,int m)
    {
    int i;    
    if (n == 0 || m == 0) 
        {
        cout <<"taille impossible, nligne ="<<n<<"et ncol = "<<m<< endl;
        }
    else 
        {    dim_l = n;
            dim_c = m ;
            tab = NULL;
            tab = new float *[n];
            if (tab == NULL) cout <<"erreur d'allocation matrice "<< endl;
            for (i=0; i<n ; i++) 
            {
                tab[i] = new float [m];
                if (tab[i]==NULL) {cout <<"erreur d'allocation ligne "<< endl;}
            }    
        }    
    }
    Merci pour votre aide !

  2. #2
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2008
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2008
    Messages : 22
    Points : 16
    Points
    16
    Par défaut
    Bonjour,

    si c'est l'affichage qui pose problème, l'erreur se trouve certainement dans la methode 'print' de ta classe Matrice, met le contenu dans la methode si tu veux que l'on regarde.

    Sinon quelques suggestions, mais si tu connais les surcharges d’opérateurs en C++ tu pourrais surcharger l'operateur * et donc ne plus t'encombrer avec une fonction a part et l'utilisation serais très simple, par exemple:

    Matrice m3 = m1 * m2;

    Sinon une dernière chose pourquoi ne pas utiliser le constructeur plutot que la methode membre creat_mat ?

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 9
    Points : 6
    Points
    6
    Par défaut
    Bonjour,
    Bonjour,

    si c'est l'affichage qui pose problème, l'erreur se trouve certainement dans la methode 'print' de ta classe Matrice, met le contenu dans la methode si tu veux que l'on regarde.

    En fait c'est pas l'affichage à proprement dit, c'est plutôt qu'il y a une erreur dans l'exécution du .exe qui fait que windows renvoie un msg d'erreur, print() marchait très bien avant le produit de matrices

    Sinon quelques suggestions, mais si tu connais les surcharges d’opérateurs en C++ tu pourrais surcharger l'operateur * et donc ne plus t'encombrer avec une fonction a part et l'utilisation serais très simple, par exemple:
    En fait je viens de découvrir ça ! En fait j'ai un ami qui m'a carrément aidé à débugger le programme. Le problème était dans la necessité de faire un constructeur pour la copie et l'assignation "=" sinon le destructeur supprimait le résultat de la matrice produit d'où l'erreur

    En tout cas merci pour tes réponses, je me rend compte que je pense trop en C mais il faut bien commencer quelque part.
    À bientôt.

    PS: je poste le contenu du nouveau code si ça peut aider d'autres personne cherchant une solution rapide.
    Contenu du fichier Matrice.cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
     
    #include "Matrice.h"
    #include <iostream>
    #include <stdlib.h>
    using namespace std;
    Matrice::Matrice() {
    	tab = NULL;
    	dim_l = 0;
    	dim_c = 0;
    	alloc = false;
    }
     
    Matrice::~Matrice() {
    	if (alloc) {
    		for (int i = 0; i < dim_l; i++) {
    			delete [] tab[i];
    		}
    		delete [] tab;
    	}
    	alloc = false;//inutile
    }
     
    void Matrice::alloc_mat(int _dim_l, int _dim_c) {
    	if(!alloc && _dim_l*_dim_c!=0)
    	{
    		dim_l=_dim_l;
    		dim_c=_dim_c;
    		tab = new type_mat* [dim_l];
    		for(int i=0;i<dim_l;i++)
    		{
    			tab[i]=new type_mat [dim_c];
    		}
    		alloc=true;
    	}
    	else
    	{
    		dim_l=dim_c=0;
    		alloc=false;
    	}
    }
     
    bool Matrice::valid_index(int i, int j){
    	return i >= 0 && i < dim_l && j >= 0 && j < dim_c;
    }
     
    Matrice::Matrice(int _dim_l, int _dim_c) {
    	alloc_mat(_dim_l, _dim_c);
    }
     
    Matrice::Matrice(int _dim_l, int _dim_c, type_mat val) {
    	alloc_mat(_dim_l,_dim_c);
    	for (int i = 0; i < dim_l; i++) {
    		for (int j = 0; j < dim_c; j++) {
    			tab[i][j] = val;
    		}
    	}
    }
     
    Matrice::Matrice(const Matrice& source)
    {
    	alloc = source.alloc;
        dim_l = source.dim_l;
        dim_c = source.dim_c;
        tab = new type_mat *[dim_l];
        for (int i=0; i<dim_l; i++)
        {
            tab[i] = new type_mat[dim_c];
            for(int j=0; j<dim_c; j++)
                tab[i][j] = source.tab[i][j];
        }
        return;
    }
     
    void Matrice::print() {
    	int i, j;
    	for (i = 0; i < dim_l; i++) {
    		for (j = 0; j < dim_c; j++) {
    			cout << " " << tab[i][j];
    			if (j == dim_c - 1) {
    				cout << "" << endl;
    			}
    		}
    	}
    }
     
    int Matrice::nlignes()// Renvoie le nombre de lignes.
    {
    	return dim_l;
    }
     
    int Matrice::ncol()// Renvoie le nombre de colonnes
    {
    	return dim_c;
    }
     
    type_mat Matrice::operator()(int i, int j){
    	if (valid_index(i, j)) {
    		return tab[i][j];
    	} else {
    		return 0;
    	}
    }
     
    type_mat* Matrice::operator[](int i) {
    	return tab[i];
    }
     
    bool Matrice::modify(int i, int j, type_mat val) {
    	bool rep;
    	if (valid_index(i, j)) {
    		tab[i][j] = val;
    		rep = true;
    	} else {
    		rep = false;
    		cout << " indice(" << i << "," << j
    				<< ") hors des dimensions de la matrice" << endl;
    	}
    	return rep;
    }
     
    Matrice& Matrice::operator=(const Matrice& p){
    	this->dim_l=p.dim_l;
    	this->dim_c=p.dim_c;
    	this->alloc=p.alloc;
    	if(this->alloc)
    	{
    		this->tab=new type_mat* [this->dim_l];
    		for(int i=0;i<(this->dim_l);i++)
    		{
    			this->tab[i]=new type_mat [this->dim_c];
    			for(int j=0;j<(this->dim_c);j++)
    			{
    				this->tab[i][j]=p.tab[i][j];
    			}
    		}
    	}
    	return *this;
    }
    Dans le fichier optimisation.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    #include "Optimisation.h"            // optimisation.h inclue Matrice.h
    using namespace std ;
     
    Matrice prod_mat(Matrice m1, Matrice m2)
    {
    	if(m1.ncol() == m2.nlignes())
    	{
    		Matrice rep(m1.nlignes(),m2.ncol(),0);   
                   // ligne précédente, inutile de remplir de 0 au début, à modifier
    			for(int i=0;i<m1.nlignes();i++)
    			{   
    				for(int j=0;j<m2.ncol();j++)
    				{  
    					//rep.modify(i,j,0);
    					for(int k=0;k<m1.ncol();k++)
    					{
    						rep[i][j]+=m1(i,k)*m2(k,j);
    					}
    				}
    			}		
    		return rep;
    	}
    	else
    	{
    		cout << "produit mat impossible, dimension non corresp" << endl;
    		return Matrice();
    	}
    }

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Citation Envoyé par lasert Voir le message
    Le problème était dans la nécessité de faire un constructeur pour la copie et l'assignation "=" sinon le destructeur supprimait le résultat de la matrice produit d'où l'erreur
    Quand tu crées une classe, il faut en théorie toujours coder le constructeur par défaut, le constructeur de copie, et le constructeur d'affectation. Ou du moins y penser.

  5. #5
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Points : 325
    Points
    325
    Par défaut
    Il y a une chose qui me choque....

    Tu utilise une méthode qui prend des matrice par copie et renvoie un résultat par copie également, ce qui implique beaucoup de copies, et donc d'allocation et de desallocations de mémoire.

    Par ailleurs pourquoi utiliser des floats et pas des doubles ?

Discussions similaires

  1. produit de matrice
    Par ngossi dans le forum MATLAB
    Réponses: 3
    Dernier message: 27/08/2011, 13h45
  2. Produit de matrices
    Par soulisameh dans le forum MATLAB
    Réponses: 1
    Dernier message: 21/12/2009, 14h24
  3. produit de matrices : ordre ?
    Par Ange_blond dans le forum Mathématiques
    Réponses: 4
    Dernier message: 22/07/2009, 12h44
  4. Produit de matrices avec les map
    Par Butterfly83 dans le forum SL & STL
    Réponses: 7
    Dernier message: 30/11/2007, 15h22
  5. Produit de matrices en vba
    Par gcadieux dans le forum Général VBA
    Réponses: 4
    Dernier message: 26/09/2006, 16h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo