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
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
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
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
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)
00126 return false;
00127
00128 M.swap_lines(line, col);
00129
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
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
00152 for(line= col; line< this->nb_lines; line++)
00153 if( M(line, col) != 0 )
00154 break;
00155 if(line == this->nb_lines)
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
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
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