Matrice inverse et determinant en C++

Fermé
christiankamewe Messages postés 14 Date d'inscription dimanche 8 novembre 2009 Statut Membre Dernière intervention 19 novembre 2009 - 10 nov. 2009 à 00:46
Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 - 12 nov. 2009 à 09:29
Bonjour,
j'ai un projet sons visual C++ et je manipule les matrices de grandes tailles ( 50 x 50 ) minimum , actuellement j'ai crée une classe matrice.h dans laquelle j'écris mes fonctions;
depuis hier je n'arrive pas à écrire la fonction qui calcule le déterminant d'une matrice carrée ainsi que la matrice inverse d'une matrice donnée.
j'ai copié des codes sur internet et ca ne me donne pas des résultats juste.
pour cela , est ce que quelqu'un pourrait m'aider à trouver un bon code pouvant résoudre mon problème.
je vous prie ,quelqu'un aurait un code écris en C++ qui m'aiderais?
voici le mon code sur la classe matrice; quelqu'un pourrais le corriger


merci d'avance

#ifndef matrice_h
#define matrice_h
//#include <cstdlib>
#include <string>
#include <iostream>
#include <fstream>
//#include <limits>
#include <iomanip>
#include <string>
#include <vector>
#include <windows.h>
#include <stdio.h>
#include <algorithm>

using namespace std;

class Matrice
{
int M;
int N;
vector<float> contenu;
public:
// initialisation de la taille de la matrice à zero
Matrice(){
M=0;
N=0;
}
// declaration d'une matrice
Matrice( int lig,int col, float val=0){
M=lig;
N=col;
contenu.resize(M*N,val);
}

// permet de retourner la talle N de la matrice
int getN(){
return N;
}

// permet de retourner la talle N de la matrice
int getM(){
return M;
}

// declaration de l operateur ()
float operator()(int i,int j)const{
return contenu[i*N+j];
}

// declaration de l operateur recuperant sa valeur
float &operator()(int i,int j){
return contenu[i*N+j];
}

// initialisation des elements d'une matrice
void initialize( int lig,int col, float val=0){
M=lig;
N=col;
contenu.clear();
contenu.resize(M*N,val);
}

// operateur d'addition d une matrice par une autre matrice
Matrice operator+( Matrice mat){
//int K=mat.N;
Matrice out=mat;

for(int i=0;i< contenu.size() ;i++)
{
out.contenu[i]=out.contenu[i]+contenu[i];

}
return out;
}

// operateur de division d une matrice par un element
Matrice operator/( float d ){

Matrice out=*this;

for(int i=0;i< contenu.size() ;i++)
{
out.contenu[i]=out.contenu[i]/d;

}
return out;
}

// operateur de multiplication d une matrice par un element
Matrice operator*( float d ){

Matrice out=*this;

for(int i=0;i< contenu.size() ;i++)
{
out.contenu[i]=out.contenu[i]*d;

}
return out;
}

// operateur d' addition d une matrice par un element
Matrice operator+( float d ){

Matrice out=*this;

for(int i=0;i< contenu.size() ;i++)
{
out.contenu[i]=out.contenu[i]+d;

}
return out;
}

// operateur de soustraction d une matrice par un element
Matrice operator-( float d ){

Matrice out=*this;

for(int i=0;i< contenu.size() ;i++)
{
out.contenu[i]=out.contenu[i]-d;

}
return out;
}

//operateur de multiplication d'une matrice par une autre matrice
Matrice operator*( Matrice mat){
int K=mat.N;
Matrice out(M,K);

for(int i=0;i<M;i++)
{
for(int j=0;j<K;j++)
{
for (int l=0;l<N;l++)
{
out(i,j)=out(i,j)+contenu[i*N+l]*mat(l,j);
}
}

}
return out;
}

// Moyenne d'une matrice

vector<float> moyenne(){
vector<float> out(N);
Matrice mat= transpose();
for(int i=0;i<N;i++)
{
for (int l=0;l<M;l++)
{
out[i]=out[i]+ mat(i,l);
}
out[i]=out[i]/M;
}
return out;
}

// affichage d'une matrice
void afficher(){
for(int i=0;i<M;i++)
{
for(int j=0;j<N;j++)
{
printf("%f\t",contenu[i*N+j]);
}
cout<<endl<<endl;
}
}

// transposer d'une matrice
Matrice transpose(){
Matrice out(N,M);

for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
out(i,j)=contenu[j*N+i];
}

}
return out;
}

// Matrice identite
Matrice identite(){
Matrice out=*this;


if (M==N){

out.initialize(M,N,0.0);
for (int i=0;i<M;i++)

out.contenu[i*(M+1)]=1.0;
}
return out;
}


float trace() const
{
if (M==N){
float tr=0.0;
for (int i=0;i<N;i++)
tr=tr+contenu[i*(1+N)];

return tr;
}
else
return 0;
}

Matrice inverse(){
if (M!=N)
{
cout<<"inversion de matrices non carrées non implémentées!\n"<<endl;
return *this;
}
Matrice MM,M1,Mi1,Minv;// déclaration de matrices de taille identique à celle à inverser
MM=*this;// copie de la matrice à inverser
M1=MM;

Mi1.initialize(M,N,0) ;//Mi1 est maintenant une matrice identité
Minv=Mi1.identite();
for (int i=0;i<M;i++)
{
for (int j=0;j<M;j++)
{
if (MM.contenu[i*N+i]==0)
{
cout<<"inversion pivot GAUSS impossible : division par 0\n"<<endl;
return *this;
}
M1.contenu[i*N+j]=MM.contenu[i*N+j]/MM.contenu[i*N+i];
Mi1.contenu[i*N+j]=Minv.contenu[i*N+j]/(MM.contenu[i*N+i]);
}
MM=M1;
Minv=Mi1;
for (int k=0;k<M;k++)// mise zéros de la colonne
if (k!=i)
for (int j=0;j<M;j++)
{
M1.contenu[k*N+j]=MM.contenu[k*N+j]-MM.contenu[i*N+j]*MM.contenu[k*N+i];
Mi1.contenu[k*N+j]=Minv.contenu[k*N+j]-Minv.contenu[i*N+j]*MM.contenu[k*N+i];
}
MM=M1;
Minv=Mi1;

}
*this=Minv;
return *this;
}

// matrice de wishart d une matrice
Matrice wishart(){
Matrice out=*this;
vector<float>moy=moyenne();
for(int i=0;i<M;i++)
{
for (int j=0;j<N;j++)
{
out(i,j)=out(i,j)-moy[j];
}

}
return out.transpose()*out;

}

// renvoie la valeur d une matrice de wishart
void Towishart(){
*this = wishart();
}

//Centrer les element d une colonne d une matrice
Matrice centrer(){
Matrice out=*this;
vector<float>moy=moyenne();
for(int i=0;i<M;i++)
{
for (int j=0;j<N;j++)
{
out(i,j)=out(i,j)-moy[j];
}

}
return out;

}

// calcul la somme des elements d une matrice
float somme(){
float som=0;
int val=contenu.size();

for(int i=0;i<val;i++)
{
som=som+contenu[i];
}

return som;
}
};
#endif

6 réponses

Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
10 nov. 2009 à 08:26
Re-salut.
Comme je te l'ai demandé, comment testes tu l'inversion ?
La bonne méthode est de commencer par du 2×2 puis 3×3 etc.
je ne suis pas certain de ton produit de matrice, c'est peut être la premier point à considérer.
C'est à toi de debugger ton code, mais si tu veux, nous pouvons te donner tes méthodes.
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
10 nov. 2009 à 08:44
Et comme je te le disais, attention à l'erreur numérique, l'inversion par pivot de Gauss est une méthode rapide et facile à mettre en œuvre, mais elle a des inconvénients.
Par exemple avec ma bibliothèque matrice.h :
A*1/A=
1            1.1561e-15
-1.61428e-17 1
0
tinoeldorados
10 nov. 2009 à 14:53
Ne reinvente pas la roue, c'est B A BA de l'informatique, surtout en objet.
utilise le travail des autres pour etres plus productifs et plus innovants...

regarde dans la librairie Open source GSL : Gnu scientific library.
Tout existe pour faire des inversion de matrices et tous les calculs matricielles et en plus ils ont maximiser les performances et miniser les erreurs numeriques.
C'est fait par des VRAIS mathematiciens ....

Je l'ai deja utilise pour inverser des matrices de 8Go !!!! et ca fonctionne ...
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
10 nov. 2009 à 15:54
C'est clair !
J'ai fait cette bibliothèque matrice au début, c'est très formateur. Mais maintenant si ce n'est pas ton but, autant utiliser GSL qui est bien mieux faite.
0
christiankamewe Messages postés 14 Date d'inscription dimanche 8 novembre 2009 Statut Membre Dernière intervention 19 novembre 2009
11 nov. 2009 à 11:57
ok , merci je viens de l'installer , maintenant je vais voir comment l'utiliser , mais je n'y trouve pas le calcul du determinant . quelqu'un aurait une solution?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
12 nov. 2009 à 09:15
Cherche mieu, ça doit bien y être (traduction de déterminant en anglais ?)
0
Pacorabanix Messages postés 3248 Date d'inscription jeudi 23 août 2007 Statut Membre Dernière intervention 19 mai 2013 660
12 nov. 2009 à 09:29
Au cas où, petite astuce : si avec cette bibliothèque tu as une décomposition QR, alors le produit de la diagonale de R est le déterminant (et la décomposition QR est assez stable numériquement)
0