Soyez le premier à donner votre avis sur cette source.
Vue 7 726 fois - Téléchargée 305 fois
/* LAMOME Julien 19/10/07 14:12 ; voir notice ci dessous */ /* Utilisation de la struct ci dessous. Déclaration : - MATRIX<type> nom_matrice(n-ligne,m-colonne) crée une matrice de n lignes sur m colonne d'éléments 'type' de valeurs nul - MATRIX<type> nom_matrice(n-ligne/colonne) comme la présédente, mais une matrice carré. - MATRIX<type> nom_matrice crée une matrice vide Acces données : lecture/écriture donnée de la matrice : nom_matrice(ligne,colonne) données de la matrice : nom_matrice[colonne][ligne] ATTENTION, la convention est inverse lecture sous matrice : nom_matrice(l1,l2,c1,c2) renvoie la matrice allant de la ligne l1 à l2 et de la colonne c1 à c2 nombre de ligne : nom_matrice.size_M().n nombre de colonnes : nom_matrice.size_M().m donnée de la matrice : nom_matrice(i,'r'|'c') renvoi la ligne(r) ou colonne(c) n° i Fonctions membres : Id() : transforme la matrice en matrice identité, si elle est carré, sinon, ne fait rien inverse() : calcul l'inverse d'une matrice carré, quitte le programme sinon transpose() : prend la transposer de la matrice. affiche() : affiche la matrice, soit avec <stdio.h> soit avec <iostream> include précédent det() : calcul le déterminant de la matrice si carrée, renvoi -1 sinon. size() : retourne le nombre de lignes d'une matrice carré, et le nombre d'éléments d'une non carré size_M() : retourne la taille de la matrice dans la structure de type M_taille. Tr() : calcul la trace de la matrice (somme diagonal), renvoi 0 si non carré. clear() : rend la matrice vide. genre() : retourne le type de matrice : IS_VECTOR, si une des dimmension est de 1; IS_SCALAR, si les 2 dim sont à 1; VIDE si les dim sont nul; IS_MATRICE ; et MATRICE_DIM_ERR si les dimensions sont indéterminés push_back(type) : rempli une matrice par la fin, la rend carré. !! UTILISATION DECONSEILLER !! fct(T fonc(T)) : applique la fonction fonc a chaque membre de la matrice Supporte : - ostream<<nom_matrice - ostream<<nom_matrice.size_M() - la plupart des opération algébrique de base : +,-,*,= - +,* par "type", et par "vector<type>" - les fonctions inverse(matrice), transpose(matrice). - la "procedure" TLU, qui à partir de la premiere matrice : A, retourne les matrice triangulaires basse et haute, L, et U, tel que A=L*U Compilation tester avec succes avec gcc, jusqu'à la version 3.3.1 compatible cygwin */ #ifndef _MATRIX #define _MATRIX #include <vector> #include <cmath> #ifdef _STDIO_H_ #define __ENVOI(x) printf(x); #define __ENVOI2(x,y) printf(x,y); #else #if defined(_CPP_IOSTREAM) || defined(__IOSTREAM__) #define __ENVOI(x) std::cout<<x; #else #define __ENVOI(x) throw (x); #endif #endif struct M_taille { int n; int m; }; #define IS_MATRICE 2 #define IS_VECTOR 1 #define IS_SCALAR 0 #define VIDE 3 #define MATRICE_DIM_ERR -1 template <class T>struct MATRIX { // variable de la matrice : ses données + sa taille private: int n,m; std::vector<T> M; // constructeur, destructeur, operateur, et fonctions public: MATRIX() {n=0;m=0;std::vector<T> M;}; MATRIX(int ,int =0); //constructeur MATRIX(std::vector<T>); //transformation d'un vecteur en matrice (1,n) MATRIX(T);// Attention si T=int !!!!! mettre "MATRIX operator=(T)" ne marche pas ~MATRIX(){M.clear();M.reserve(0);}; int size() const; M_taille size_M() const; void clear(); T& operator()(int ,int ); const T operator()(int ,int )const; MATRIX operator()(int ,int ,int ,int ); std::vector<T> operator()(int,char); // std::vector<T> operator[](int); T* operator[](int); const T* operator[](int)const; MATRIX operator=(MATRIX ); MATRIX operator+=(MATRIX ); MATRIX operator-=(MATRIX ); MATRIX operator*=(MATRIX ); MATRIX operator-() const ; MATRIX operator+() const {return *this;}; MATRIX<T> fct(T t(T)) const;// pour appliquer n'importe quelle fonction T Tr() const; MATRIX& push_back(T); int genre() const; T det() const; MATRIX& Id(); MATRIX& inverse(); MATRIX& transpose(); void affiche() const; void resize(int,int); // Fonctions amies template <class _T>friend MATRIX<_T> operator+(const MATRIX<_T>&,_T); template <class _T>friend MATRIX<_T> operator*(const MATRIX<_T>&,const _T); template <class _T>friend MATRIX<_T> operator*(MATRIX<_T>&,MATRIX<_T>&); template <class _T>friend MATRIX<_T> operator+(MATRIX<_T>&,MATRIX<_T>&); template <class _T>friend MATRIX<_T> operator&(MATRIX<_T>&,MATRIX<_T>&); template <class _T>friend MATRIX<_T> operator-(MATRIX<_T>&,MATRIX<_T>&); template <class _T>friend bool operator==(MATRIX<_T>,MATRIX<_T>); template <class _T>friend std::vector<_T> operator*(MATRIX<_T>,std::vector<_T>); template <class _T>friend int TLU(const MATRIX<_T>&,MATRIX<_T>&,MATRIX<_T>&); // template <class _T>friend std::ostream& operator<<(std::ostream&, MATRIX<_T>); // template <class _T>friend MATRIX<_T>& operator>>(std::istream&, MATRIX<_T>&); template <class _T,typename T1>friend MATRIX<_T>& operator>>(T1&, MATRIX<_T>&); template <class T1,typename _T>friend T1& operator<<(T1&, MATRIX<_T>); }; /*------------fin de la struct MATRIX-----------------------------------------*/ /*------------------opération binaire sur les matrices------------------------*/ template <class T>MATRIX<T> operator+(const MATRIX<T>& ,const T ); template <class T>MATRIX<T> operator+(const T ,const MATRIX<T>& ); template <class T>MATRIX<T> operator*(const MATRIX<T>& ,const T ); template <class T>MATRIX<T> operator*(const T ,const MATRIX<T>& ); template <class T>MATRIX<T> operator+(const MATRIX<T>& ,const MATRIX<T>& ); template <class T>MATRIX<T> operator+(const MATRIX<T>& ,const MATRIX<T>& ); template <class T>MATRIX<T> operator-(const MATRIX<T>& ,const MATRIX<T>& ); template <class T>MATRIX<T> operator-(const MATRIX<T>& ,const MATRIX<T>& ); template <class T>MATRIX<T> operator&(MATRIX<T>& ,MATRIX<T>& ); //multiplication terme à terme template <class T>MATRIX<T> operator&(const MATRIX<T>& ,const MATRIX<T>& ); template <class T>MATRIX<T> operator*(MATRIX<T>& ,MATRIX<T>& ); template <class T>MATRIX<T> operator*(const MATRIX<T>& ,const MATRIX<T>& ); template<class T> bool operator==(const MATRIX<T>,const MATRIX<T>); template<class T> bool operator!=(MATRIX<T>,MATRIX<T>); /*------------------opération binaire matrice vecteur------------------------*/ template <class T>std::vector<T> operator*(MATRIX<T> ,std::vector<T> ); template <class T>std::vector<T> operator*(std::vector<T> ,MATRIX<T> ); /*-----------fonction supplémentaire utile au calculs de matrices-------------*/ template<class T>std::vector<T> operator+(std::vector<T> ,std::vector<T>); template<class T>std::vector<T> operator*(T ,std::vector<T>); template<class T>std::vector<T> operator*(std::vector<T>,T ); template<class T>MATRIX<T> transpose(MATRIX<T> ); template<class T>MATRIX<T> inverse(MATRIX<T> ); template<class T> int TLU(const MATRIX<T>& A,MATRIX<T>& L,MATRIX<T>& U); #if defined(_CPP_IOSTREAM) || defined(__IOSTREAM__) //template<class T>std::ostream& operator<<(std::ostream& s, MATRIX<T> A); //std::ostream& operator<<(std::ostream& s, M_taille A); #endif // IOSTREAM /*--------------------- fonctions de flux pour matrices ----------------------*/ template <class _T,typename T1> MATRIX<_T>& operator>>(T1&, MATRIX<_T>&); template <class T1,typename _T> T1& operator<<(T1&, MATRIX<_T>); typedef MATRIX<double> MATRIX2; /*----------------------------------------------------------------------------*/ //--------début des implementation--------------------------------------------*/ /*----------------------------------------------------------------------------*/ template<class T>void MATRIX<T>::affiche() const { #ifdef _STDIO_H_ for (int i=0;i<n;i++) { printf("| "); for (int j=0;j<m;j++) printf("%.1e | ",M[i+n*j]); printf("\n"); } #else #if defined(_CPP_IOSTREAM) || defined(__IOSTREAM__) for (int i=0;i<n;i++) { std::cout<<"| "; for (int j=0;j<m;j++) std::cout<<M[i+n*j]<<" | "; std::cout<<"\n"; } #endif #endif } /*------------------opération binaire sur les matrices------------------------*/ template <class T>MATRIX<T> operator+(const MATRIX<T>& A,const T B) { MATRIX<T> tmp; if (A.m==A.n) { for (int i=0;i<A.M.size();i++) tmp.push_back(A.M[i]+B); return tmp; } MATRIX<T> tmp1(A.n,A.m); for (int j=0;j<A.m;j++) for (int i=0;i<A.n;i++) tmp1(i,j)=A(i,j)+B; return tmp1; } template <class T>MATRIX<T> operator+(const T B,const MATRIX<T>& A) { return A+B; } template <class T>MATRIX<T> operator*(const MATRIX<T>& A,const T B) { MATRIX<T> tmp; if (A.m==A.n) { for (unsigned int i=0;i<A.M.size();i++) tmp.push_back(A.M[i]*B); return tmp; } MATRIX<T> tmp1(A.n,A.m); for (int j=0;j<A.m;j++) for (int i=0;i<A.n;i++) tmp1(i,j)=A(i,j)*B; return tmp1; } template <class T>MATRIX<T> operator*(const T B,const MATRIX<T>& A) { return A*B; } template <class T>MATRIX<T> operator+(MATRIX<T>& A,MATRIX<T>& B) { if (A.m==B.m & A.n==B.n) { MATRIX<T> tmp; for (int i=0;i<A.M.size();i++) tmp.push_back(A.M[i]+B.M[i]); tmp.n=A.n; tmp.m=A.m; return tmp; } __ENVOI("problème de dimension (operator+)"); return -1; } template <class T>MATRIX<T> operator+(const MATRIX<T>& A,const MATRIX<T>& B) { MATRIX<T> a=A; MATRIX<T> b=B; return a+b; } template <class T>MATRIX<T> operator-(MATRIX<T>& A,MATRIX<T>& B) { if (A.m==B.m & A.n==B.n) { MATRIX<T> tmp; for (int i=0;i<A.M.size();i++) tmp.push_back(A.M[i]-B.M[i]); tmp.n=A.n; tmp.m=A.m; return tmp; } __ENVOI("problème de dimension (operator-)"); return -1; } template <class T>MATRIX<T> operator-(const MATRIX<T>& A,const MATRIX<T>& B) { MATRIX<T> a=A; MATRIX<T> b=B; return a-b; } template <class T>MATRIX<T> operator&(MATRIX<T>& A,MATRIX<T>& B) { if (A.m==B.m & A.n==B.n) { MATRIX<T> tmp; T a; for (int i=0;i<A.n*A.m;i++) { a=A.M[i]*B.M[i]; tmp.push_back(a); } tmp.n=A.n; tmp.m=A.m; return tmp; } return -1; } template <class T>MATRIX<T> operator&(const MATRIX<T>& A,const MATRIX<T>& B) { MATRIX<T> a=A; MATRIX<T> b=B; return a&b; } template <class T>MATRIX<T> operator*(MATRIX<T>& A,MATRIX<T>& B) { if (A.m==B.n) { MATRIX<T> tmp; T a=0; for (int j=0;j<B.m;j++) for (int i=0;i<A.n;i++) { for (int k=0;k<A.m;k++) a=a+A(i,k)*B(k,j); tmp.push_back(a); a=0; } tmp.n=A.n; tmp.m=B.m; return (tmp); } if ((A.n==B.m)&(A.m==1)&(B.n==1)) //très con, reviens au test précedent Am=1 et Bn=1 => Am==Bn ! { MATRIX<T> tmp; for (int i=0;i<A.n;i++) for (int j=0;j<B.m;j++) tmp.push_back(A(i,0)*B(0,j)); return tmp; } if (A.n==1 & A.m==1) return A(0,0)*B; if (B.n==1 & B.m==1) return B*A; __ENVOI("multiplication de matrices de dimension incompatible\n"); return -1; } template <class T>MATRIX<T> operator*(const MATRIX<T>& A,const MATRIX<T>& B) { MATRIX<T> a=A; MATRIX<T> b=B; return a*b; } template<class T> bool operator==(MATRIX<T> A,MATRIX<T> B) { if( (A.n!=B.n) | (A.m!=B.m) ) return false; for (int i=0;i<A.n*A.m;i++) if(A.M[i]!=B.M[i]) return false; return true; } template<class T> bool operator!=(MATRIX<T> A,MATRIX<T> B){return !(A==B);} /*------------------opération binaire matrice vecteur------------------------*/ template <class T>std::vector<T> operator*(MATRIX<T> A,std::vector<T> v) { if (v.size()!=A.n) { __ENVOI("vecteur de mauvaise dimension\n"); } std::vector<T> tmp; T a ; for (int i=0;i<A.n;i++) { a=0; for (int j=0;j<A.m;j++) a=a+A(i,j)*v[j]; tmp.push_back(a); } return tmp; } template <class T>std::vector<T> operator*(std::vector<T> v,MATRIX<T> A) { return A*v; } /*---définitions des fonctions et constructeurs de la strut MATRIX------------*/ template <class T>MATRIX<T>::MATRIX<T>(int a,int b) { n=a; m=b; if (b==0) m=n; for (int i=0;i<n*m;i++) M.push_back(T(0)); } template <class T>MATRIX<T>::MATRIX<T>(std::vector<T> v) { n=v.size(); m=1; M=v; } template <class T>MATRIX<T>::MATRIX<T>(T v) { n=1; m=1; M.push_back(v); } template<class T> T& MATRIX<T>::operator()(int x,int y) { if ( (x<n)&(y<m) ) return M[x+n*y]; __ENVOI("indice trop grand [operator()]\n"); exit(-1); } template<class T> const T MATRIX<T>::operator()(int x,int y)const { if ( (x<n)&(y<m) ) return M[x+n*y]; __ENVOI("indice trop grand [operator()]\n"); exit(-1); } template<class T> MATRIX<T> MATRIX<T>::operator()(int a,int b,int c,int d) { if (a>b | b>n | c>d | d>m) {__ENVOI("erreur indice sous matrice");return 0;} MATRIX<T> tmp(b-a+1,d-c+1); for (int i=0;i<b-a+1;i++) for (int j=0;j<d-c+1;j++) tmp(i,j)=M[i+a+n*(j+c)]; return tmp; } template<class T> std::vector<T> MATRIX<T>::operator()(int x,char c) { std::vector<T> tmp; if (c=='c') { for (int i=0;i<n;i++) tmp.push_back(M[i+n*x]); return tmp; } if (c=='r') { for (int i=0;i<m;i++) tmp.push_back(M[x+n*i]); return tmp; } return tmp; } /*template<class T> std::vector<T> MATRIX<T>::operator[](int r) { std::vector<T> tmp(m); for (int i=0;i<m;i++) tmp[i]=M[i+n*r]; return tmp; }*/ template<class T> T* MATRIX<T>::operator[](int r) //renvoie l'adresse T* du premier element de la colonne r, donc T[l] sera la ligne l de la colonne r { int nr=n*r; return &M[nr]; } template<class T>const T* MATRIX<T>::operator[](int r)const //renvoie l'adresse T* du premier element de la colonne r, donc T[l] sera la ligne l de la colonne r { int nr=n*r; return &M[nr]; } template <class T> MATRIX<T> MATRIX<T>::operator=(MATRIX S) { M=S.M; n=S.n; m=S.m; return *this; } template <class T> MATRIX<T> MATRIX<T>::operator+=(MATRIX S){*this=*this+S;return *this;} template <class T> MATRIX<T> MATRIX<T>::operator-=(MATRIX S){*this=*this-S;return *this;} template <class T> MATRIX<T> MATRIX<T>::operator*=(MATRIX S){*this=*this*S;return *this;} template <class T> MATRIX<T> MATRIX<T>::operator-()const {return T(-1)**this;} template <class T> int MATRIX<T>::size() const { if (M.size()!=n*m) return -1; if (m==n) return n; return n*m; } template <class T>MATRIX<T>& MATRIX<T>::Id() { if (m==n) for (int i=0;i<n;i++) M[i+n*i]=1.0; return *this; } template <class T> void MATRIX<T>::clear() { M.clear(); n=0; m=0; } template <class T> T MATRIX<T>::Tr() const { T tr=0; for (int i=0;i<n;i++) tr+=M[i*(1+n)]; if (m==n) return tr; return 0; } template <class T>MATRIX<T>& MATRIX<T>::inverse() { if (m!=n) { __ENVOI("inversion de matrices non carré non implémenter!\n"); return *this; } MATRIX<T> MM(n),M1(n),Mi1(n),Minv(n); MM=*this; M1=MM; Mi1.Id(); Minv=Mi1; for (int i=0;i<n;i++) { for (int j=0;j<n;j++) { if (MM(i,i)==0) { __ENVOI("inversion pivot GAUSS impossible : division par 0\n"); return *this; } M1(i,j)=MM(i,j)/MM(i,i); Mi1(i,j)=Minv(i,j)/(MM(i,i)); } MM=M1; Minv=Mi1; for (int k=0;k<n;k++)// mise zéros de la colonne if (k!=i) for (int j=0;j<n;j++) { M1(k,j)=MM(k,j)-MM(i,j)*MM(k,i); Mi1(k,j)=Minv(k,j)-Minv(i,j)*MM(k,i); } MM=M1; Minv=Mi1; /*for (int k=0;k<n;k++)//mise à zéro de la ligne. ap essai : pas la peine if (k!=i) for (int j=0;j<n;j++) { M1(j,k)=MM(j,k)-MM(i,j)*MM(i,k); Mi1(j,k)=Minv(j,k)-Minv(i,j)*MM(i,k); } MM=M1; Minv=Mi1;*/ }
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.