![]() |
TAPs 0.7.7.3
|
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