MeshKit  1.0
matrixtemplate.hpp
Go to the documentation of this file.
00001 
00006 #ifndef __MESHKIT_MATRIXTEMPLATE_H__
00007 #define __MESHKIT_MATRIXTEMPLATE_H__
00008 
00009 #include <string>
00010 #include <iostream>
00011 #include <fstream>
00012 #include <cassert>
00013 #include <cmath>
00014 #include <stdlib.h>
00015 
00016 // defines the Matrix class
00017 template <class T>
00018 class CMatrix
00019 #ifdef __RGGMETER
00020     : public CArrayBase
00021 #endif
00022 {
00023     private:                      
00024         T   **m_pCells;   // address where the matrix of 
00025                           // type T is stored
00026         int m_nRows;      // number of rows in the matrix
00027         int m_nColumns;   // number of columns in the matrix
00028         std::string m_szName; // matrix name
00029         void ErrorHandler (int,int nR=0, int nC=0) const;
00030                                 // handles error conditions
00031         void Release ();        // similar to destructor
00032 
00033     public:                     
00034         CMatrix ();                       // default constructor
00035         CMatrix (int, int);               // constructor
00036         CMatrix (const char *);           // constructor
00037         CMatrix (const char *, int, int); // constructor
00038         CMatrix (const CMatrix<T>&); // copy constructor
00039         ~CMatrix ();                 // destructor
00040         void SetSize (int, int);     // sets the size of the matrix
00041                                      // used with the default constructor
00042 
00043         // helper functions
00044         int GetRows () const;       // gets the current number of rows
00045         int GetColumns () const;    // gets the current number of columns
00046         void GetName (std::string&) const; // gets the matrix name
00047 
00048         // matrix manipulations (mutator)
00049         void Set (T);               // sets the value of all elements
00050                                     // of a matrix
00051         void SetName (const std::string&); // sets the matrix name
00052         T& operator() (int, int);               // row-col access
00053         const T& operator() (int, int) const;   // row-col access
00054         T& operator= (const CMatrix&);  // overloaded = operator
00055         int Read (std::ifstream& IFile);
00056 };
00057 
00058 // =============== definitions ===========================================
00059 template <class T>
00060 CMatrix<T>::CMatrix ()
00061 // ---------------------------------------------------------------------------
00062 // Function: default ctor
00063 // Input:    none
00064 // Output:   none
00065 // ---------------------------------------------------------------------------
00066 {
00067     m_pCells = NULL; 
00068     m_nRows = 0;
00069     m_nColumns = 0;
00070 }
00071 
00072 template <class T>
00073 CMatrix<T>::CMatrix (int nR, int nC)
00074 // ---------------------------------------------------------------------------
00075 // Function: overloaded ctor
00076 // Input:    # of rows and columns
00077 // Output:   none
00078 // ---------------------------------------------------------------------------
00079 {
00080     m_pCells = NULL; 
00081     SetSize (nR, nC);
00082 }
00083 
00084 template <class T>
00085 CMatrix<T>::CMatrix (const char* szName)
00086 // ---------------------------------------------------------------------------
00087 // Function: overloaded ctor
00088 // Input:    matrix name
00089 // Output:   none
00090 // ---------------------------------------------------------------------------
00091 {
00092     m_pCells = NULL; 
00093         m_szName = szName;
00094     m_nRows = 0;
00095     m_nColumns = 0;
00096 }
00097 
00098 template <class T>
00099 CMatrix<T>::CMatrix (const char* szName, int nR, int nC)
00100 // ---------------------------------------------------------------------------
00101 // Function: overloaded ctor
00102 // Input:    matrix name, # of rows and columns
00103 // Output:   none
00104 // ---------------------------------------------------------------------------
00105 {
00106     m_pCells = NULL; 
00107         m_szName = szName;
00108     SetSize (nR, nC);
00109 }
00110 
00111 template <class T>
00112 CMatrix<T>::CMatrix (const CMatrix<T>& A)
00113 // ---------------------------------------------------------------------------
00114 // Function: copy ctor
00115 // Input:    matrix
00116 // Output:   none
00117 // ---------------------------------------------------------------------------
00118 {
00119     m_pCells = NULL;
00120     m_nRows = A.m_nRows;
00121     m_nColumns = A.m_nColumns;
00122         m_szName = A.m_szName;
00123     SetSize (m_nRows, m_nColumns);
00124     for (int i=1; i <= m_nRows; i++)
00125     {
00126         for (int j=1; j <= m_nColumns; j++)
00127         {
00128             m_pCells[i][j] = A.m_pCells[i][j];
00129         }
00130     }
00131 }
00132 
00133 template <class T>
00134 void CMatrix<T>::SetSize (int nR, int nC)
00135 // ---------------------------------------------------------------------------
00136 // Function: dynamically allocates memory
00137 // Input:    matrix size (# of rows and columns)
00138 // Output:   none
00139 // ---------------------------------------------------------------------------
00140 {
00141     // check whether nR and nC are legal
00142     if (nR <= 0 || nC <= 0)
00143         ErrorHandler (3);
00144     Release ();
00145     int size = nR*nC + 1;
00146     try {m_pCells = new T *[nR + 1];}
00147     catch (std::bad_alloc) {ErrorHandler (1);}
00148     try {m_pCells[0] = new T[size];}
00149     catch (std::bad_alloc) {ErrorHandler (1);}
00150     m_pCells[1] = m_pCells[0];
00151     for (int i=2; i <= nR; i++)
00152          m_pCells[i] = m_pCells[i-1]+nC;
00153     m_nRows = nR;
00154     m_nColumns = nC;
00155 #ifdef __RGGMETER
00156     m_dAllocated += static_cast<double>(sizeof(T*)*(nR+1));
00157     m_dAllocated += static_cast<double>(sizeof(T)*size);
00158 #endif
00159 }
00160 
00161 template <class T>
00162 CMatrix<T>::~CMatrix ()
00163 // ---------------------------------------------------------------------------
00164 // Function: dtor
00165 // Input:    none
00166 // Output:   none
00167 // ---------------------------------------------------------------------------
00168 {
00169     // deallocate storage
00170     if (m_pCells != NULL)
00171     {
00172         delete [] m_pCells[0];
00173         m_pCells[0] = NULL;
00174 #ifdef __RGGMETER
00175         m_dDeAllocated += static_cast<double>(sizeof(T*)*(m_nRows+1));
00176 #endif
00177     }
00178     if (m_pCells != NULL)
00179     {
00180         delete [] m_pCells;
00181         m_pCells = NULL;
00182 #ifdef __RGGMETER
00183         int nSize = m_nRows*m_nColumns+1;
00184         m_dDeAllocated += static_cast<double>(sizeof(T)*nSize);
00185 #endif
00186     }
00187     m_nRows = 0;
00188     m_nColumns = 0;
00189 }
00190 
00191 template <class T>
00192 void CMatrix<T>::Release ()
00193 // ---------------------------------------------------------------------------
00194 // Function: dynamically deallocates memory
00195 // Input:    none
00196 // Output:   none
00197 // ---------------------------------------------------------------------------
00198 {
00199     // deallocate storage
00200     if (m_pCells != NULL)
00201     {
00202         delete [] m_pCells[0];
00203 #ifdef __RGGMETER
00204         m_dDeAllocated += static_cast<double>(sizeof(T*)*(m_nRows+1));
00205 #endif
00206     }
00207     if (m_pCells != NULL)
00208     {
00209         delete [] m_pCells;
00210 #ifdef __RGGMETER
00211         int nSize = m_nRows*m_nColumns+1;
00212         m_dDeAllocated += static_cast<double>(sizeof(T)*nSize);
00213 #endif
00214     }
00215     m_pCells = NULL; 
00216     m_nRows = 0;
00217     m_nColumns = 0;
00218 }
00219 
00220 // =============== member functions ===========================================
00221 template <class T>
00222 void CMatrix<T>::SetName (const std::string& szName) 
00223 // ---------------------------------------------------------------------------
00224 // Function: sets the name of the matrix
00225 // Input:    matrix name
00226 // Output:   none
00227 // ---------------------------------------------------------------------------
00228 {
00229     m_szName = szName;
00230 }
00231 
00232 template <class T>
00233 void CMatrix<T>::GetName (std::string& szName) const
00234 // ---------------------------------------------------------------------------
00235 // Function: gets the name of the matrix
00236 // Input:    string to hold matrix name
00237 // Output:   matrix name
00238 // ---------------------------------------------------------------------------
00239 {
00240     szName = m_szName;
00241 }
00242 
00243 template <class T>
00244 int CMatrix<T>::GetRows () const
00245 // ---------------------------------------------------------------------------
00246 // Function: gets the # of rows in the matrix
00247 // Input:    none
00248 // Output:   # of rows
00249 // ---------------------------------------------------------------------------
00250 {
00251     return (m_nRows);
00252 }
00253 
00254 template <class T>
00255 int CMatrix<T>::GetColumns () const
00256 // ---------------------------------------------------------------------------
00257 // Function: gets the # of columns in the matrix
00258 // Input:    none
00259 // Output:   # of columns
00260 // ---------------------------------------------------------------------------
00261 {
00262     return (m_nColumns);
00263 }
00264 
00265 template <class T>
00266 void CMatrix<T>::Set (T dV)
00267 // ---------------------------------------------------------------------------
00268 // Function: sets the value of all the elements in the matrix to the
00269 //           specified value
00270 // Input:    specified value
00271 // Output:   none
00272 // ---------------------------------------------------------------------------
00273 {
00274     for (int i=1; i <= m_nRows; i++)
00275     {
00276         for (int j=1; j <= m_nColumns; j++)
00277         {
00278             m_pCells[i][j] = dV; // or, (*this)(i,j) = dV;
00279         }
00280     }
00281 }
00282 
00283 // ==================== Overloaded Operators ========================
00284 template <class T>
00285 T& CMatrix<T>::operator() (int nR, int nC)
00286 // ---------------------------------------------------------------------------
00287 // Function: overloaded () operator to access matrix contents
00288 //           carries out bound checking
00289 // Input:    row and column indices
00290 // Output:   value at the specified indices
00291 // ---------------------------------------------------------------------------
00292 {
00293 #ifdef _DEBUG
00294     if (nR <= 0 || nR > m_nRows || nC <= 0 || nC > m_nColumns)
00295     {
00296         ErrorHandler (2,nR,nC);
00297         return m_pCells[1][1];
00298     }
00299     else
00300         return m_pCells[nR][nC];
00301 #else
00302         return m_pCells[nR][nC];
00303 #endif
00304 }
00305 
00306 template <class T>
00307 const T& CMatrix<T>::operator() (int nR, int nC) const
00308 // ---------------------------------------------------------------------------
00309 // Function: overloaded () operator to access matrix contents
00310 //           carries out bound checking
00311 // Input:    row and column indices
00312 // Output:   value at the specified indices
00313 // ---------------------------------------------------------------------------
00314 {
00315 #ifdef _DEBUG
00316     if (nR <= 0 || nR > m_nRows || nC <= 0 || nC > m_nColumns)
00317     {
00318         ErrorHandler (2,nR,nC);
00319         return m_pCells[1][1];
00320     }
00321     else
00322         return m_pCells[nR][nC];
00323 #else
00324         return m_pCells[nR][nC];
00325 #endif
00326 }
00327 
00328 template <class T>
00329 T& CMatrix<T>::operator= (const CMatrix& matarg)
00330 // ---------------------------------------------------------------------------
00331 // Function: overloaded = operator 
00332 // Input:    matrix to use as rvalue
00333 // Output:   modified values
00334 // ---------------------------------------------------------------------------
00335 {
00336     // check whether matrix is assigned to itself
00337     if (this != &matarg)
00338     {
00339         // compatible matrices?
00340         if (m_nRows != matarg.m_nRows || m_nColumns != matarg.m_nColumns)
00341         {
00342             ErrorHandler (4);
00343             return (T&)(*this);
00344         }
00345         // now copy
00346         for (int i=1; i <= matarg.m_nRows; i++)
00347         {
00348             for (int j=1; j <= matarg.m_nColumns; j++)
00349             {
00350                 m_pCells[i][j]= matarg.m_pCells[i][j];
00351             }
00352         }
00353     }
00354 
00355     return (T&)(*this);
00356 }
00357 
00358 template <class T>
00359 int CMatrix<T>::Read (std::ifstream& IFile)
00360 // ---------------------------------------------------------------------------
00361 // Function: Reads a matrix rowwise
00362 //    Input: input stream to read from
00363 //   Output: the modified matrix
00364 // ---------------------------------------------------------------------------
00365 {
00366         // read matrix size
00367         int m_nRowsI, nColsI;
00368         IFile >> m_nRowsI >> nColsI;
00369         if (m_nRowsI <= 0 || nColsI <= 0)
00370                 return 1;
00371         if (IFile.eof() || IFile.fail())
00372                 return 1;
00373 
00374         // reallocate?
00375         if (m_nRows != m_nRowsI || m_nColumns != nColsI)
00376                 SetSize (m_nRowsI, nColsI);
00377         
00378         T v;
00379 
00380         for (int i=1; i <= m_nRows; i++)
00381         {
00382                 for (int j=1; j <= m_nColumns; j++)
00383                 {
00384                         IFile >> v;
00385                         m_pCells[i][j] = v;
00386                         if (IFile.eof() || IFile.fail())
00387                                 return 1;
00388                 }
00389         }
00390 
00391         return 0;
00392 }
00393 
00394 // ==================== Error Handler ========================
00395 template <class T>
00396 void CMatrix<T>::ErrorHandler (int nErrorCode, int nR, int nC) const
00397 // ---------------------------------------------------------------------------
00398 // Function: channels error message via std:err
00399 // Input:    error code and optional int value
00400 // Output:   none
00401 // ---------------------------------------------------------------------------
00402 {
00403     std::cerr << "CMatrix: Matrix Name: " << m_szName << ".\n";
00404     switch (nErrorCode)
00405     {
00406         case 1:
00407             std::cerr << "Matrix:: Memory allocation failure.\n";
00408         break;
00409         case 2:
00410             std::cerr << "Matrix::Row-Column reference is out of bounds.\n";
00411         break;
00412         case 3:
00413             std::cerr << "Matrix::Constructor. Invalid number of rows "
00414                          "or columns.\n";
00415         break;
00416         case 4:
00417             std::cerr << "Matrix::Incompatible matrices.\n";
00418         break;
00419     }
00420     std::cerr << "Unable to populate matrix.\n";
00421     exit (1);
00422 }
00423 
00424 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines