TAPs 0.7.7.3
SPT_Matrix.h
Go to the documentation of this file.
00001 /******************************************************************************
00002 SP_Matrix.h
00003 
00004 Matrix class and its operations
00005 
00006 Sukitti Punak   (11/10/2003)
00007 Latest Update   (11/11/2003)
00008 ******************************************************************************/
00009 
00010 #ifndef SPT_MATRIX_H
00011 #define SPT_MATRIX_H
00012 
00013 #include <iostream>
00014 #include <cassert>
00015 #include <cmath>
00016 using std::cout;
00017 using std::endl;
00018 using std::ostream;
00019 
00020 #include "SPT_Point3_Vector3.h"
00021 
00022 template< typename T >
00023 class MATRIX;   // forward reference
00024 
00025 //===============================================================================================
00026 //
00027 //                          C L A S S    D E C L A R A T I O N S
00028 //
00029 //===============================================================================================
00030 // CLASS:   SPtMatrix  ********************************************************
00031 // Desc:  3-D Point
00032 template< typename T >
00033 class SPtMatrix
00034 {
00035     // Friend Functions for Operator Overloading
00036     // Add vector v2 to vector v1
00037     friend ostream &operator<<( ostream &output, const SPtMatrix< T > &M )
00038     {
00039         int r, c;
00040 
00041         output << "A(n) " << m_iRows << " x " << m_iCols << " Matrix \n";
00042         output.precision(10);
00043         for ( r = 0; r < m_iRows; r++ ) {
00044             output << "| ";
00045             for ( c = 0; c < m_iCols; c++ ) {
00046                 output.width( 20 ); output << m_tElement[r][c];
00047             }
00048             output << " |" << endl;
00049         }
00050         output.precision(6);
00051         
00052         return output;
00053     }
00054 
00055     friend SPtMatrix< T > operator*( double s, const SPtMatrix< T > &M )
00056     {
00057         SPtMatrix< double > temp( M );
00058         temp *= s;
00059         return temp;
00060     }
00061 
00062     friend SPtMatrix< T > operator-( const SPtMatrix< T > &A, const SPtMatrix< T > &B )
00063     {
00064         // Both matrices have to be the same order!
00065         if ( A.m_iRows != B.m_iRows || A.m_iCols != B.m_iCols )     return NULL;
00066 
00067         SPtMatrix< T > temp( A );
00068         for ( int r = 0; r < temp.m_iRows; r++ ) {
00069             for ( int c = 0; c < temp.m_iCols; c++ ) {
00070                 temp.m_tElement[r][c] -= B.m_tElement[r][c];
00071             }
00072         }
00073 
00074         return temp;
00075     }
00076     friend SPtMatrix< T > operator+( const SPtMatrix< T > &A, const SPtMatrix< T > &B )
00077     {
00078         // Both matrices have to be the same order!
00079         if ( A.m_iRows != B.m_iRows || A.m_iCols != B.m_iCols )     return NULL;
00080 
00081         SPtMatrix< T > temp( A );
00082         for ( int r = 0; r < temp.m_iRows; r++ ) {
00083             for ( int c = 0; c < temp.m_iCols; c++ ) {
00084                 temp.m_tElement[r][c] += B.m_tElement[r][c];
00085             }
00086         }
00087 
00088         return temp;
00089     }
00090     friend class MatrixOperations;
00091 
00092 // Data Members  --------------------------------------------------------------
00093 public:
00094     T   **m_tElement;
00095     int m_iRows, m_iCols;
00096 
00097 // Member Functions  ----------------------------------------------------------
00098 public:
00099     // Constructors  ------------------------------------------------
00100     SPtMatrix( int = 3, int = 3 );
00101     //SPtMatrix( T **e, int r, int c ) : m_tElement< T >( e ), m_iRows( r ), m_iCols( c ) { }
00102     SPtMatrix( const SPtMatrix< T > & );
00103     SPtMatrix( const SPtVector3< T > & );
00104     SPtMatrix( const SPtPoint3< T > & );
00105     ~SPtMatrix();
00106 
00107 
00108     // Useful Member Functions      ---------------------------------
00109     // Display Elements
00110     void DisplayElements() const;
00111     T    Get( int, int ) const;
00112     void Set( int, int, T );
00113     bool SetToIdentity();
00114     int GetNoOfRows() const;
00115     int GetNoOfCols() const;
00116     void GetNoOfRowsAndCols( int &, int & ) const;
00117     
00118 
00119     // Matrix Operations        -------------------------------------
00120     SPtMatrix< T > GetTranspose() const;
00121     SPtMatrix< T > &Transpose();
00122 
00123 
00124     // Overloaded Operators     -------------------------------------
00125     // assign matrix
00126     SPtMatrix< T > &operator=( const SPtMatrix< T > & );
00127     // negation
00128     SPtMatrix< T > operator-() const;
00129     // add/assign matrix
00130     SPtMatrix< T > &operator+=( const SPtMatrix< T > & );
00131     // subtract/assign vector v
00132     SPtMatrix< T > &operator-=( const SPtMatrix< T > & );
00133     // multiply/assign by scalar s
00134     SPtMatrix< T > &operator*=( double );
00135     // divide/assign by scalar s
00136     SPtMatrix< T > &operator/=( double );
00137 
00138     // multiply by a matrix
00139     SPtMatrix< T > operator*( const SPtMatrix< T > & ) const;
00140 
00141 
00142 // Helper Fn Member     ---------------------------------------------
00143 private:
00144     bool CheckRanges( int, int ) const;
00145     void DeleteMemory();
00146     void CopyElements( const SPtMatrix< T > & );
00147 
00148 
00149 }; // END:  SPtMatrix
00150 //===============================================================================================
00151 
00152 
00153 //===============================================================================================
00154 //
00155 //                      M E M B E R    F U N C T I O N    D E F I N I T I O N S
00156 //
00157 //===============================================================================================
00158 // START:   SPtMatrix Member Functions  ******************************************
00159 //------------------------------------------------------------------------------------------------
00160 // Default Constructor
00161 template< typename T >
00162 SPtMatrix< T >::SPtMatrix( int r, int c ) : m_iRows( r ), m_iCols( c )
00163 {
00164     m_tElement = new T*[ m_iRows ];
00165     for ( r = 0; r < m_iRows; r++ ) {
00166         m_tElement[ r ] = new T[ m_iCols ];
00167         for ( c = 0; c < m_iCols; c++ ) {
00168             m_tElement[r][c] = T();
00169         }
00170     }
00171 }
00172 
00173 //------------------------------------------------------------------------------------------------
00174 // Copy Constructor
00175 template< typename T >
00176 SPtMatrix< T >::SPtMatrix( const SPtMatrix< T > &M )
00177 {
00178     CopyElements( M );
00179 }
00180 
00181 //------------------------------------------------------------------------------------------------
00182 // Vector3-To-Matrix Constructor
00183 template< typename T >
00184 SPtMatrix< T >::SPtMatrix( const SPtVector3< T > &V )
00185 {
00186     SPtMatrix( 3, 1 );
00187     this->m_tElement[0] = V.GetX();
00188     this->m_tElement[1] = V.GetY();
00189     this->m_tElement[2] = V.GetZ();
00190 }
00191 
00192 //------------------------------------------------------------------------------------------------
00193 // Point3-To-Matrix Constructor
00194 template< typename T >
00195 SPtMatrix< T >::SPtMatrix( const SPtPoint3< T > &P )
00196 {
00197     SPtMatrix( 3, 1 );
00198     this->m_tElement[0] = P.GetX();
00199     this->m_tElement[1] = P.GetY();
00200     this->m_tElement[2] = P.GetZ();
00201 }
00202 
00203 //------------------------------------------------------------------------------------------------
00204 // Destructor
00205 template< typename T >
00206 SPtMatrix< T >::~SPtMatrix()
00207 {
00208     DeleteMemory();
00209 }
00210 
00211 //------------------------------------------------------------------------------------------------
00212 // Useful Member Functions      -----------------------------------------------
00213 // Fn Member:   DisplayElements()  ********************************************
00214 // Desc:  Display the matrix elements
00215 template< typename T >
00216 void SPtMatrix< T >::DisplayElements() const
00217 {
00218     int r, c;
00219 
00220     cout << "A(n) " << m_iRows << " x " << m_iCols << " Matrix \n";
00221     cout.precision(10);
00222     for ( r = 0; r < m_iRows; r++ ) {
00223         cout << "| ";
00224         for ( c = 0; c < m_iCols; c++ ) {
00225             cout.width( 20 );   cout << m_tElement[r][c];
00226         }
00227         cout << " |" << endl;
00228     }
00229     cout.precision(6);
00230 } // END Fn Member: DisplayElements()
00231 
00232 //------------------------------------------------------------------------------------------------
00233 // Fn Member:   Get()       ***************************************************
00234 // Desc:  Get the element value at row r, and column c.
00235 template< typename T >
00236 T SPtMatrix< T >::Get( int r, int c ) const
00237 {
00238     if ( CheckRanges( r, c ) ) {
00239         return m_tElement[ r ][ c ];
00240     }
00241     else {
00242         return -777;
00243     }
00244 
00245 } // END Fn Member: Get()
00246 
00247 //------------------------------------------------------------------------------------------------
00248 // Fn Member:   Set()       ***************************************************
00249 // Desc:  Set the element value at row r, and column c.
00250 template< typename T >
00251 void SPtMatrix< T >::Set( int r, int c, T value )
00252 {
00253     if ( CheckRanges( r, c ) ) {
00254         m_tElement[ r ][ c ] = value;
00255     }
00256 } // END Fn Member: Set()
00257 
00258 //------------------------------------------------------------------------------------------------
00259 // Fn Member:   SetToIdentity()
00260 template< typename T >
00261 bool SPtMatrix< T >::SetToIdentity()
00262 {
00263     if ( m_iRows != m_iCols )   return false;
00264     for ( int r = 0; r < m_iRows; r++ ) {
00265         for ( int c = 0; c < m_iCols; c++ ) {
00266             this->m_tElement[r][c] = T( 0 );
00267         }
00268     }
00269     for ( int i = 0; i < m_iRows; i++ ) {
00270         this->m_tElement[i][i] = T( 1 );
00271     }
00272     return true;
00273 } // END Fn Member: SetToIdentity()
00274 
00275 //------------------------------------------------------------------------------------------------
00276 // Fn Member:   GetNoOfRows()
00277 template< typename T >
00278 int SPtMatrix< T >::GetNoOfRows() const
00279 {
00280     return m_iRows;
00281 } // END Fn Member: GetNoOfRows()
00282 
00283 //------------------------------------------------------------------------------------------------
00284 // Fn Member:   GetNoOfCols()
00285 template< typename T >
00286 int SPtMatrix< T >::GetNoOfCols() const
00287 {
00288     return m_iCols;
00289 } // END Fn Member: GetNoOfCols()
00290 
00291 //------------------------------------------------------------------------------------------------
00292 // Fn Member:   GetNoOfRowsAndCols()
00293 template< typename T >
00294 void SPtMatrix< T >::GetNoOfRowsAndCols( int &r, int &c ) const
00295 {
00296     r = m_iRows;
00297     c = m_iCols;
00298 } // END Fn Member: GetNoOfRowsAndCols()
00299 
00300 
00301 //------------------------------------------------------------------------------------------------
00302 // Matrix Operations        ---------------------------------------------------
00303 template< typename T >
00304 SPtMatrix< T > SPtMatrix< T >::GetTranspose() const
00305 {
00306     SPtMatrix< T > temp( m_iCols, m_iRows );
00307 
00308     for ( int r = 0; r < temp.m_iRows; r++ ) {
00309         for ( int c = 0; c < temp.m_iCols; c++ ) {
00310             temp.m_tElement[r][c] = this->m_tElement[c][r];
00311         }
00312     }
00313 
00314     return temp;
00315 }
00316 
00317 //------------------------------------------------------------------------------------------------
00318 template< typename T >
00319 SPtMatrix< T > &SPtMatrix< T >::Transpose()
00320 {
00321     *this = this->GetTranspose();
00322 
00323     return *this;
00324 }
00325 
00326 //------------------------------------------------------------------------------------------------
00327 // Overloaded Operators     ---------------------------------------------------
00328 
00329 // assign matrix
00330 template< typename T >
00331 SPtMatrix< T > &SPtMatrix< T >::operator=( const SPtMatrix< T > & M )
00332 {
00333     // check self assignment
00334     if ( this != &M ) {
00335         DeleteMemory();         // delete the space
00336         CopyElements( M );      // copy all elements from M matrix
00337     }
00338 
00339     return *this;
00340 }
00341 
00342 //------------------------------------------------------------------------------------------------
00343 // negation
00344 template< typename T >
00345 SPtMatrix< T > SPtMatrix< T >::operator-() const
00346 {
00347     SPtMatrix< T > temp( *this );
00348     temp *= -1.0;
00349     return temp;
00350 }
00351 
00352 //------------------------------------------------------------------------------------------------
00353 // add/assign matrix
00354 template< typename T >
00355 SPtMatrix< T > &SPtMatrix< T >::operator+=( const SPtMatrix< T > & M )
00356 {
00357     if ( m_iRows == M.m_iRows && m_iCols == M.m_iCols ) {
00358         for ( int r = 0; r < m_iRows; r++ ) {
00359             for ( int c = 0; c < m_iCols; c++ ) {
00360                 this->m_tElement[r][c] += M.m_tElement[r][c];
00361             }
00362         }
00363     }
00364 
00365     return *this;
00366 }
00367 
00368 //------------------------------------------------------------------------------------------------
00369 // subtract/assign matrix
00370 template< typename T >
00371 SPtMatrix< T > &SPtMatrix< T >::operator-=( const SPtMatrix< T > & M )
00372 {
00373     if ( m_iRows == M.m_iRows && m_iCols == M.m_iCols ) {
00374         for ( int r = 0; r < m_iRows; r++ ) {
00375             for ( int c = 0; c < m_iCols; c++ ) {
00376                 this->m_tElement[r][c] -= M.m_tElement[r][c];
00377             }
00378         }
00379     }
00380 
00381     return *this;
00382 }
00383 
00384 //------------------------------------------------------------------------------------------------
00385 // multiply/assign by scalar s
00386 template< typename T >
00387 SPtMatrix< T > &SPtMatrix< T >::operator*=( double s )
00388 {
00389     for ( int r = 0; r < m_iRows; r++ ) {
00390         for ( int c = 0; c < m_iCols; c++ ) {
00391             this->m_tElement[r][c] *= s;
00392         }
00393     }
00394 
00395     return *this;
00396 }
00397 
00398 //------------------------------------------------------------------------------------------------
00399 // divide/assign by scalar s
00400 template< typename T >
00401 SPtMatrix< T > &SPtMatrix< T >::operator/=( double s )
00402 {
00403     for ( int r = 0; r < m_iRows; r++ ) {
00404         for ( int c = 0; c < m_iCols; c++ ) {
00405             this->m_tElement[r][c] /= s;
00406         }
00407     }
00408 
00409     return *this;
00410 }
00411 
00412 //------------------------------------------------------------------------------------------------
00413 // multiply by a matrix
00414 template< typename T >
00415 SPtMatrix< T > SPtMatrix< T >::operator*( const SPtMatrix< T > &M ) const
00416 {
00417     // The rows# of the first matrix must equals the cols# of the second matrix
00418     if ( this->m_iCols == M.m_iRows ) {
00419         SPtMatrix< T > temp( this->m_iRows, M.m_iCols );
00420         if ( temp.m_iRows < temp.m_iCols ) {
00421             for ( int r = 0; r < temp.m_iRows; r++ ) {
00422                 for ( int c = 0; c < temp.m_iCols; c++ ) {
00423                     for ( int k = 0; k < M.m_iRows; k++ ) {
00424                         temp.m_tElement[r][c] += this->m_tElement[r][k] * M.m_tElement[k][c];
00425                     }
00426                     //if ( fabs(temp.m_tElement[r][c]) < 5E-20 ) temp.m_tElement[r][c] = 0;
00427                 }
00428             }
00429         }
00430         else {
00431             for ( int c = 0; c < temp.m_iCols; c++ ) {
00432                 for ( int r = 0; r < temp.m_iRows; r++ ) {
00433                     for ( int k = 0; k < M.m_iRows; k++ ) {
00434                         temp.m_tElement[r][c] += this->m_tElement[r][k] * M.m_tElement[k][c];
00435                     }
00436                     //if ( fabs(temp.m_tElement[r][c]) < 5E-20 ) temp.m_tElement[r][c] = 0;
00437                 }
00438             }
00439         }
00440 
00441         return temp;
00442     }
00443 
00444     else return NULL;
00445 }
00446 
00447 
00448 
00449 
00450 //------------------------------------------------------------------------------------------------
00451 // Helper Fn Member     -------------------------------------------------------
00452 // Check that row and column numbers are in the valid ranges.
00453 template< typename T >
00454 bool SPtMatrix< T >::CheckRanges( int r, int c ) const
00455 {
00456     assert( 0 <= r && r < m_iRows );
00457     assert( 0 <= c && c < m_iCols );
00458 
00459     return true;
00460 }
00461 
00462 //------------------------------------------------------------------------------------------------
00463 // Deallocate memory held by the matrix
00464 template< typename T >
00465 void SPtMatrix< T >::DeleteMemory()
00466 {
00467     for ( int r = 0; r < m_iRows; r++ ) {
00468         delete [] m_tElement[ r ];
00469     }
00470     delete [] m_tElement;
00471 }
00472 
00473 //------------------------------------------------------------------------------------------------
00474 // Copy all elements from M to this matrix
00475 template< typename T >
00476 void SPtMatrix< T >::CopyElements( const SPtMatrix< T > & M )
00477 {
00478     int r, c;
00479 
00480     // copy the data members from M
00481     m_iRows = M.m_iRows;
00482     m_iCols = M.m_iCols;
00483     m_tElement = new T*[ m_iRows ];
00484     for ( r = 0; r < m_iRows; r++ ) {
00485         m_tElement[ r ] = new T[ m_iCols ];
00486         for ( c = 0; c < m_iCols; c++ ) {
00487             m_tElement[ r ][ c ] = M.m_tElement[ r ][ c ];
00488         }
00489     }
00490 }
00491 // END:     SPtMatrix Member Functions  ***************************************
00492 
00493 
00494 /*
00495 //------------------------------------------------------------------------------------------------
00496 // Friend Functions for Operator Overloading        ***************************
00497 template< typename T >
00498 ostream &operator<<( ostream &output, const SPtMatrix< T > &M )
00499 {
00500     int r, c;
00501 
00502     output << "A(n) " << m_iRows << " x " << m_iCols << " Matrix \n";
00503     output.precision(10);
00504     for ( r = 0; r < m_iRows; r++ ) {
00505         output << "| ";
00506         for ( c = 0; c < m_iCols; c++ ) {
00507             output.width( 20 ); output << m_tElement[r][c];
00508         }
00509         output << " |" << endl;
00510     }
00511     output.precision(6);
00512     
00513     return output;
00514 }
00515 
00516 //------------------------------------------------------------------------------------------------
00517 template< typename T >
00518 SPtMatrix< T > operator*( double s, const SPtMatrix< T > &M )
00519 {
00520     SPtMatrix< double > temp( M );
00521     temp *= s;
00522     return temp;
00523 }
00524 
00525 //------------------------------------------------------------------------------------------------
00526 template< typename T >
00527 SPtMatrix< T > operator+( const SPtMatrix< T > &A, const SPtMatrix< T > &B )
00528 {
00529     // Both matrices have to be the same order!
00530     if ( A.m_iRows != B.m_iRows || A.m_iCols != B.m_iCols )     return NULL;
00531 
00532     SPtMatrix< T > temp( A );
00533     for ( int r = 0; r < temp.m_iRows; r++ ) {
00534         for ( int c = 0; c < temp.m_iCols; c++ ) {
00535             temp.m_tElement[r][c] += B.m_tElement[r][c];
00536         }
00537     }
00538 
00539     return temp;
00540 }
00541 
00542 //------------------------------------------------------------------------------------------------
00543 template< typename T >
00544 SPtMatrix< T > operator-( const SPtMatrix< T > &A, const SPtMatrix< T > &B )
00545 {
00546     // Both matrices have to be the same order!
00547     if ( A.m_iRows != B.m_iRows || A.m_iCols != B.m_iCols )     return NULL;
00548 
00549     SPtMatrix< T > temp( A );
00550     for ( int r = 0; r < temp.m_iRows; r++ ) {
00551         for ( int c = 0; c < temp.m_iCols; c++ ) {
00552             temp.m_tElement[r][c] -= B.m_tElement[r][c];
00553         }
00554     }
00555 
00556     return temp;
00557 }
00558 */
00559 //------------------------------------------------------------------------------------------------
00560 //===============================================================================================
00561 
00562 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines