/* LAMOME Julien 19/10/05 14:12 ; voir notice ci dessous */ /* Utilisation de la struct ci dessous. Déclaration : - MATRIX nom_matrice(n-ligne,m-colonne) crée une matrice de n lignes sur m colonne d'éléments 'type' de valeurs nul - MATRIX nom_matrice(n-ligne/colonne) comme la présédente, mais une matrice carré. - MATRIX 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 soit avec 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 !! Supporte : - ostream<" - 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 #include #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<struct MATRIX { // variable de la matrice : ses données + sa taille private: int n,m; std::vector M; // constructeur, destructeur, operateur, et fonctions public: MATRIX() {n=0;m=0;std::vector M;}; MATRIX(int ,int =0); //constructeur MATRIX(std::vector); //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(); M_taille size_M(); void clear(); T& operator()(int ,int ); MATRIX operator()(int ,int ,int ,int ); std::vector operator()(int,char); // std::vector operator[](int); T* operator[](int); const T* operator[](int)const; MATRIX operator=(MATRIX ); MATRIX operator+=(MATRIX ); MATRIX operator-=(MATRIX ); MATRIX operator*=(MATRIX ); MATRIX operator-(); MATRIX operator+(){return *this;}; T Tr(); MATRIX& push_back(T); int genre(); T det(); MATRIX& Id(); MATRIX& inverse(); MATRIX& transpose(); void affiche(); void resize(int,int); // Fonctions amies template friend MATRIX<_T> operator+(MATRIX<_T>&,_T); template friend MATRIX<_T> operator*(MATRIX<_T>,_T); template friend MATRIX<_T> operator*(MATRIX<_T>&,MATRIX<_T>&); template friend MATRIX<_T> operator+(MATRIX<_T>&,MATRIX<_T>&); template friend MATRIX<_T> operator&(MATRIX<_T>&,MATRIX<_T>&); template friend MATRIX<_T> operator-(MATRIX<_T>&,MATRIX<_T>&); template friend bool operator==(MATRIX<_T>,MATRIX<_T>); template friend std::vector<_T> operator*(MATRIX<_T>,std::vector<_T>); template friend int TLU(MATRIX<_T>&,MATRIX<_T>&,MATRIX<_T>&); // template friend std::ostream& operator<<(std::ostream&, MATRIX<_T>); // template friend MATRIX<_T>& operator>>(std::istream&, MATRIX<_T>&); template friend MATRIX<_T>& operator>>(T1&, MATRIX<_T>&); template friend T1& operator<<(T1&, MATRIX<_T>); }; /*------------fin de la struct MATRIX-----------------------------------------*/ /*------------------opération binaire sur les matrices------------------------*/ template MATRIX operator+(MATRIX& ,T ); template MATRIX operator+(T ,MATRIX& ); template MATRIX operator*(MATRIX ,T ); template MATRIX operator*(T ,MATRIX& ); template MATRIX operator+(MATRIX& ,MATRIX& ); template MATRIX operator+(const MATRIX& ,const MATRIX& ); template MATRIX operator-(MATRIX& ,MATRIX& ); template MATRIX operator-(const MATRIX& ,const MATRIX& ); template MATRIX operator&(MATRIX& ,MATRIX& ); //multiplication terme à terme template MATRIX operator&(const MATRIX& ,const MATRIX& ); template MATRIX operator*(MATRIX& ,MATRIX& ); template MATRIX operator*(const MATRIX& ,const MATRIX& ); template bool operator==(MATRIX,MATRIX); template bool operator!=(MATRIX,MATRIX); /*------------------opération binaire matrice vecteur------------------------*/ template std::vector operator*(MATRIX ,std::vector ); template std::vector operator*(std::vector ,MATRIX ); /*-----------fonction supplémentaire utile au calculs de matrices-------------*/ templatestd::vector operator+(std::vector ,std::vector); templatestd::vector operator*(T ,std::vector); templatestd::vector operator*(std::vector,T ); templateMATRIX transpose(MATRIX ); templateMATRIX inverse(MATRIX ); template int TLU(MATRIX& A,MATRIX& L,MATRIX& U); #if defined(_CPP_IOSTREAM) || defined(__IOSTREAM__) //templatestd::ostream& operator<<(std::ostream& s, MATRIX A); //std::ostream& operator<<(std::ostream& s, M_taille A); #endif // IOSTREAM /*--------------------- fonctions de flux pour matrices ----------------------*/ template MATRIX<_T>& operator>>(T1&, MATRIX<_T>&); template T1& operator<<(T1&, MATRIX<_T>); typedef MATRIX MATRIX2; /*----------------------------------------------------------------------------*/ //--------début des implementation--------------------------------------------*/ /*----------------------------------------------------------------------------*/ templatevoid MATRIX::affiche() { #ifdef _STDIO_H_ for (int i=0;iMATRIX operator+(MATRIX& A,T B) { MATRIX tmp; if (A.m==A.n) { for (int i=0;i tmp1(A.n,A.m); for (int j=0;jMATRIX operator+(T B,MATRIX& A) { return A+B; } template MATRIX operator*(MATRIX A,T B) { MATRIX tmp; if (A.m==A.n) { for (unsigned int i=0;i tmp1(A.n,A.m); for (int j=0;jMATRIX operator*(T B,MATRIX& A) { return A*B; } template MATRIX operator+(MATRIX& A,MATRIX& B) { if (A.m==B.m & A.n==B.n) { MATRIX tmp; for (int i=0;iMATRIX operator+(const MATRIX& A,const MATRIX& B) { MATRIX a=A; MATRIX b=B; return a+b; } template MATRIX operator-(MATRIX& A,MATRIX& B) { if (A.m==B.m & A.n==B.n) { MATRIX tmp; for (int i=0;iMATRIX operator-(const MATRIX& A,const MATRIX& B) { MATRIX a=A; MATRIX b=B; return a-b; } template MATRIX operator&(MATRIX& A,MATRIX& B) { if (A.m==B.m & A.n==B.n) { MATRIX tmp; T a; for (int i=0;iMATRIX operator&(const MATRIX& A,const MATRIX& B) { MATRIX a=A; MATRIX b=B; return a&b; } template MATRIX operator*(MATRIX& A,MATRIX& B) { if (A.m==B.n) { MATRIX tmp; T a=0; for (int j=0;j Am==Bn ! { MATRIX tmp; for (int i=0;iMATRIX operator*(const MATRIX& A,const MATRIX& B) { MATRIX a=A; MATRIX b=B; return a*b; } template bool operator==(MATRIX A,MATRIX B) { if( (A.n!=B.n) | (A.m!=B.m) ) return false; for (int i=0;i bool operator!=(MATRIX A,MATRIX B){return !(A==B);} /*------------------opération binaire matrice vecteur------------------------*/ template std::vector operator*(MATRIX A,std::vector v) { if (v.size()!=A.n) { __ENVOI("vecteur de mauvaise dimension\n"); } std::vector tmp; T a ; for (int i=0;istd::vector operator*(std::vector v,MATRIX A) { return A*v; } /*---définitions des fonctions et constructeurs de la strut MATRIX------------*/ template MATRIX::MATRIX(int a,int b) { n=a; m=b; if (b==0) m=n; for (int i=0;iMATRIX::MATRIX(std::vector v) { n=v.size(); m=1; M=v; } template MATRIX::MATRIX(T v) { n=1; m=1; M.push_back(v); } template T& MATRIX::operator()(int x,int y) { if ( (x MATRIX MATRIX::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 tmp(b-a+1,d-c+1); for (int i=0;i std::vector MATRIX::operator()(int x,char c) { std::vector tmp; if (c=='c') { for (int i=0;i std::vector MATRIX::operator[](int r) { std::vector tmp(m); for (int i=0;i T* MATRIX::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]; } templateconst T* MATRIX::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 MATRIX MATRIX::operator=(MATRIX S) { M=S.M; n=S.n; m=S.m; return *this; } template MATRIX MATRIX::operator+=(MATRIX S){*this=*this+S;return *this;} template MATRIX MATRIX::operator-=(MATRIX S){*this=*this-S;return *this;} template MATRIX MATRIX::operator*=(MATRIX S){*this=*this*S;return *this;} template MATRIX MATRIX::operator-() {return T(-1)**this;} template int MATRIX::size() { if (M.size()!=n*m) return -1; if (m==n) return n; return n*m; } template MATRIX& MATRIX::Id() { if (m==n) for (int i=0;i void MATRIX::clear() { M.clear(); n=0; m=0; } template T MATRIX::Tr() { T tr=0; for (int i=0;iMATRIX& MATRIX::inverse() { if (m!=n) { __ENVOI("inversion de matrices non carré non implémenter!\n"); return *this; } MATRIX MM(n),M1(n),Mi1(n),Minv(n); MM=*this; M1=MM; Mi1.Id(); Minv=Mi1; for (int i=0;i T MATRIX::det() { if (m!=n) { __ENVOI("déterminant de matrices non carré non implémenter!\n"); return -1; } if (n==1) return M[0]; //if (n==2) return M[0]*M[3]-M[1]*M[2]; T d=0.0; MATRIX tmp; for (int i=0;i MATRIX& MATRIX::transpose() { MATRIX P(m,n); for (int i=0; i MATRIX& MATRIX::push_back(T x) { M.push_back(x); n=int(sqrt(double(M.size()))); m=n; return *this; } template int MATRIX::genre() { if ((m==1)&(n==1)) return IS_SCALAR; if ((m==1)|(n==1)) return IS_VECTOR; if ((m==0)&(n==0)) return VIDE; if ((m>1)&(n>1)) return IS_MATRICE; else return MATRICE_DIM_ERR; } templatevoid MATRIX::resize(int l,int c) { if(l*c>m*n) {__ENVOI("changement de taille impossible : pas assez d'éléments\n");return;} if(l*c==m*n) {n=l;m=c;return;} for(int i=0;iM_taille MATRIX::size_M() { M_taille tmp; tmp.n=n; tmp.m=m; return tmp; } /*-----------fonction supplémentaire utile au calculs de matrices-------------*/ templatestd::vector operator+(std::vector x,std::vectory) { std::vector tmp; if ( x.size()==y.size() ) for (int i=0;istd::vector operator-(std::vector x,std::vectory){return x+T(-1.)*y;} templatestd::vector operator*(T x,std::vectory) { std::vector tmp; for (int i=0;istd::vector operator*(std::vectory,T x) { return x*y; } templateMATRIX transpose(MATRIX A) {return A.transpose();} templateMATRIX inverse(MATRIX A) {return A.inverse();} templateint TLU(MATRIX& A,MATRIX& b,MATRIX& c) // fonction retournant une matrice triangulaire haute(c), et basse (b) // tel que a=b×c { if (A.n!=A.m) return -1; //MATRIX c(A.n),b(A.n); b=MATRIX(A.n);c=b; T som=0; b(0,0)=A(0,0); c(0,0)=1; for (int j=1;jstd::ostream& operator<<(std::ostream& s, MATRIX A) // { // if(A.genre()==IS_SCALAR) {s<MATRIX& operator>>(std::istream& s, MATRIX& A) // { // std::cout<<"Saisi de matrice:\nnombre de lignes\n"; // s>>A.n; // std::cout<<"nombre de colonnes\n"; // s>>A.m; // A=MATRIX(A.n,A.m); // std::cout<<"Remplisage par ligne puis par colonne\n"; // for (int i=0;i>A.M[i]; // //A.transpose(); // return A; // } std::ostream& operator<<(std::ostream& s, M_taille A) { s<<"| "< MATRIX& operator>>(T1& s, MATRIX& A) { __ENVOI("Saisi de matrice:\nnombre de lignes\n"); s>>A.n; __ENVOI("nombre de colonnes\n"); s>>A.m; A=MATRIX(A.n,A.m); __ENVOI("Remplisage par ligne puis par colonne\n"); for (int i=0;i>A.M[i]; //A.transpose(); return A; } template T1& operator<<(T1& s, MATRIX<_T> A) { if(A.genre()==IS_SCALAR) {s<MATRIX pow(MATRIX r,MATRIX e)// à généraliser pour les autres fonctions : sin cos exp ln etc... { MATRIX tmp1=r; if ((r.genre()==IS_SCALAR) & (e.genre()==IS_SCALAR)) return pow(r(0,0),e(0,0)); else if(e.genre()==IS_SCALAR) if(e(0,0)>0) for(int i=1;iMATRIX cos(MATRIX r)// à généraliser pour les autres fonctions : sin cos exp ln etc... { MATRIX tmp1=r; int n=tmp1.size_M().n,m=tmp1.size_M().m; for(int i=0;iMATRIX log(MATRIX r)// à généraliser pour les autres fonctions : sin cos exp ln etc... { MATRIX tmp1=r; int n=tmp1.size_M().n,m=tmp1.size_M().m; for(int i=0;iMATRIX fabs(MATRIX r)// à généraliser pour les autres fonctions : sin cos exp ln etc... { MATRIX tmp1=r; int n=tmp1.size_M().n,m=tmp1.size_M().m; for(int i=0;iMATRIX operator<(MATRIX r,MATRIX s) // Compare les matrices. Tout d'abord le nombre d'éléments, si s a plus délément s que r // Ensuite compare leur déterminant si elles sont carrées // Pour finir leur ordre, ainsi 2×2>1×4 // le cas 1×4<4×1 renvoi zero car on ne peut comparer { MATRIX tmp1(1); if(r.size()s.size()) {tmp1(0,0)=0;return tmp1;} else if((r.size_M().n==r.size_M().m)&(s.size_M().n==r.size_M().m)) {tmp1(0,0)=(T)(r.det()MATRIX operator>(MATRIX r,MATRIX s) { MATRIX tmp1(1); if(r.size()>s.size()) {tmp1(0,0)=1;return tmp1;} else if(r.size()s.det());return tmp1;} int rn=r.size_M().n,rm=r.size_M().m,sn=s.size_M().n,sm=s.size_M().m; if(fmin(rn,rm)>fmin(sn,sm)){tmp1(0,0)=1;return tmp1;} tmp1(0,0)=0; return tmp1; } //templateMATRIX operator==(MATRIX r,MATRIX s) //définie par défaut // { // MATRIX tmp1(1); // int rn=r.size_M().n,rm=r.size_M().m,sn=s.size_M().n,sm=s.size_M().m; // if((rn!=sn)|(rm!=sm)){tmp1(0,0)=0;return tmp1;} // else // for(int i=0;i&); int diagonalisation(MATRIX2 A,MATRIX2& D,MATRIX2& P,std::vector& Lambda) { double s,df; D=MATRIX2(A.n);P=MATRIX2(A.n);Lambda.clear(); if (A.n!=A.m) {__ENVOI("imposible de diagonalise une matrice non carre!\n");exit(0);} double inter=0,tmp1,tmp2,tmp3; double pr=200;//precision for (int i=0;i