Matrix.h

Go to the documentation of this file.
00001 //Copyright (c) 2004-2005, Baris Sumengen
00002 //All rights reserved.
00003 //
00004 // CIMPL Matrix Performance Library
00005 //
00006 //Redistribution and use in source and binary
00007 //forms, with or without modification, are
00008 //permitted provided that the following
00009 //conditions are met:
00010 //
00011 //    * No commercial use is allowed. 
00012 //    This software can only be used
00013 //    for non-commercial purposes. This 
00014 //    distribution is mainly intended for
00015 //    academic research and teaching.
00016 //    * Redistributions of source code must
00017 //    retain the above copyright notice, this
00018 //    list of conditions and the following
00019 //    disclaimer.
00020 //    * Redistributions of binary form must
00021 //    mention the above copyright notice, this
00022 //    list of conditions and the following
00023 //    disclaimer in a clearly visible part 
00024 //    in associated product manual, 
00025 //    readme, and web site of the redistributed 
00026 //    software.
00027 //    * Redistributions in binary form must
00028 //    reproduce the above copyright notice,
00029 //    this list of conditions and the
00030 //    following disclaimer in the
00031 //    documentation and/or other materials
00032 //    provided with the distribution.
00033 //    * The name of Baris Sumengen may not be
00034 //    used to endorse or promote products
00035 //    derived from this software without
00036 //    specific prior written permission.
00037 //
00038 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
00039 //HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00040 //EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
00041 //NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00042 //MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00043 //PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00044 //CONTRIBUTORS BE LIABLE FOR ANY
00045 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00046 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00047 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00048 //OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00049 //DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00050 //HOWEVER CAUSED AND ON ANY THEORY OF
00051 //LIABILITY, WHETHER IN CONTRACT, STRICT
00052 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00053 //OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00054 //OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00055 //POSSIBILITY OF SUCH DAMAGE.
00056 
00057 
00058 
00059 #pragma once
00060 #ifndef MATRIX_H
00061 #define MATRIX_H
00062 
00063 
00064 
00065 #include <iostream>
00066 
00067 using std::cout;
00068 using std::cerr;
00069 using std::endl;
00070 using std::ostream;
00071 using std::right;
00072 using std::fixed;
00073 
00074 #include <iomanip>
00075 
00076 using std::setw;
00077 
00078 #include <cstdlib>
00079 #include <ctime>
00080 #include <math.h>
00081 
00082 #include <string>
00083 
00084 using std::string;
00085 
00086 #include <sstream>
00087 
00088 using std::ostringstream;
00089 
00090 #include <typeinfo>
00091 
00092 
00093 #include "./Cleaner.h"
00094 #include "./Utility.h"
00095 #include "./Array.h"
00096 #include "./Vector.h"
00097 #include "./SubMatrix.h"
00098 #include "./RandomGen.h"
00099 
00100 
00101 // forward declaration
00102 template< class T > class Array;
00103 template< class T > class Matrix;
00104 template< class T > class SubMatrix;
00105 template< class T > class Vector;
00106 template< class T, int l > class List;
00107 template< class T > class VarList;
00108 
00110 template< class T >
00111 class Matrix 
00112 {
00113 
00114     friend class Array<T>;
00115     friend class Vector<T>;
00116     friend class SubMatrix<T>;
00117 
00118 
00119 protected:
00120     T *data;
00121     int ndims;  // always 2
00122     int length; // xDim*yDim
00123     int xDim;
00124     int yDim;
00125     Cleaner<T> *clean;   // Reference counting Garbage collector.
00126 
00127     Vector<T> *columns;
00128     
00129 public:
00130     Matrix();
00131     Matrix(const int rows, const int columns);
00132     Matrix(const int rows, const int columns, T init);
00133     
00134 
00135     Matrix(Matrix<T> &m); // copy constructor
00136 
00137     ~Matrix();
00138     
00139     void Clean();
00140 
00143     void Set(const int rows, const int columns, T *_data); 
00144 
00145     const T* DataPtr();
00146     T* Data();
00147 
00148     Matrix<T> Clone() const;
00149     
00150     void SwitchColumns(int i, int j);
00151 
00158     void SyncData2Columns();
00159     
00160     SubMatrix<T> Slice(int row1, int row2, int col1, int col2);
00161 
00162 
00163     const int Columns() const;
00164     const int Rows() const;
00165     const int XDim() const;
00166     const int YDim() const;
00167     const int* Dims() const;
00168     const List<int,2> Size() const;
00169     const int Length() const;
00170     const int NDims() const;
00171     void Init(const T init);
00172     Matrix<T>&  Rand();
00173     Matrix<T>&  Rand(const double max);
00174     static Matrix<T> Rand(const int rows, const int cols);
00175     static Matrix<T> Rand(const int rows, const int cols, const double max);
00176 
00177     void ReadFromMatrix(const Matrix<T>& m);
00178     void ReadFromMatrix(const Matrix<T>& m, const int rowStart, const int colStart);
00179 
00180 
00181     static bool IsSquare(Matrix<T>& m);
00182     static bool IsM2MCompatible(Matrix<T>& m1, Matrix<T>& m2);
00183     static Matrix<T> MMultiply(Matrix<T>& m1, Matrix<T>& m2);
00184     static Matrix<T> MMultiply(Matrix<T>& m1, Vector<T>& m2);
00185     static Matrix<T> MMultiply(Vector<T>& m1, Matrix<T>& m2);
00186 
00187     static Matrix<T> Transpose(Matrix<T>& m);
00188     Matrix<T>& Transpose();
00189 
00190     //static Matrix<T> Hermitian(Matrix<T>& m);
00191     //Matrix<T>& Hermitian();
00192 
00193     static bool IsCompatible(Matrix<T>& m1, Matrix<T>& m2);
00194     
00195     // Boolean Operations...
00196     static Matrix<int> And(Matrix<T>& m1, Matrix<T>& m2);
00197     static Matrix<int> Or(Matrix<T>& m1, Matrix<T>& m2);
00198     static Matrix<int> Lt(Matrix<T>& m1, Matrix<T>& m2);
00199     static Matrix<int> Gt(Matrix<T>& m1, Matrix<T>& m2);
00200     static Matrix<int> Le(Matrix<T>& m1, Matrix<T>& m2);
00201     static Matrix<int> Ge(Matrix<T>& m1, Matrix<T>& m2);
00202     static Matrix<int> Eq(Matrix<T>& m1, Matrix<T>& m2);
00203     static Matrix<int> Ne(Matrix<T>& m1, Matrix<T>& m2);
00204 
00205     // Boolean Operations with value type...
00206     static Matrix<int> And(Matrix<T>& m, T v);
00207     static Matrix<int> Or(Matrix<T>& m, T v);
00208     static Matrix<int> Lt(Matrix<T>& m, T v);
00209     static Matrix<int> Gt(Matrix<T>& m, T v);
00210     static Matrix<int> Le(Matrix<T>& m, T v);
00211     static Matrix<int> Ge(Matrix<T>& m, T v);
00212     static Matrix<int> Eq(Matrix<T>& m, T v);
00213     static Matrix<int> Ne(Matrix<T>& m, T v);
00214 
00215 
00216 // Add matrix to another matrix
00217     static Matrix<T> Add(Matrix<T>& m1, Matrix<T>& m2);
00218     static Matrix<T> Subtract(Matrix<T>& m1, Matrix<T>& m2);
00219     static Matrix<T> Multiply(Matrix<T>& m1, Matrix<T>& m2);
00220     static Matrix<T> Divide(Matrix<T>& m1, Matrix<T>& m2);
00221 
00222 // Add value to another matrix
00223     static Matrix<T> Add(Matrix<T>& m1, T v2);
00224     static Matrix<T> Subtract(Matrix<T>& m1, T v2);
00225     static Matrix<T> Subtract(T v2, Matrix<T>& m1);
00226     static Matrix<T> Multiply(Matrix<T>& m1, T v2);
00227     static Matrix<T> Divide(Matrix<T>& m1, T v2);
00228     static Matrix<T> Divide(T v2, Matrix<T>& m1);
00229 
00230 
00231 // Add matrix to "this" matrix
00232     Matrix<T>& Add(Matrix<T>& m);
00233     Matrix<T>& Subtract(Matrix<T>& m);
00234     Matrix<T>& Multiply(Matrix<T>& m);
00235     Matrix<T>& Divide(Matrix<T>& m);
00236 
00237 // Add value to "this" matrix
00238     Matrix<T>& Add(T v);
00239     Matrix<T>& Subtract(T v);
00240     Matrix<T>& Multiply(T v);
00241     Matrix<T>& Divide(T v);
00242 
00243 
00244 //OPERATORS
00245     Matrix<T>& operator= (Matrix<T>& m);
00246     Matrix<T>& operator= (Array<T>& m);
00247     Matrix<T>& operator= (Vector<T>& m);
00248 
00249 
00250     Matrix<T> operator+ ();
00251     Matrix<T> operator- ();
00252     Matrix<int> operator! ();
00253 
00254     // Transpose
00255     Matrix<T> operator~ ();
00256 
00257     friend ostream& operator<< (ostream& output, Matrix<T>& m)
00258     {
00259         int bufferWidth = 80;
00260         int lm = m.Rows();
00261         int rowNoWidth = (int)log10((double)(lm-1))+2;
00262         int infoWidth = 3+rowNoWidth+2;
00263 
00264         int maxLength  = 1;
00265         for(int i=0; i<m.Length(); i++)
00266         {
00267             ostringstream oS;
00268             oS << m.ElemNC(i);
00269             int l = (int)oS.str().length();
00270             if(l>maxLength)
00271             {
00272                 maxLength = l;
00273             }
00274         }
00275 
00276         int columnWidth = maxLength+3;
00277         int columnMax = (bufferWidth-infoWidth)/columnWidth;
00278         
00279         output << typeid(m).name() << " of size " << m.Rows() << "x" << m.Columns() << endl;
00280         output << "=======================" << endl;
00281         if(m.Columns() <= columnMax)
00282         {
00283             for(int i=0;i<m.Rows();i++)
00284             {
00285                 output << "ROW" << right << setw(rowNoWidth) << i+1 << "|";
00286                 for(int j=0;j<m.Columns();j++)
00287                 {
00288                     output << right << setw(columnWidth) << m.ElemNC(i,j);
00289                 }
00290                 output << endl;
00291             }
00292         }
00293         else
00294         {
00295             int groups = m.Columns()/columnMax;
00296             int leftover = m.Columns() % columnMax;
00297             for(int k=0; k<groups; k++)
00298             {
00299                 output << endl;
00300                 output << "----------------------" << endl;
00301                 output << "Columns " << k*columnMax+1 << " through " << k*columnMax+columnMax-1+1 << endl;
00302                 output << "----------------------" << endl;
00303                 for(int i=0;i<m.Rows();i++)
00304                 {
00305                     output << "ROW" << right << setw(rowNoWidth) << i+1 << "|";
00306                     for(int j=columnMax*k;j<columnMax*(k+1);j++)
00307                     {
00308                         output << right << setw(columnWidth) << m.ElemNC(i,j);
00309                     }
00310                     output << endl;
00311                 }
00312             }
00313             if(leftover > 0)
00314             {
00315                 output << endl;
00316                 output << "----------------------" << endl;
00317                 output << "Columns " << groups*columnMax+1 << " through " << groups*columnMax+leftover-1+1 << endl;
00318                 output << "----------------------" << endl;
00319                 for(int i=0;i<m.Rows();i++)
00320                 {
00321                     output << "ROW" << right << setw(rowNoWidth) << i+1 << "|";
00322                     for(int j=groups*columnMax;j<groups*columnMax+leftover;j++)
00323                     {
00324                         output << right << setw(columnWidth) << m.ElemNC(i,j);
00325                     }
00326                     output << endl;
00327                 }
00328             }
00329         }
00330         output << "=======================" << endl;
00331         output << endl;
00332         
00333         return output;
00334     }
00335 
00336 
00337     T& Coor(const int x, const int y);
00338     T& CoorNC(const int x, const int y); // No bounds check
00339     T& Elem(const int _row, const int _col);
00340     T& ElemNC(const int _row, const int _col); // No bounds check
00341     T& Elem(const int i);
00342     T& ElemNC(const int i); // No bounds check
00343 
00344     T& operator() (const int i);
00345     T& operator() (const int i, const int j);
00346     Vector<T>& operator[] (const int i);
00347     
00349     Matrix<T> operator() (const int row1, const int row2, const int col1, const int col2);
00350 
00351 
00353     friend Matrix<T> operator& (Matrix<T>& m1, Matrix<T>& m2)
00354     {
00355         return Matrix<T>::MMultiply(m1, m2);
00356     }
00357     
00359     friend Matrix<T> operator& (Matrix<T>& m1, Vector<T>& m2)
00360     {
00361         return Matrix<T>::MMultiply(m1, m2);
00362     }
00363 
00365     friend Matrix<T> operator& (Vector<T>& m1, Matrix<T>& m2)
00366     {
00367         return Matrix<T>::MMultiply(m1, m2);
00368     }
00369 
00370 
00371     // Boolean operations
00372     friend Matrix<int> operator&& (Matrix<T>& m1, Matrix<T>& m2)
00373     {
00374         return Matrix<T>::And(m1, m2);
00375     }
00376 
00377     friend Matrix<int> operator|| (Matrix<T>& m1, Matrix<T>& m2)
00378     {
00379         return Matrix<T>::Or(m1, m2);
00380     }
00381 
00382     friend Matrix<int> operator< (Matrix<T>& m1, Matrix<T>& m2)
00383     {
00384         return Matrix<T>::Lt(m1, m2);
00385     }
00386 
00387     friend Matrix<int> operator> (Matrix<T>& m1, Matrix<T>& m2)
00388     {
00389         return Matrix<T>::Gt(m1, m2);
00390     }
00391 
00392     friend Matrix<int> operator<= (Matrix<T>& m1, Matrix<T>& m2)
00393     {
00394         return Matrix<T>::Le(m1, m2);
00395     }
00396 
00397     friend Matrix<int> operator>= (Matrix<T>& m1, Matrix<T>& m2)
00398     {
00399         return Matrix<T>::Ge(m1, m2);
00400     }
00401 
00402     friend Matrix<int> operator== (Matrix<T>& m1, Matrix<T>& m2)
00403     {
00404         return Matrix<T>::Eq(m1, m2);
00405     }
00406 
00407     friend Matrix<int> operator!= (Matrix<T>& m1, Matrix<T>& m2)
00408     {
00409         return Matrix<T>::Ne(m1, m2);
00410     }
00411 
00412 
00413     // Boolean operations with value type
00414     friend Matrix<int> operator&& (Matrix<T>& m, T v)
00415     {
00416         return Matrix<T>::And(m, v);
00417     }
00418     friend Matrix<int> operator&& (T v, Matrix<T>& m)
00419     {
00420         return Matrix<T>::And(m, v);
00421     }
00422 
00423     friend Matrix<int> operator|| (Matrix<T>& m, T v)
00424     {
00425         return Matrix<T>::Or(m, v);
00426     }
00427     friend Matrix<int> operator|| (T v, Matrix<T>& m)
00428     {
00429         return Matrix<T>::Or(m, v);
00430     }
00431 
00432     friend Matrix<int> operator< (Matrix<T>& m, T v)
00433     {
00434         return Matrix<T>::Lt(m, v);
00435     }
00436     friend Matrix<int> operator< (T v, Matrix<T>& m)
00437     {
00438         return Matrix<T>::Gt(m, v);
00439     }
00440 
00441     friend Matrix<int> operator> (Matrix<T>& m, T v)
00442     {
00443         return Matrix<T>::Gt(m, v);
00444     }
00445     friend Matrix<int> operator> (T v, Matrix<T>& m)
00446     {
00447         return Matrix<T>::Lt(m, v);
00448     }
00449 
00450     friend Matrix<int> operator<= (Matrix<T>& m, T v)
00451     {
00452         return Matrix<T>::Le(m, v);
00453     }
00454     friend Matrix<int> operator<= (T v, Matrix<T>& m)
00455     {
00456         return Matrix<T>::Ge(m, v);
00457     }
00458 
00459     friend Matrix<int> operator>= (Matrix<T>& m, T v)
00460     {
00461         return Matrix<T>::Ge(m, v);
00462     }
00463     friend Matrix<int> operator>= (T v, Matrix<T>& m)
00464     {
00465         return Matrix<T>::Le(m, v);
00466     }
00467 
00468     friend Matrix<int> operator== (Matrix<T>& m, T v)
00469     {
00470         return Matrix<T>::Eq(m, v);
00471     }
00472     friend Matrix<int> operator== (T v, Matrix<T>& m)
00473     {
00474         return Matrix<T>::Eq(m, v);
00475     }
00476 
00477     friend Matrix<int> operator!= (Matrix<T>& m, T v)
00478     {
00479         return Matrix<T>::Ne(m, v);
00480     }
00481     friend Matrix<int> operator!= (T v, Matrix<T>& m)
00482     {
00483         return Matrix<T>::Ne(m, v);
00484     }
00485 
00486 
00487 
00488 
00489 
00490 
00491 
00492 
00493 // Add matrix to another matrix
00494     friend Matrix<T> operator+ (Matrix<T>& m1, Matrix<T>& m2)
00495     {
00496         return Matrix<T>::Add(m1, m2);
00497     }
00498 
00499     friend Matrix<T> operator- (Matrix<T>& m1, Matrix<T>& m2)
00500     {
00501         return Matrix<T>::Subtract(m1, m2);
00502     }
00503 
00504     friend Matrix<T> operator* (Matrix<T>& m1, Matrix<T>& m2)
00505     {
00506         return Matrix<T>::Multiply(m1, m2);
00507     }
00508 
00509     friend Matrix<T> operator/ (Matrix<T>& m1, Matrix<T>& m2)
00510     {
00511         return Matrix<T>::Divide(m1, m2);
00512     }
00513 
00514 
00515 // Add value to another matrix
00516     friend Matrix<T> operator+ (Matrix<T>& m, T v)
00517     {
00518         return Matrix<T>::Add(m, v);
00519     }
00520 
00521     friend Matrix<T> operator+ (T v, Matrix<T>& m)
00522     {
00523         return Matrix<T>::Add(m, v);
00524     }
00525 
00526     friend Matrix<T> operator- (Matrix<T>& m, T v)
00527     {
00528         return Matrix<T>::Subtract(m, v);
00529     }
00530 
00531     friend Matrix<T> operator- (T v, Matrix<T>& m)
00532     {
00533         return Matrix<T>::Subtract(v, m);
00534     }
00535 
00536     friend Matrix<T> operator* (Matrix<T>& m, T v)
00537     {
00538         return Matrix<T>::Multiply(m, v);
00539     }
00540 
00541     friend Matrix<T> operator* (T v, Matrix<T>& m)
00542     {
00543         return Matrix<T>::Multiply(m, v);
00544     }
00545 
00546     friend Matrix<T> operator/ (Matrix<T>& m, T v)
00547     {
00548         return Matrix<T>::Divide(m, v);
00549     }
00550 
00551     friend Matrix<T> operator/ (T v, Matrix<T>& m)
00552     {
00553         return Matrix<T>::Divide(v, m);
00554     }
00555 
00556 
00557 
00558 
00559 // Add inline
00560     Matrix<T>& operator+= (Matrix<T>& m);
00561     Matrix<T>& operator-= (Matrix<T>& m);
00562     Matrix<T>& operator*= (Matrix<T>& m);
00563     Matrix<T>& operator/= (Matrix<T>& m);
00564 
00565     Matrix<T>& operator+= (T v);
00566     Matrix<T>& operator-= (T v);
00567     Matrix<T>& operator*= (T v);
00568     Matrix<T>& operator/= (T v);
00569 
00570     
00571 // TYPE CONVERSIONS
00572     Matrix(Array<T> &m);
00573     Matrix(Vector<T> &m);
00574 
00575 
00576 };
00577 
00578 #include "./Matrix.inl"
00579 
00580 
00581 
00582 
00583 #endif
00584 
00585 
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 

CIMPL 0.1 Code Reference. Copyright © 2004, Baris Sumengen. All rights reserved.