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 <cmath>
00081 
00082 #include <string>
00083 
00084 using std::string;
00085 
00086 #include <sstream>
00087 
00088 using std::ostringstream;
00089 
00090 #include <typeinfo>
00091 
00092 #include <limits>
00093 using std::numeric_limits;
00094 
00095 
00096 using namespace std;
00097 
00098 
00099 #include "./cimpl.h"
00100 
00101 
00102 namespace CIMPL
00103 {
00104 
00105 
00106 // forward declaration
00107 template< class T > class Array;
00108 template< class T > class Matrix;
00109 template< class T > class SubMatrix;
00110 template< class T > class Vector;
00111 
00113 template< class T >
00114 class Matrix 
00115 {
00116 
00117         friend class Array<T>;
00118         friend class Vector<T>;
00119         friend class SubMatrix<T>;
00120 
00121 
00122 protected:
00123         T *data;
00124         int ndims;  // always 2
00125         int length; // xDim*yDim
00126         int xDim;
00127         int yDim;
00128         Cleaner<T> *clean;   // Reference counting Garbage collector.
00129 
00130         Vector<T> *columns;
00131         
00132 public:
00133         Matrix();
00134         Matrix(const int rows, const int columns);
00135         Matrix(const int rows, const int columns, T init);
00136         
00137         Matrix(string str);
00138 
00139         Matrix(Matrix<T> &m); // copy constructor
00140 
00141         ~Matrix();
00142         
00143         void Clean();
00144 
00147         void Set(const int rows, const int columns, T *_data); 
00148 
00149         const T* DataPtr();
00150         T* Data();
00151 
00152         Matrix<T> Clone() const;
00153         
00154         void SwitchColumns(int i, int j);
00155 
00162         void SyncData2Columns();
00163         
00164 //      SubMatrix<T> Slice(int row1, int row2, int col1, int col2);
00165 //      SubMatrix<T> Slice(string str1, string str2);
00166 
00167         Matrix<T> Slice(int row1, int row2, int col1, int col2);
00168         Matrix<T> Slice(string str1, string str2);
00169 
00170         Vector<T> Slice(string str);
00171 
00172 
00173         const int Columns() const;
00174         const int Rows() const;
00175         const int XDim() const;
00176         const int YDim() const;
00177         const int* Dims() const;
00178         const int Length() const;
00179         const int Numel() const;
00180         const int NDims() const;
00181         void Init(const T init);
00182 
00183         Matrix<T>&  Rand(const double max);
00184         static Matrix<T> Rand(const int rows, const int cols, const double max);
00185 
00186         void ReadFromMatrix(const Matrix<T>& m);
00187         void ReadFromMatrix(const Matrix<T>& m, const int rowStart, const int colStart);
00188 
00189         static Matrix<T> Cat(int dimension, Matrix<T>& m1, Matrix<T>& m2);
00190         static Matrix<T> Cat(int dimension, Matrix<T>& m1, Vector<T>& m2);
00191         static Matrix<T> Cat(int dimension, Vector<T>& m1, Matrix<T>& m2);
00192         static Matrix<T> Cat(int dimension, Vector<T>& m1, Vector<T>& m2);
00193 
00194         static Matrix<T> Ones(int side);
00195         static Matrix<T> Ones(int rows, int cols);
00196         static Matrix<T> Zeros(int side);
00197         static Matrix<T> Zeros(int rows, int cols);
00198 
00199 
00200         static bool IsSquare(Matrix<T>& m);
00201         static bool IsM2MCompatible(Matrix<T>& m1, Matrix<T>& m2);
00202         static Matrix<T> MMultiply(Matrix<T>& m1, Matrix<T>& m2);
00203         static Matrix<T> MMultiply(Matrix<T>& m1, Vector<T>& m2);
00204         static Matrix<T> MMultiply(Vector<T>& m1, Matrix<T>& m2);
00205 
00206         static Matrix<T> Transpose(Matrix<T>& m);
00207         Matrix<T>& Transpose();
00208 
00209         //static Matrix<T> Hermitian(Matrix<T>& m);
00210         //Matrix<T>& Hermitian();
00211 
00212         static bool IsCompatible(Matrix<T>& m1, Matrix<T>& m2);
00213         
00214         // Boolean Operations...
00215         static Matrix<int> And(Matrix<T>& m1, Matrix<T>& m2);
00216         static Matrix<int> Or(Matrix<T>& m1, Matrix<T>& m2);
00217         static Matrix<int> Lt(Matrix<T>& m1, Matrix<T>& m2);
00218         static Matrix<int> Gt(Matrix<T>& m1, Matrix<T>& m2);
00219         static Matrix<int> Le(Matrix<T>& m1, Matrix<T>& m2);
00220         static Matrix<int> Ge(Matrix<T>& m1, Matrix<T>& m2);
00221         static Matrix<int> Eq(Matrix<T>& m1, Matrix<T>& m2);
00222         static Matrix<int> Ne(Matrix<T>& m1, Matrix<T>& m2);
00223 
00224         // Boolean Operations with value type...
00225         static Matrix<int> And(Matrix<T>& m, T v);
00226         static Matrix<int> Or(Matrix<T>& m, T v);
00227         static Matrix<int> Lt(Matrix<T>& m, T v);
00228         static Matrix<int> Gt(Matrix<T>& m, T v);
00229         static Matrix<int> Le(Matrix<T>& m, T v);
00230         static Matrix<int> Ge(Matrix<T>& m, T v);
00231         static Matrix<int> Eq(Matrix<T>& m, T v);
00232         static Matrix<int> Ne(Matrix<T>& m, T v);
00233 
00234 
00235 // Add matrix to another matrix
00236         static Matrix<T> Add(Matrix<T>& m1, Matrix<T>& m2);
00237         static Matrix<T> Subtract(Matrix<T>& m1, Matrix<T>& m2);
00238         static Matrix<T> Multiply(Matrix<T>& m1, Matrix<T>& m2);
00239         static Matrix<T> Divide(Matrix<T>& m1, Matrix<T>& m2);
00240 
00241 // Add value to another matrix
00242         static Matrix<T> Add(Matrix<T>& m1, T v2);
00243         static Matrix<T> Subtract(Matrix<T>& m1, T v2);
00244         static Matrix<T> Subtract(T v2, Matrix<T>& m1);
00245         static Matrix<T> Multiply(Matrix<T>& m1, T v2);
00246         static Matrix<T> Divide(Matrix<T>& m1, T v2);
00247         static Matrix<T> Divide(T v2, Matrix<T>& m1);
00248 
00249 
00250 // Add matrix to "this" matrix
00251         Matrix<T>& Add(Matrix<T>& m);
00252         Matrix<T>& Subtract(Matrix<T>& m);
00253         Matrix<T>& Multiply(Matrix<T>& m);
00254         Matrix<T>& Divide(Matrix<T>& m);
00255 
00256 // Add value to "this" matrix
00257         Matrix<T>& Add(T v);
00258         Matrix<T>& Subtract(T v);
00259         Matrix<T>& Multiply(T v);
00260         Matrix<T>& Divide(T v);
00261 
00262 
00263 //OPERATORS
00264         Matrix<T>& operator= (Matrix<T>& m);
00265         Matrix<T>& operator= (Array<T>& m);
00266         Matrix<T>& operator= (Vector<T>& m);
00267         Matrix<T>& operator= (SubMatrix<T>& m);
00268 
00269         Matrix<T>& operator= (string str);
00270 
00271         Matrix<T> operator+ ();
00272         Matrix<T> operator- ();
00273         Matrix<int> operator! ();
00274         
00275         friend Matrix<T> operator, (Matrix<T>& m1, Matrix<T>& m2)
00276         {
00277                 return Matrix<T>::Cat(2, m1, m2);
00278         }
00279         
00280         friend Matrix<T> operator, (Matrix<T>& m1, Vector<T>& m2)
00281         {
00282                 return Matrix<T>::Cat(2, m1, m2);
00283         }
00284 
00285         friend Matrix<T> operator, (Vector<T>& m1, Matrix<T>& m2)
00286         {
00287                 return Matrix<T>::Cat(2, m1, m2);
00288         }
00289 
00290         
00291         friend Matrix<T> operator| (Matrix<T>& m1, Matrix<T>& m2)
00292         {
00293                 return Matrix<T>::Cat(1, m1, m2);
00294         }
00295         
00296         friend Matrix<T> operator| (Matrix<T>& m1, Vector<T>& m2)
00297         {
00298                 return Matrix<T>::Cat(1, m1, m2);
00299         }
00300 
00301         friend Matrix<T> operator| (Vector<T>& m1, Matrix<T>& m2)
00302         {
00303                 return Matrix<T>::Cat(1, m1, m2);
00304         }
00305 
00306 
00307 
00308         // Transpose
00309         Matrix<T> operator~ ();
00310 
00311         friend ostream& operator<< (ostream& output, Matrix<T>& m)
00312         {
00313                 int bufferWidth = 80;
00314                 int lm = m.Rows();
00315                 int rowNoWidth = (int)log10((double)(lm-1))+2;
00316                 int infoWidth = 3+rowNoWidth+2;
00317 
00318                 int maxLength  = 1;
00319                 for(int i=0; i<m.Length(); i++)
00320                 {
00321                         ostringstream oS;
00322                         oS << m.ElemNC(i);
00323                         int l = (int)oS.str().length();
00324                         if(l>maxLength)
00325                         {
00326                                 maxLength = l;
00327                         }
00328                 }
00329 
00330                 int columnWidth = maxLength+3;
00331                 int columnMax = (bufferWidth-infoWidth)/columnWidth;
00332                 
00333                 output << typeid(m).name() << " of size " << m.Rows() << "x" << m.Columns() << endl;
00334                 output << "=======================" << endl;
00335                 if(m.Columns() <= columnMax)
00336                 {
00337                         for(int i=0;i<m.Rows();i++)
00338                         {
00339                                 output << "ROW" << right << setw(rowNoWidth) << i+1 << "|";
00340                                 for(int j=0;j<m.Columns();j++)
00341                                 {
00342                                         output << right << setw(columnWidth) << m.ElemNC(i,j);
00343                                 }
00344                                 output << endl;
00345                         }
00346                 }
00347                 else
00348                 {
00349                         int groups = m.Columns()/columnMax;
00350                         int leftover = m.Columns() % columnMax;
00351                         for(int k=0; k<groups; k++)
00352                         {
00353                                 output << endl;
00354                                 output << "----------------------" << endl;
00355                                 output << "Columns " << k*columnMax+1 << " through " << k*columnMax+columnMax-1+1 << endl;
00356                                 output << "----------------------" << endl;
00357                                 for(int i=0;i<m.Rows();i++)
00358                                 {
00359                                         output << "ROW" << right << setw(rowNoWidth) << i+1 << "|";
00360                                         for(int j=columnMax*k;j<columnMax*(k+1);j++)
00361                                         {
00362                                                 output << right << setw(columnWidth) << m.ElemNC(i,j);
00363                                         }
00364                                         output << endl;
00365                                 }
00366                         }
00367                         if(leftover > 0)
00368                         {
00369                                 output << endl;
00370                                 output << "----------------------" << endl;
00371                                 output << "Columns " << groups*columnMax+1 << " through " << groups*columnMax+leftover-1+1 << endl;
00372                                 output << "----------------------" << endl;
00373                                 for(int i=0;i<m.Rows();i++)
00374                                 {
00375                                         output << "ROW" << right << setw(rowNoWidth) << i+1 << "|";
00376                                         for(int j=groups*columnMax;j<groups*columnMax+leftover;j++)
00377                                         {
00378                                                 output << right << setw(columnWidth) << m.ElemNC(i,j);
00379                                         }
00380                                         output << endl;
00381                                 }
00382                         }
00383                 }
00384                 output << "=======================" << endl;
00385                 output << endl;
00386                 
00387                 return output;
00388         }
00389 
00390 
00391         T& Coor(const int x, const int y);
00392         T& CoorNC(const int x, const int y); // No bounds check
00393         T& Elem(const int _row, const int _col);
00394         T& ElemNC(const int _row, const int _col); // No bounds check
00395         T& Elem(const int i);
00396         T& ElemNC(const int i); // No bounds check
00397 
00398         T& operator() (const int i);
00399         T& operator() (const int i, const int j);
00400         Vector<T>& operator[] (const int i);
00401         
00403         //Matrix<T> operator() (const int row1, const int row2, const int col1, const int col2);
00404         SubMatrix<T> operator() (const int row1, const int row2, const int col1, const int col2);
00405 
00407         //Matrix<T> operator() (string str1, string str2);
00408         SubMatrix<T> operator() (string str1, string str2);
00409         Vector<T> operator() (string str);
00410 
00412         friend Matrix<T> operator& (Matrix<T>& m1, Matrix<T>& m2)
00413         {
00414                 return Matrix<T>::MMultiply(m1, m2);
00415         }
00416         
00418         friend Matrix<T> operator& (Matrix<T>& m1, Vector<T>& m2)
00419         {
00420                 return Matrix<T>::MMultiply(m1, m2);
00421         }
00422 
00424         friend Matrix<T> operator& (Vector<T>& m1, Matrix<T>& m2)
00425         {
00426                 return Matrix<T>::MMultiply(m1, m2);
00427         }
00428 
00429 
00430         // Boolean operations
00431         friend Matrix<int> operator&& (Matrix<T>& m1, Matrix<T>& m2)
00432         {
00433                 return Matrix<T>::And(m1, m2);
00434         }
00435 
00436         friend Matrix<int> operator|| (Matrix<T>& m1, Matrix<T>& m2)
00437         {
00438                 return Matrix<T>::Or(m1, m2);
00439         }
00440 
00441         friend Matrix<int> operator< (Matrix<T>& m1, Matrix<T>& m2)
00442         {
00443                 return Matrix<T>::Lt(m1, m2);
00444         }
00445 
00446         friend Matrix<int> operator> (Matrix<T>& m1, Matrix<T>& m2)
00447         {
00448                 return Matrix<T>::Gt(m1, m2);
00449         }
00450 
00451         friend Matrix<int> operator<= (Matrix<T>& m1, Matrix<T>& m2)
00452         {
00453                 return Matrix<T>::Le(m1, m2);
00454         }
00455 
00456         friend Matrix<int> operator>= (Matrix<T>& m1, Matrix<T>& m2)
00457         {
00458                 return Matrix<T>::Ge(m1, m2);
00459         }
00460 
00461         friend Matrix<int> operator== (Matrix<T>& m1, Matrix<T>& m2)
00462         {
00463                 return Matrix<T>::Eq(m1, m2);
00464         }
00465 
00466         friend Matrix<int> operator!= (Matrix<T>& m1, Matrix<T>& m2)
00467         {
00468                 return Matrix<T>::Ne(m1, m2);
00469         }
00470 
00471 
00472         // Boolean operations with value type
00473         friend Matrix<int> operator&& (Matrix<T>& m, T v)
00474         {
00475                 return Matrix<T>::And(m, v);
00476         }
00477         friend Matrix<int> operator&& (T v, Matrix<T>& m)
00478         {
00479                 return Matrix<T>::And(m, v);
00480         }
00481 
00482         friend Matrix<int> operator|| (Matrix<T>& m, T v)
00483         {
00484                 return Matrix<T>::Or(m, v);
00485         }
00486         friend Matrix<int> operator|| (T v, Matrix<T>& m)
00487         {
00488                 return Matrix<T>::Or(m, v);
00489         }
00490 
00491         friend Matrix<int> operator< (Matrix<T>& m, T v)
00492         {
00493                 return Matrix<T>::Lt(m, v);
00494         }
00495         friend Matrix<int> operator< (T v, Matrix<T>& m)
00496         {
00497                 return Matrix<T>::Gt(m, v);
00498         }
00499 
00500         friend Matrix<int> operator> (Matrix<T>& m, T v)
00501         {
00502                 return Matrix<T>::Gt(m, v);
00503         }
00504         friend Matrix<int> operator> (T v, Matrix<T>& m)
00505         {
00506                 return Matrix<T>::Lt(m, v);
00507         }
00508 
00509         friend Matrix<int> operator<= (Matrix<T>& m, T v)
00510         {
00511                 return Matrix<T>::Le(m, v);
00512         }
00513         friend Matrix<int> operator<= (T v, Matrix<T>& m)
00514         {
00515                 return Matrix<T>::Ge(m, v);
00516         }
00517 
00518         friend Matrix<int> operator>= (Matrix<T>& m, T v)
00519         {
00520                 return Matrix<T>::Ge(m, v);
00521         }
00522         friend Matrix<int> operator>= (T v, Matrix<T>& m)
00523         {
00524                 return Matrix<T>::Le(m, v);
00525         }
00526 
00527         friend Matrix<int> operator== (Matrix<T>& m, T v)
00528         {
00529                 return Matrix<T>::Eq(m, v);
00530         }
00531         friend Matrix<int> operator== (T v, Matrix<T>& m)
00532         {
00533                 return Matrix<T>::Eq(m, v);
00534         }
00535 
00536         friend Matrix<int> operator!= (Matrix<T>& m, T v)
00537         {
00538                 return Matrix<T>::Ne(m, v);
00539         }
00540         friend Matrix<int> operator!= (T v, Matrix<T>& m)
00541         {
00542                 return Matrix<T>::Ne(m, v);
00543         }
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 // Add matrix to another matrix
00553         friend Matrix<T> operator+ (Matrix<T>& m1, Matrix<T>& m2)
00554         {
00555                 return Matrix<T>::Add(m1, m2);
00556         }
00557 
00558         friend Matrix<T> operator- (Matrix<T>& m1, Matrix<T>& m2)
00559         {
00560                 return Matrix<T>::Subtract(m1, m2);
00561         }
00562 
00563         friend Matrix<T> operator* (Matrix<T>& m1, Matrix<T>& m2)
00564         {
00565                 return Matrix<T>::Multiply(m1, m2);
00566         }
00567 
00568         friend Matrix<T> operator/ (Matrix<T>& m1, Matrix<T>& m2)
00569         {
00570                 return Matrix<T>::Divide(m1, m2);
00571         }
00572 
00573 
00574 // Add value to another matrix
00575         friend Matrix<T> operator+ (Matrix<T>& m, T v)
00576         {
00577                 return Matrix<T>::Add(m, v);
00578         }
00579 
00580         friend Matrix<T> operator+ (T v, Matrix<T>& m)
00581         {
00582                 return Matrix<T>::Add(m, v);
00583         }
00584 
00585         friend Matrix<T> operator- (Matrix<T>& m, T v)
00586         {
00587                 return Matrix<T>::Subtract(m, v);
00588         }
00589 
00590         friend Matrix<T> operator- (T v, Matrix<T>& m)
00591         {
00592                 return Matrix<T>::Subtract(v, m);
00593         }
00594 
00595         friend Matrix<T> operator* (Matrix<T>& m, T v)
00596         {
00597                 return Matrix<T>::Multiply(m, v);
00598         }
00599 
00600         friend Matrix<T> operator* (T v, Matrix<T>& m)
00601         {
00602                 return Matrix<T>::Multiply(m, v);
00603         }
00604 
00605         friend Matrix<T> operator/ (Matrix<T>& m, T v)
00606         {
00607                 return Matrix<T>::Divide(m, v);
00608         }
00609 
00610         friend Matrix<T> operator/ (T v, Matrix<T>& m)
00611         {
00612                 return Matrix<T>::Divide(v, m);
00613         }
00614 
00615 
00616 
00617 
00618 // Add inline
00619         Matrix<T>& operator+= (Matrix<T>& m);
00620         Matrix<T>& operator-= (Matrix<T>& m);
00621         Matrix<T>& operator*= (Matrix<T>& m);
00622         Matrix<T>& operator/= (Matrix<T>& m);
00623 
00624         Matrix<T>& operator+= (T v);
00625         Matrix<T>& operator-= (T v);
00626         Matrix<T>& operator*= (T v);
00627         Matrix<T>& operator/= (T v);
00628 
00629         
00630 // TYPE CONVERSIONS
00631         Matrix(Array<T> &m);
00632         Matrix(Vector<T> &m);
00633         Matrix(SubMatrix<T> &m);
00634 
00635 
00636 };
00637 
00638 }; //namespace
00639 
00640 
00641 #include "./Matrix.inl"
00642 
00643 
00644 
00645 
00646 
00647 #endif
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656 
00657 
00658 
00659 

Generated on Thu Jan 20 08:43:44 2005 for CIMPL by  doxygen 1.3.9.1