Main Page | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

matrix.H

Go to the documentation of this file.
00001 
00006 #ifndef _MATRIX_H_
00007 #define _MATRIX_H_
00008 
00009 #include "tables.H"
00010 using namespace std;
00011 
00013 
00022 template <class T> class Matrix : public Table<T> {
00023 public:
00024   Matrix<T>() : Table<T>() {this->left='('; this->right=')';}
00025   Matrix<T>(long i, long j) : Table<T>(i,j) {this->left='('; this->right=')';}
00026   Matrix<T>(const Matrix<T>& that) : Table<T>(that) {}
00027 
00028   void make_identity(long n)
00029   {
00030     this->resize(n, n);
00031     long i, j;
00032     for(i= 0; i< this->nb_lines; i++)
00033       for(j= 0; j< this->nb_cols; j++)
00034         if( i == j )
00035           this->pdata[i][i]= 1;
00036         else
00037           this->pdata[i][j]= 0;
00038   }
00039 
00040 
00041   void get_data_from_matrix_list(const list< Matrix<T> >& L){
00042     long li, col, i, j, total;
00043     typename list< Matrix<T> >::const_iterator it;
00044     
00045     //find out number of lines and cols
00046     li= col= 0;
00047     for(it= L.begin(); it!= L.end(); it++){
00048       li+= it->nlines();
00049       col= col > it->ncols() ? col : it->ncols();
00050     }
00051     //get the memory for it
00052     delete[] this->data;
00053     this->data= new T[col*li];
00054     this->nb_lines= li;
00055     this->nb_cols= col;
00056     this->tuple_size= col*li;
00057     delete[] this->pdata;
00058     this->write_ptrs();
00059 
00060     //now copy
00061     for(total= 0, it=L.begin(); it!= L.end(); total+= it->nlines(), it++)
00062       for(i=0; i< it->nlines(); i++)
00063         for(j=0; j< it->ncols(); j++)
00064           this->pdata[total+i][j]= (*it)(i,j);
00065 
00066   }
00067 
00068   
00069 
00071   void swap_lines(long i, long j){
00072     long k;
00073     T dummy;
00074     
00075     if( i == j )
00076       return;
00077 
00078     for(k=0; k< this->nb_cols; k++){
00079       dummy= this->pdata[i][k];
00080       this->pdata[i][k]=  this->pdata[j][k];
00081       this->pdata[j][k]= dummy;
00082     }
00083   }
00085   void add_line(long i, long j, T coeff){
00086     long k;
00087 
00088     for(k=0; k< this->nb_cols; k++)
00089       this->pdata[i][k]+= this->pdata[j][k]*coeff;
00090   }
00091 
00093   void multiply_line(long i, T coeff)
00094   {
00095     for(long j=0; j< this->nb_cols; j++)
00096       this->pdata[i][j]*= coeff;
00097   }
00098   
00099     
00100 
00102 
00108   bool is_invertible() const {
00109     Matrix<T> M;
00110     long col, line;
00111         
00112 
00113     if( this->nb_cols != this->nb_lines )
00114       return false;
00115 
00116     M= *this;
00117     for(col=0; col < this->nb_cols; col++){
00118 
00119       // look for a nonzero entry
00120       for(line= col; line< this->nb_lines; line++)
00121         if( M(line, col) != 0 )
00122           break;
00123       
00124 
00125       if(line == this->nb_lines) //not found ?
00126         return false;
00127       // else swap the lines
00128       M.swap_lines(line, col);
00129       // and triangulate
00130       for(line= col + 1; line < this->nb_lines; line++)
00131         M.add_line(line, col, - M(line, col) / M(col, col) );
00132     }
00133     return true;
00134 
00135   }
00136 
00138   Matrix<T> inverse() const 
00139   {
00140     if(this->nb_cols != this->nb_lines)
00141       return *this;
00142     //else...
00143     Matrix<T> M, N;
00144     M= *this;
00145     N.make_identity(this->nb_lines);
00146     long line, col;
00147     T c;
00148     
00149         
00150     for(col=0; col < this->nb_cols; col++){
00151       //looks for a nonzero entry in M
00152       for(line= col; line< this->nb_lines; line++)
00153         if( M(line, col) != 0 )
00154           break;
00155       if(line == this->nb_lines) //not found ?
00156         return *this;
00157       c= 1 / M(line,col);
00158       M.multiply_line(line, c);
00159       N.multiply_line(line, c);
00160       M.swap_lines(line, col);
00161       N.swap_lines(line, col);
00162       for(line=0; line<this->nb_lines; line++)
00163         if(line != col){
00164           c= -M(line, col);
00165           M.add_line(line, col, c);
00166           N.add_line(line, col, c);
00167         }
00168     
00169     }
00170     
00171     return N;
00172   }
00173   
00174 
00175 
00177 
00183   Matrix<T>& operator+=(const Matrix<T>& that){
00184     long i;
00185     
00186     if( (this->nb_lines != that.nb_lines) || (this->nb_cols != that.nb_cols) )
00187       return *this;
00188     for(i=0; i < this->tuple_size; i++){
00189       this->data[i] += that.data[i];
00190     }
00191     return *this;
00192   }
00194 
00200    Matrix<T>& operator-=(const Matrix<T>& that){
00201     long i,j;
00202     
00203     if( (this->nb_lines != that.nb_lines) || (this->nb_cols != that.nb_cols) )
00204       return *this;
00205     for(i=0; i < this->tuple_size; i++){
00206       this->data[i] -= that.data[i];
00207     }
00208     return *this;
00209   }
00210 
00211 
00212 
00214   Matrix<T>& operator*=(const Matrix<T>& that){
00215     Matrix<T> ans;
00216     
00217     matrixprod(*this, that, ans);
00218     this->steal( ans );
00219     return *this;
00220   }
00221     //OLD VERSION
00222 //     Tuple<T> temp;
00223 //     Matrix<T> *duplicate;
00224 //     T element;
00225 //     long current_line, current_col,j;
00226 
00227 //     if( this->nb_cols != that.nb_lines )
00228 //       return *this;
00229     
00230 //     if( this == &that ){   // if we are squaring this...
00231 //       duplicate=new Matrix<T>(*this);
00232 //       (*this) *= (*duplicate);
00233 //       delete duplicate;
00234 //       return *this;
00235 //     }
00236 
00237 //     this->resize(this->nb_lines, that.nb_cols);
00238 //     temp.resize(that.nb_cols);
00239 
00240 //     for(current_line=0; current_line < this->nb_lines; current_line++){
00241 //       for(current_col=0; current_col < that.nb_cols; current_col++){
00242 //      element= this->pdata[current_line][0];
00243 //      element *= that.pdata[0][current_col];
00244 //      temp[current_col]= element;
00245 //      for(j=1; j < that.nb_lines; j++){
00246 //        element= this->pdata[current_line][j];
00247 //        element *= that.pdata[j][current_col];
00248 //        temp[current_col] += element;
00249 //      }
00250 //       }
00251 //       readline(current_line, temp);
00252 //     }
00253 
00254 //     return *this;
00255 //  }
00256 
00257   Matrix<T>& operator*=(const T& c) {
00258     long i;
00259 
00260     for(i=0; i< this->nb_lines * this->nb_cols; i++)
00261       this->data[i] *= c;
00262      
00263     return *this;
00264   }
00265 
00266   Matrix<T> operator*(const T& c) const {
00267     Matrix<T> ans;
00268 
00269     ans= *this;
00270     ans*= c;
00271     return ans;
00272   }
00273 
00274 
00275 
00277 
00282 friend void matrixprod(const Matrix<T>& A, const Matrix<T>& B, Matrix<T>& ans) {
00283     T element;
00284     long current_line, current_col,j;
00285 
00286     if( A.nb_cols != B.nb_lines)
00287       return;
00288     
00289     ans.resize( A.nb_lines , B.nb_cols );
00290 
00291     for(current_line=0; current_line < A.nb_lines; current_line++){
00292       for(current_col=0; current_col< B.nb_cols; current_col++){
00293         element = A(current_line,0);
00294         element  *= B(0,current_col);   
00295         ans(current_line,current_col)= element;
00296         for(j=1; j < A.nb_cols; j++){
00297           element = A(current_line,j);
00298           element  *= B(j,current_col); 
00299           ans(current_line,current_col) += element;
00300         }
00301       }
00302     }
00303 
00304     return;
00305   }
00306 
00308 
00312   Matrix<T> operator*(const Matrix<T>& that) const {
00313     Matrix<T> ans;
00314 
00315     matrixprod(*this, that, ans);
00316     return ans;
00317   }
00318 
00320   Matrix<T> operator+(const Matrix<T>& that) const {
00321     Matrix<T> ans;
00322 
00323     ans= *this;
00324     ans+= that;
00325     return ans;
00326   }
00327 
00328 
00329 };
00330 
00331 #endif

Generated on Wed Jun 18 17:22:40 2008 for Pierre Guillot by  doxygen 1.3.9.1