![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsMatrix.hpp 00003 00004 Matrix class is a class for any dimension Matrix. 00005 00006 Sukitti Punak (01/19/2006) 00007 Update (12/16/2009) 00008 ******************************************************************************/ 00009 #ifndef TAPs_MATRIX_HPP 00010 #define TAPs_MATRIX_HPP 00011 00012 #include "TAPsMath.hpp" 00013 00014 BEGIN_NAMESPACE_TAPs 00015 //============================================================================= 00016 // class forward 00017 template <typename T, int N> class Vector; 00018 //============================================================================= 00019 template <typename T, int R, int C> // R = #rows, C = #cols, S = R*C 00020 class Matrix { 00021 //============================================================================= 00022 protected: 00023 // Data Members --------------------------------------------------------------- 00024 // Matrix Elements 00025 // -- -- 00026 // | | 00027 // | R by C | 00028 // | | 00029 // -- -- 00030 T e[R*C]; 00031 public: 00032 //------------------------------------------------------------------------- 00033 // Output Operator << 00034 friend std::ostream &operator<<( std::ostream &output, const Matrix<T,R,C> &M ) 00035 { 00036 //output << typeid(*this).name() << "( "; 00037 output << "Matrix<" << typeid(T).name() << "," << R << "," << C << ">\n"; 00038 output.precision(10); 00039 for ( int r = 0; r < R; r++ ) { 00040 output << "\t| "; 00041 for ( int c = 0; c < C; c++ ) { 00042 output.width( 20 ); output << M.e[r*C + c]; 00043 } 00044 output << " |" << endl; 00045 } 00046 output.precision(6); 00047 return output; 00048 } 00049 //------------------------------------------------------------------------- 00050 // Constructors and Destructor 00051 Matrix (); // default constructor (Identity Matrix) 00052 Matrix ( Matrix<T,R,C> const &M ); // copy constructor 00053 //Matrix ( Matrix<T,C,R> const &M ); // (transpose) copy constructor 00054 // Cannot declare another copy constructor, since the copy ctor is the same, 00055 // when R = C. 00056 Matrix ( T val ); // constructor 00057 Matrix ( T const a[] ); // constructor from array 00058 virtual ~Matrix (); // destructor 00059 //------------------------------------------------------------------------- 00060 // Member Access 00061 inline T & operator[] ( int i ); 00062 inline T const & operator[] ( int i ) const; 00063 inline T & operator() ( int r, int c ); 00064 inline T const & operator() ( int r, int c ) const; 00065 //------------------------------------------------------------------------- 00066 // Convert to one dimension array 00067 operator const T *() const; 00068 operator T *(); 00069 //------------------------------------------------------------------------- 00070 // Useful Functions 00071 int GetNumOfRows () const { return R; } 00072 int GetNumOfCols () const { return C; } 00073 void SetAllElements ( T ); // set all elements 00074 void SetAllElements ( T const a[] ); // set all elements 00075 void MakeIdentity (); // set to identity matrix 00076 void MakeDiagonal ( T d ); // set to diagonal matrix 00077 void MakeDiagonal ( T const a[] ); // set to diagonal matrix 00078 void MakeZero (); // set all elements to zero 00079 bool IsIdentity () const; // Is it an identity matrix? 00080 bool IsSymmetric () const; // Is it a symmetric matrix? 00081 bool IsSquare () const { return R==C; } // Is it a square matrix? 00082 //------------------------------------------------------------------------- 00083 // Matrix Operations 00084 //Matrix<T,C,R> & Transposed (); 00085 Matrix<T,C,R> GetTranspose () const; 00086 //Matrix<T,R,C> & Inversed (); 00087 //Matrix<T,R,C> GetInverse () const; 00088 //T GetDeterminant () const; 00089 //------------------------------------------------------------------------- 00090 // Assignment Overloaded Operator 00091 Matrix<T,R,C> & operator= ( Matrix<T,R,C> const &M ); 00092 //------------------------------------------------------------------------- 00093 // Unary Overloaded Operators 00094 Matrix<T,R,C> operator- (); // negation 00095 //------------------------------------------------------------------------- 00096 // Assign Overloaded Operators 00097 Matrix<T,R,C> &operator+= ( Matrix<T,R,C> const &M ); // += with matrix 00098 Matrix<T,R,C> &operator-= ( Matrix<T,R,C> const &M ); // -= with matrix 00099 //Matrix<T,R,C> &operator*= ( Matrix<T,C,R> const &M ); // *= with matrix 00100 Matrix<T,R,C> &operator*= ( T s ); // *= with scalar 00101 Matrix<T,R,C> &operator/= ( T s ); // /= with scalar 00102 //------------------------------------------------------------------------- 00103 // Binary Overloaded Operators 00104 Matrix<T,R,C> operator+ ( Matrix<T,R,C> const &M ) const; // matrix + matrix 00105 Matrix<T,R,C> operator- ( Matrix<T,R,C> const &M ) const; // matrix - matrix 00106 //Matrix<T,R,C> operator* ( Matrix<T,C,R> const &M ) const; // matrix * matrix 00107 Matrix<T,R,C> operator* ( T s ) const; // matrix * scalar 00108 friend inline Matrix<T,R,C> operator* ( T s, Matrix<T,R,C> const &M ) // scalar * matrix 00109 { return M * s; } 00110 Matrix<T,R,C> operator/ ( T s ) const; // matrix / scalar 00111 //inline void MultLeft ( Matrix<T,C,R> const &M ); // this matrix = matrix M * this matrix 00112 //inline void MultRight ( Matrix<T,C,R> const &M ); // this matrix = this matrix * matrix M 00113 //------------------------------------------------------------------------- 00114 // Matrix * Vector 00115 Vector<T,R> operator* ( Vector<T,C> const &V ) const; 00116 //------------------------------------------------------------------------- 00117 //*/ 00118 }; // END CLASS Matrix 00119 //============================================================================= 00120 END_NAMESPACE_TAPs 00121 //----------------------------------------------------------------------------- 00122 // Include definition if TAPs_USE_EXPORT is not defined 00123 //#if !defined( TAPs_USE_EXPORT ) 00124 #include "TAPsMatrix.cpp" 00125 //#endif 00126 //----------------------------------------------------------------------------- 00127 #endif 00128 //345678901234567890123456789012345678901234567890123456789012345678901234567890 00129 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8 00130 00131 00132 00133 00134 00135 00136 00137 00138 00139 /* 00140 00141 00142 //------------------------------------------------------------------------- 00143 // Friend Functions for Operator Overloading 00144 00145 //------------------------------------------------------------------------- 00146 // Operator Overloading 00147 Matrix<T,R,C> operator*( T s ) 00148 { 00149 Matrix<T,R,C> M( *this ); 00150 M *= s; 00151 return M; 00152 } 00153 00154 friend SPtMatrix< T > operator-( const SPtMatrix< T > &A, const SPtMatrix< T > &B ) 00155 { 00156 // Both matrices have to be the same order! 00157 if ( A.m_iRows != B.m_iRows || A.m_iCols != B.m_iCols ) return NULL; 00158 00159 SPtMatrix< T > temp( A ); 00160 for ( int r = 0; r < temp.m_iRows; r++ ) { 00161 for ( int c = 0; c < temp.m_iCols; c++ ) { 00162 temp.m_tElement[r][c] -= B.m_tElement[r][c]; 00163 } 00164 } 00165 00166 return temp; 00167 } 00168 friend SPtMatrix< T > operator+( const SPtMatrix< T > &A, const SPtMatrix< T > &B ) 00169 { 00170 // Both matrices have to be the same order! 00171 if ( A.m_iRows != B.m_iRows || A.m_iCols != B.m_iCols ) return NULL; 00172 00173 SPtMatrix< T > temp( A ); 00174 for ( int r = 0; r < temp.m_iRows; r++ ) { 00175 for ( int c = 0; c < temp.m_iCols; c++ ) { 00176 temp.m_tElement[r][c] += B.m_tElement[r][c]; 00177 } 00178 } 00179 00180 return temp; 00181 } 00182 friend class MatrixOperations; 00183 00184 // Member Functions ---------------------------------------------------------- 00185 public: 00186 // Constructors ------------------------------------------------ 00187 SPtMatrix( int = 3, int = 3 ); 00188 //SPtMatrix( T **e, int r, int c ) : m_tElement< T >( e ), m_iRows( r ), m_iCols( c ) { } 00189 SPtMatrix( const SPtMatrix< T > & ); 00190 SPtMatrix( const SPtVector3< T > & ); 00191 SPtMatrix( const SPtPoint3< T > & ); 00192 ~SPtMatrix(); 00193 00194 00195 // Useful Member Functions --------------------------------- 00196 // Display Elements 00197 void DisplayElements() const; 00198 T Get( int, int ) const; 00199 void Set( int, int, T ); 00200 bool SetToIdentity(); 00201 int GetNoOfRows() const; 00202 int GetNoOfCols() const; 00203 void GetNoOfRowsAndCols( int &, int & ) const; 00204 00205 00206 // Matrix Operations ------------------------------------- 00207 SPtMatrix< T > GetTranspose() const; 00208 SPtMatrix< T > &Transpose(); 00209 00210 00211 // Overloaded Operators ------------------------------------- 00212 // assign matrix 00213 SPtMatrix< T > &operator=( const SPtMatrix< T > & ); 00214 // negation 00215 SPtMatrix< T > operator-() const; 00216 // add/assign matrix 00217 SPtMatrix< T > &operator+=( const SPtMatrix< T > & ); 00218 // subtract/assign vector v 00219 SPtMatrix< T > &operator-=( const SPtMatrix< T > & ); 00220 // multiply/assign by scalar s 00221 SPtMatrix< T > &operator*=( double ); 00222 // divide/assign by scalar s 00223 SPtMatrix< T > &operator/=( double ); 00224 00225 // multiply by a matrix 00226 SPtMatrix< T > operator*( const SPtMatrix< T > & ) const; 00227 00228 00229 // Helper Fn Member --------------------------------------------- 00230 private: 00231 bool CheckRanges( int, int ) const; 00232 void DeleteMemory(); 00233 void CopyElements( const SPtMatrix< T > & ); 00234 00235 00236 }; // END: SPtMatrix 00237 //=============================================================================================== 00238 00239 00240 //=============================================================================================== 00241 // 00242 // 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 00243 // 00244 //=============================================================================================== 00245 // START: SPtMatrix Member Functions ****************************************** 00246 //------------------------------------------------------------------------------------------------ 00247 // Default Constructor 00248 template< typename T > 00249 SPtMatrix< T >::SPtMatrix( int r, int c ) : m_iRows( r ), m_iCols( c ) 00250 { 00251 m_tElement = new T*[ m_iRows ]; 00252 for ( r = 0; r < m_iRows; r++ ) { 00253 m_tElement[ r ] = new T[ m_iCols ]; 00254 for ( c = 0; c < m_iCols; c++ ) { 00255 m_tElement[r][c] = T(); 00256 } 00257 } 00258 } 00259 00260 //------------------------------------------------------------------------------------------------ 00261 // Copy Constructor 00262 template< typename T > 00263 SPtMatrix< T >::SPtMatrix( const SPtMatrix< T > &M ) 00264 { 00265 CopyElements( M ); 00266 } 00267 00268 //------------------------------------------------------------------------------------------------ 00269 // Vector3-To-Matrix Constructor 00270 template< typename T > 00271 SPtMatrix< T >::SPtMatrix( const SPtVector3< T > &V ) 00272 { 00273 SPtMatrix( 3, 1 ); 00274 this->m_tElement[0] = V.GetX(); 00275 this->m_tElement[1] = V.GetY(); 00276 this->m_tElement[2] = V.GetZ(); 00277 } 00278 00279 //------------------------------------------------------------------------------------------------ 00280 // Point3-To-Matrix Constructor 00281 template< typename T > 00282 SPtMatrix< T >::SPtMatrix( const SPtPoint3< T > &P ) 00283 { 00284 SPtMatrix( 3, 1 ); 00285 this->m_tElement[0] = P.GetX(); 00286 this->m_tElement[1] = P.GetY(); 00287 this->m_tElement[2] = P.GetZ(); 00288 } 00289 00290 //------------------------------------------------------------------------------------------------ 00291 // Destructor 00292 template< typename T > 00293 SPtMatrix< T >::~SPtMatrix() 00294 { 00295 DeleteMemory(); 00296 } 00297 00298 //------------------------------------------------------------------------------------------------ 00299 // Useful Member Functions ----------------------------------------------- 00300 // Fn Member: DisplayElements() ******************************************** 00301 // Desc: Display the matrix elements 00302 template< typename T > 00303 void SPtMatrix< T >::DisplayElements() const 00304 { 00305 int r, c; 00306 00307 cout << "A(n) " << m_iRows << " x " << m_iCols << " Matrix \n"; 00308 cout.precision(10); 00309 for ( r = 0; r < m_iRows; r++ ) { 00310 cout << "| "; 00311 for ( c = 0; c < m_iCols; c++ ) { 00312 cout.width( 20 ); cout << m_tElement[r][c]; 00313 } 00314 cout << " |" << endl; 00315 } 00316 cout.precision(6); 00317 } // END Fn Member: DisplayElements() 00318 00319 //------------------------------------------------------------------------------------------------ 00320 // Fn Member: Get() *************************************************** 00321 // Desc: Get the element value at row r, and column c. 00322 template< typename T > 00323 T SPtMatrix< T >::Get( int r, int c ) const 00324 { 00325 if ( CheckRanges( r, c ) ) { 00326 return m_tElement[ r ][ c ]; 00327 } 00328 else { 00329 return -777; 00330 } 00331 00332 } // END Fn Member: Get() 00333 00334 //------------------------------------------------------------------------------------------------ 00335 // Fn Member: Set() *************************************************** 00336 // Desc: Set the element value at row r, and column c. 00337 template< typename T > 00338 void SPtMatrix< T >::Set( int r, int c, T value ) 00339 { 00340 if ( CheckRanges( r, c ) ) { 00341 m_tElement[ r ][ c ] = value; 00342 } 00343 } // END Fn Member: Set() 00344 00345 //------------------------------------------------------------------------------------------------ 00346 // Fn Member: SetToIdentity() 00347 template< typename T > 00348 bool SPtMatrix< T >::SetToIdentity() 00349 { 00350 if ( m_iRows != m_iCols ) return false; 00351 for ( int r = 0; r < m_iRows; r++ ) { 00352 for ( int c = 0; c < m_iCols; c++ ) { 00353 this->m_tElement[r][c] = T( 0 ); 00354 } 00355 } 00356 for ( int i = 0; i < m_iRows; i++ ) { 00357 this->m_tElement[i][i] = T( 1 ); 00358 } 00359 return true; 00360 } // END Fn Member: SetToIdentity() 00361 00362 //------------------------------------------------------------------------------------------------ 00363 // Fn Member: GetNoOfRows() 00364 template< typename T > 00365 int SPtMatrix< T >::GetNoOfRows() const 00366 { 00367 return m_iRows; 00368 } // END Fn Member: GetNoOfRows() 00369 00370 //------------------------------------------------------------------------------------------------ 00371 // Fn Member: GetNoOfCols() 00372 template< typename T > 00373 int SPtMatrix< T >::GetNoOfCols() const 00374 { 00375 return m_iCols; 00376 } // END Fn Member: GetNoOfCols() 00377 00378 //------------------------------------------------------------------------------------------------ 00379 // Fn Member: GetNoOfRowsAndCols() 00380 template< typename T > 00381 void SPtMatrix< T >::GetNoOfRowsAndCols( int &r, int &c ) const 00382 { 00383 r = m_iRows; 00384 c = m_iCols; 00385 } // END Fn Member: GetNoOfRowsAndCols() 00386 00387 00388 //------------------------------------------------------------------------------------------------ 00389 // Matrix Operations --------------------------------------------------- 00390 template< typename T > 00391 SPtMatrix< T > SPtMatrix< T >::GetTranspose() const 00392 { 00393 SPtMatrix< T > temp( m_iCols, m_iRows ); 00394 00395 for ( int r = 0; r < temp.m_iRows; r++ ) { 00396 for ( int c = 0; c < temp.m_iCols; c++ ) { 00397 temp.m_tElement[r][c] = this->m_tElement[c][r]; 00398 } 00399 } 00400 00401 return temp; 00402 } 00403 00404 //------------------------------------------------------------------------------------------------ 00405 template< typename T > 00406 SPtMatrix< T > &SPtMatrix< T >::Transpose() 00407 { 00408 *this = this->GetTranspose(); 00409 00410 return *this; 00411 } 00412 00413 //------------------------------------------------------------------------------------------------ 00414 // Overloaded Operators --------------------------------------------------- 00415 00416 // assign matrix 00417 template< typename T > 00418 SPtMatrix< T > &SPtMatrix< T >::operator=( const SPtMatrix< T > & M ) 00419 { 00420 // check self assignment 00421 if ( this != &M ) { 00422 DeleteMemory(); // delete the space 00423 CopyElements( M ); // copy all elements from M matrix 00424 } 00425 00426 return *this; 00427 } 00428 00429 //------------------------------------------------------------------------------------------------ 00430 // negation 00431 template< typename T > 00432 SPtMatrix< T > SPtMatrix< T >::operator-() const 00433 { 00434 SPtMatrix< T > temp( *this ); 00435 temp *= -1.0; 00436 return temp; 00437 } 00438 00439 //------------------------------------------------------------------------------------------------ 00440 // add/assign matrix 00441 template< typename T > 00442 SPtMatrix< T > &SPtMatrix< T >::operator+=( const SPtMatrix< T > & M ) 00443 { 00444 if ( m_iRows == M.m_iRows && m_iCols == M.m_iCols ) { 00445 for ( int r = 0; r < m_iRows; r++ ) { 00446 for ( int c = 0; c < m_iCols; c++ ) { 00447 this->m_tElement[r][c] += M.m_tElement[r][c]; 00448 } 00449 } 00450 } 00451 00452 return *this; 00453 } 00454 00455 //------------------------------------------------------------------------------------------------ 00456 // subtract/assign matrix 00457 template< typename T > 00458 SPtMatrix< T > &SPtMatrix< T >::operator-=( const SPtMatrix< T > & M ) 00459 { 00460 if ( m_iRows == M.m_iRows && m_iCols == M.m_iCols ) { 00461 for ( int r = 0; r < m_iRows; r++ ) { 00462 for ( int c = 0; c < m_iCols; c++ ) { 00463 this->m_tElement[r][c] -= M.m_tElement[r][c]; 00464 } 00465 } 00466 } 00467 00468 return *this; 00469 } 00470 00471 //------------------------------------------------------------------------------------------------ 00472 // multiply/assign by scalar s 00473 template< typename T > 00474 SPtMatrix< T > &SPtMatrix< T >::operator*=( double s ) 00475 { 00476 for ( int r = 0; r < m_iRows; r++ ) { 00477 for ( int c = 0; c < m_iCols; c++ ) { 00478 this->m_tElement[r][c] *= s; 00479 } 00480 } 00481 00482 return *this; 00483 } 00484 00485 //------------------------------------------------------------------------------------------------ 00486 // divide/assign by scalar s 00487 template< typename T > 00488 SPtMatrix< T > &SPtMatrix< T >::operator/=( double s ) 00489 { 00490 for ( int r = 0; r < m_iRows; r++ ) { 00491 for ( int c = 0; c < m_iCols; c++ ) { 00492 this->m_tElement[r][c] /= s; 00493 } 00494 } 00495 00496 return *this; 00497 } 00498 00499 //------------------------------------------------------------------------------------------------ 00500 // multiply by a matrix 00501 template< typename T > 00502 SPtMatrix< T > SPtMatrix< T >::operator*( const SPtMatrix< T > &M ) const 00503 { 00504 // The rows# of the first matrix must equals the cols# of the second matrix 00505 if ( this->m_iCols == M.m_iRows ) { 00506 SPtMatrix< T > temp( this->m_iRows, M.m_iCols ); 00507 if ( temp.m_iRows < temp.m_iCols ) { 00508 for ( int r = 0; r < temp.m_iRows; r++ ) { 00509 for ( int c = 0; c < temp.m_iCols; c++ ) { 00510 for ( int k = 0; k < M.m_iRows; k++ ) { 00511 temp.m_tElement[r][c] += this->m_tElement[r][k] * M.m_tElement[k][c]; 00512 } 00513 //if ( fabs(temp.m_tElement[r][c]) < 5E-20 ) temp.m_tElement[r][c] = 0; 00514 } 00515 } 00516 } 00517 else { 00518 for ( int c = 0; c < temp.m_iCols; c++ ) { 00519 for ( int r = 0; r < temp.m_iRows; r++ ) { 00520 for ( int k = 0; k < M.m_iRows; k++ ) { 00521 temp.m_tElement[r][c] += this->m_tElement[r][k] * M.m_tElement[k][c]; 00522 } 00523 //if ( fabs(temp.m_tElement[r][c]) < 5E-20 ) temp.m_tElement[r][c] = 0; 00524 } 00525 } 00526 } 00527 00528 return temp; 00529 } 00530 00531 else return NULL; 00532 } 00533 00534 00535 00536 00537 //------------------------------------------------------------------------------------------------ 00538 // Helper Fn Member ------------------------------------------------------- 00539 // Check that row and column numbers are in the valid ranges. 00540 template< typename T > 00541 bool SPtMatrix< T >::CheckRanges( int r, int c ) const 00542 { 00543 assert( 0 <= r && r < m_iRows ); 00544 assert( 0 <= c && c < m_iCols ); 00545 00546 return true; 00547 } 00548 00549 //------------------------------------------------------------------------------------------------ 00550 // Deallocate memory held by the matrix 00551 template< typename T > 00552 void SPtMatrix< T >::DeleteMemory() 00553 { 00554 for ( int r = 0; r < m_iRows; r++ ) { 00555 delete [] m_tElement[ r ]; 00556 } 00557 delete [] m_tElement; 00558 } 00559 00560 //------------------------------------------------------------------------------------------------ 00561 // Copy all elements from M to this matrix 00562 template< typename T > 00563 void SPtMatrix< T >::CopyElements( const SPtMatrix< T > & M ) 00564 { 00565 int r, c; 00566 00567 // copy the data members from M 00568 m_iRows = M.m_iRows; 00569 m_iCols = M.m_iCols; 00570 m_tElement = new T*[ m_iRows ]; 00571 for ( r = 0; r < m_iRows; r++ ) { 00572 m_tElement[ r ] = new T[ m_iCols ]; 00573 for ( c = 0; c < m_iCols; c++ ) { 00574 m_tElement[ r ][ c ] = M.m_tElement[ r ][ c ]; 00575 } 00576 } 00577 } 00578 // END: SPtMatrix Member Functions *************************************** 00579 00580 00581 /* 00582 //------------------------------------------------------------------------------------------------ 00583 // Friend Functions for Operator Overloading *************************** 00584 template< typename T > 00585 ostream &operator<<( ostream &output, const SPtMatrix< T > &M ) 00586 { 00587 int r, c; 00588 00589 output << "A(n) " << m_iRows << " x " << m_iCols << " Matrix \n"; 00590 output.precision(10); 00591 for ( r = 0; r < m_iRows; r++ ) { 00592 output << "| "; 00593 for ( c = 0; c < m_iCols; c++ ) { 00594 output.width( 20 ); output << m_tElement[r][c]; 00595 } 00596 output << " |" << endl; 00597 } 00598 output.precision(6); 00599 00600 return output; 00601 } 00602 00603 //------------------------------------------------------------------------------------------------ 00604 template< typename T > 00605 SPtMatrix< T > operator*( double s, const SPtMatrix< T > &M ) 00606 { 00607 SPtMatrix< double > temp( M ); 00608 temp *= s; 00609 return temp; 00610 } 00611 00612 //------------------------------------------------------------------------------------------------ 00613 template< typename T > 00614 SPtMatrix< T > operator+( const SPtMatrix< T > &A, const SPtMatrix< T > &B ) 00615 { 00616 // Both matrices have to be the same order! 00617 if ( A.m_iRows != B.m_iRows || A.m_iCols != B.m_iCols ) return NULL; 00618 00619 SPtMatrix< T > temp( A ); 00620 for ( int r = 0; r < temp.m_iRows; r++ ) { 00621 for ( int c = 0; c < temp.m_iCols; c++ ) { 00622 temp.m_tElement[r][c] += B.m_tElement[r][c]; 00623 } 00624 } 00625 00626 return temp; 00627 } 00628 00629 //------------------------------------------------------------------------------------------------ 00630 template< typename T > 00631 SPtMatrix< T > operator-( const SPtMatrix< T > &A, const SPtMatrix< T > &B ) 00632 { 00633 // Both matrices have to be the same order! 00634 if ( A.m_iRows != B.m_iRows || A.m_iCols != B.m_iCols ) return NULL; 00635 00636 SPtMatrix< T > temp( A ); 00637 for ( int r = 0; r < temp.m_iRows; r++ ) { 00638 for ( int c = 0; c < temp.m_iCols; c++ ) { 00639 temp.m_tElement[r][c] -= B.m_tElement[r][c]; 00640 } 00641 } 00642 00643 return temp; 00644 } 00645 */