![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsMatrixp.cpp 00003 00004 Matrixp class is a class for any dimension Matrixp. 00005 00006 Sukitti Punak (01/19/2006) 00007 Update (12/16/2009) 00008 ******************************************************************************/ 00009 #include "TAPsMatrixp.hpp" 00010 // Using Inclusion Model (i.e. definitions are included in declarations) 00011 // (this name.cpp is included in name.hpp) 00012 // Each friend is defined directly inside its declaration. 00013 00014 BEGIN_NAMESPACE_TAPs 00015 //============================================================================= 00016 // Constructors and Destructor 00017 //----------------------------------------------------------------------------- 00018 template <typename T> 00019 Matrixp<T>::Matrixp ( int rows, int cols ) 00020 : R( rows ), C( cols ) 00021 { 00022 e = new T[R*C]; 00023 // Identity Matrix 00024 MakeIdentity(); 00025 } 00026 //----------------------------------------------------------------------------- 00027 template <typename T> 00028 Matrixp<T>::Matrixp ( Matrixp<T> const &M ) 00029 : R( M.R ), C( M.C ) 00030 { 00031 e = new T[R*C]; 00032 for ( int i = 0; i < R*C; ++i ) 00033 e[i] = M.e[i]; 00034 } 00035 //----------------------------------------------------------------------------- 00036 template <typename T> 00037 Matrixp<T>::Matrixp ( int rows, int cols, T val ) 00038 : R( rows ), C( cols ) 00039 { 00040 e = new T[R*C]; 00041 for ( int i = 0; i < R*C; ++i ) 00042 e[i] = val; 00043 } 00044 //----------------------------------------------------------------------------- 00045 template <typename T> 00046 Matrixp<T>::Matrixp ( int rows, int cols, T const a[] ) 00047 : R( rows ), C( cols ) 00048 { 00049 e = new T[R*C]; 00050 for ( int i = 0; i < R*C; ++i ) 00051 e[i] = a[i]; 00052 } 00053 //----------------------------------------------------------------------------- 00054 template <typename T> 00055 Matrixp<T>::~Matrixp () 00056 { 00057 delete [] e; 00058 } 00059 //----------------------------------------------------------------------------- 00060 //============================================================================= 00061 // Member Access 00062 //----------------------------------------------------------------------------- 00063 template <typename T> 00064 inline T & Matrixp<T>::operator[] ( int i ) 00065 { return e[i]; } 00066 //----------------------------------------------------------------------------- 00067 template <typename T> 00068 inline T const & Matrixp<T>::operator[] ( int i ) const 00069 { return e[i]; } 00070 //----------------------------------------------------------------------------- 00071 template <typename T> 00072 inline T & Matrixp<T>::operator() ( int r, int c ) 00073 { return e[r*C + c]; } 00074 //----------------------------------------------------------------------------- 00075 template <typename T> 00076 inline T const & Matrixp<T>::operator() ( int r, int c ) const 00077 { return e[r*C + c]; } 00078 //----------------------------------------------------------------------------- 00079 //============================================================================= 00080 // Convert to one dimension array 00081 //----------------------------------------------------------------------------- 00082 template <typename T> 00083 Matrixp<T>::operator const T * () const 00084 { return e; } 00085 //----------------------------------------------------------------------------- 00086 template <typename T> 00087 Matrixp<T>::operator T * () 00088 { return e; } 00089 //----------------------------------------------------------------------------- 00090 //============================================================================= 00091 // Useful Functions 00092 //----------------------------------------------------------------------------- 00093 template <typename T> 00094 std::ostream & Matrixp<T>::Display ( int precision, std::ostream &o ) const 00095 { 00096 if ( precision < 0 ) precision = 6; 00097 //-------------------------------------------------------------------- 00098 //o << typeid(*this).name() << "( "; 00099 o << "Matrixp<" << typeid(T).name() << ">" 00100 << " " << R << "-by-" << C << "\n"; 00101 o.precision( precision ); 00102 int width = precision + 10; 00103 for ( int r = 0; r < R*C; r+=C ) { 00104 o << "| "; 00105 for ( int c = 0; c < C; c++ ) { 00106 o.width( width ); o << e[r + c]; 00107 } 00108 o << " |" << endl; 00109 } 00110 o.precision( 6 ); 00111 return o; 00112 } 00113 //----------------------------------------------------------------------------- 00114 template <typename T> 00115 void Matrixp<T>::SetAllElements ( T t ) 00116 { 00117 for ( int i = 0; i < R*C; ++i ) 00118 e[i] = t; 00119 } 00120 //----------------------------------------------------------------------------- 00121 template <typename T> 00122 void Matrixp<T>::SetAllElements ( T const a[] ) 00123 { 00124 for ( int i = 0; i < R*C; ++i ) 00125 e[i] = a[i]; 00126 } 00127 //----------------------------------------------------------------------------- 00128 template <typename T> 00129 void Matrixp<T>::MakeIdentity () 00130 { 00131 // Identity Matrix 00132 for ( int r = 0; r < R*C; r+=C ) 00133 for ( int c = 0; c < C; ++c ) 00134 e[r + c] = Math<T>::ZERO; 00135 if ( R <= C ) { 00136 for ( int r = 0; r < R; ++r ) 00137 e[r*C + r] = Math<T>::ONE; 00138 } 00139 else { 00140 for ( int r = 0; r < C; ++r ) 00141 e[r*C + r] = Math<T>::ONE; 00142 } 00143 } 00144 //----------------------------------------------------------------------------- 00145 template <typename T> 00146 void Matrixp<T>::MakeDiagonal ( T d ) 00147 { 00148 // Diagonal Matrix 00149 for ( int r = 0; r < R*C; r+=C ) 00150 for ( int c = 0; c < C; ++c ) 00151 e[r + c] = Math<T>::ZERO; 00152 for ( int r = 0; r < R; ++r ) 00153 e[r*C + r] = d; 00154 } 00155 //----------------------------------------------------------------------------- 00156 template <typename T> 00157 void Matrixp<T>::MakeDiagonal ( T const a[] ) 00158 { 00159 // Diagonal Matrix 00160 for ( int r = 0; r < R*C; r+=C ) 00161 for ( int c = 0; c < C; ++c ) 00162 e[r + c] = Math<T>::ZERO; 00163 for ( int r = 0; r < R; ++r ) 00164 e[r*C + r] = a[r]; 00165 } 00166 //----------------------------------------------------------------------------- 00167 template <typename T> 00168 void Matrixp<T>::MakeZero () 00169 { 00170 for ( int i = 0; i < R*C; ++i ) 00171 e[i] = Math<T>::ZERO; 00172 } 00173 //----------------------------------------------------------------------------- 00174 template <typename T> 00175 bool Matrixp<T>::IsIdentity () const 00176 { 00177 int i; 00178 for ( int r = 0; r < R; ++r ) { 00179 for ( int c = 0; c < C; ++c ) { 00180 i = r*C; 00181 if ( r != c ) { 00182 if ( e[i + c] != Math<T>::ZERO ) { 00183 return false; 00184 } 00185 } 00186 else { 00187 if ( e[i + c] != Math<T>::ONE ) { 00188 return false; 00189 } 00190 } 00191 } 00192 } 00193 return true; 00194 } 00195 //----------------------------------------------------------------------------- 00196 template <typename T> 00197 bool Matrixp<T>::IsSymmetric () const 00198 { 00199 if ( R != C ) return false; // Not an N-by-N matrix 00200 for ( int r = 0; r < R; ++r ) 00201 for ( int c = r; c < C; ++c ) 00202 if ( e[r*C + c] != e[c*R + r] ) 00203 return false; 00204 return true; 00205 } 00206 00207 //----------------------------------------------------------------------------- 00208 template <typename T> 00209 void Matrixp<T>::ChangeSize ( int numOfRow, int numOfCol ) 00210 { 00211 delete [] e; 00212 R = numOfRow; 00213 C = numOfCol; 00214 e = new T[R*C]; 00215 for ( int i = 0; i < R*C; ++i ) 00216 e[i] = T(0); 00217 } 00218 00219 //============================================================================= 00220 // Matrix Operations 00221 //----------------------------------------------------------------------------- 00222 // Transpose this matrix 00223 template <typename T> 00224 Matrixp<T> & Matrixp<T>::Transposed () 00225 { 00226 /* 00227 T temp; int i, j; 00228 if ( R >= C ) { // If row >= col 00229 for ( int r = 0; r < R; ++r ) { 00230 for ( int c = r; c < C; ++c ) { 00231 i = r*C + c; 00232 j = c*R + r; 00233 temp = e[i]; 00234 e[i] = e[j]; 00235 e[j] = temp; 00236 } 00237 } 00238 } 00239 else { // If col > row 00240 for ( int c = 0; c < C; ++c ) { 00241 for ( int r = c; r < R; ++r ) { 00242 i = r*C + c; 00243 j = c*R + r; 00244 temp = e[i]; 00245 e[i] = e[j]; 00246 e[j] = temp; 00247 } 00248 } 00249 } 00250 //*/ 00251 00252 *this = GetTranspose(); 00253 int r = R; 00254 R = C; 00255 C = r; 00256 00257 return *this; 00258 } 00259 //----------------------------------------------------------------------------- 00260 // Get the transpose matrix of this matrix 00261 template <typename T> 00262 Matrixp<T> Matrixp<T>::GetTranspose() const 00263 { 00264 Matrixp<T> O( C, R ); 00265 int i; 00266 for ( int r = 0; r < R; ++r ) { 00267 i = r*C; 00268 for ( int c = 0; c < C; ++c ) { 00269 O[c*R + r] = e[i + c]; 00270 } 00271 } 00272 return O; 00273 } 00274 /* 00275 //----------------------------------------------------------------------------- 00276 // Inverse the matrix 00277 template <typename T> 00278 inline Matrixp<T> & Matrixp<T>::Inversed () 00279 { 00280 *this = (*this).GetInverse(); 00281 return *this; 00282 } 00283 //----------------------------------------------------------------------------- 00284 // Get the matrix inverse 00285 template <typename T> 00286 Matrixp<T> Matrixp<T>::GetInverse () const 00287 { 00288 T det = GetDeterminant(); 00289 00290 if ( -Math<T>::EPSILON < det && det < Math<T>::EPSILON ) 00291 return Matrixp( Math<T>::INFINITY ); 00292 00293 return Matrixp<T>( ( e[4]*e[8] - e[7]*e[5] ) / det, 00294 -( e[1]*e[8] - e[7]*e[2] ) / det, 00295 ( e[1]*e[5] - e[4]*e[2] ) / det, 00296 -( e[3]*e[8] - e[6]*e[5] ) / det, 00297 ( e[0]*e[8] - e[6]*e[2] ) / det, 00298 -( e[0]*e[5] - e[3]*e[2] ) / det, 00299 ( e[3]*e[7] - e[6]*e[4] ) / det, 00300 -( e[0]*e[7] - e[6]*e[1] ) / det, 00301 ( e[0]*e[4] - e[3]*e[1] ) / det ); 00302 } 00303 //----------------------------------------------------------------------------- 00304 template <typename T> 00305 inline T Matrixp<T>::GetDeterminant () const 00306 { 00307 return e[0] * ( e[4]*e[8] - e[5]*e[7] ) 00308 - e[3] * ( e[1]*e[8] - e[2]*e[7] ) 00309 + e[6] * ( e[1]*e[5] - e[2]*e[4] ); 00310 } 00311 //*/ 00312 //----------------------------------------------------------------------------- 00313 //============================================================================= 00314 // Assignment Overloaded Operator 00315 //-------------------------------------------------------------------------- 00316 // Assignment Operator 00317 template <typename T> 00318 inline Matrixp<T> & Matrixp<T>::operator= ( Matrixp<T> const &M ) 00319 { 00320 //assert( R*C == M.R*M.C ); 00321 if ( this != &M ) { 00322 delete [] e; 00323 R = M.R; 00324 C = M.C; 00325 e = new T[R*C]; 00326 for ( int i = 0; i < R*C; ++i ) 00327 e[i] = M.e[i]; 00328 } 00329 return *this; 00330 } 00331 //----------------------------------------------------------------------------- 00332 //============================================================================= 00333 // Unary Overloaded Operators 00334 //----------------------------------------------------------------------------- 00335 template <typename T> 00336 Matrixp<T> Matrixp<T>::operator- () 00337 { 00338 Matrixp<T> O( R, C ); 00339 for ( int i = 0; i < R*C; ++i ) 00340 O.e[i] = -e[i]; 00341 return O; 00342 } 00343 //============================================================================= 00344 // Assign Overloaded Operators 00345 //----------------------------------------------------------------------------- 00346 template <typename T> 00347 Matrixp<T> & Matrixp<T>::operator+= ( Matrixp<T> const &M ) 00348 { 00349 assert( R == M.R && C == M.C ); 00350 for ( int i = 0; i < R*C; ++i ) 00351 e[i] += M.e[i]; 00352 return *this; 00353 } 00354 //----------------------------------------------------------------------------- 00355 template <typename T> 00356 Matrixp<T> & Matrixp<T>::operator-= ( Matrixp<T> const &M ) 00357 { 00358 assert( R == M.R && C == M.C ); 00359 for ( int i = 0; i < R*C; ++i ) 00360 e[i] -= M.e[i]; 00361 return *this; 00362 } 00363 //----------------------------------------------------------------------------- 00364 template <typename T> 00365 Matrixp<T> & Matrixp<T>::operator*= ( Matrixp<T> const &M ) 00366 { 00367 *this = (*this) * M; 00368 return *this; 00369 } 00370 //----------------------------------------------------------------------------- 00371 template <typename T> 00372 Matrixp<T> & Matrixp<T>::operator*= ( T s ) 00373 { 00374 for ( int i = 0; i < R*C; ++i ) 00375 e[i] *= s; 00376 return *this; 00377 } 00378 //----------------------------------------------------------------------------- 00379 template <typename T> 00380 Matrixp<T> & Matrixp<T>::operator/= ( T s ) 00381 { 00382 for ( int i = 0; i < R*C; ++i ) 00383 e[i] /= s; 00384 return *this; 00385 } 00386 //----------------------------------------------------------------------------- 00387 //============================================================================= 00388 // Binary Overloaded Operators 00389 //----------------------------------------------------------------------------- 00390 template <typename T> 00391 Matrixp<T> Matrixp<T>::operator+ ( Matrixp<T> const &M ) const 00392 { 00393 assert( R == M.R && C == M.C ); 00394 Matrixp<T> O( R, C ); 00395 for ( int i = 0; i < R*C; ++i ) 00396 O.e[i] = e[i] + M.e[i]; 00397 return O; 00398 } 00399 //----------------------------------------------------------------------------- 00400 template <typename T> 00401 Matrixp<T> Matrixp<T>::operator- ( Matrixp<T> const &M ) const 00402 { 00403 assert( R == M.R && C == M.C ); 00404 Matrixp<T> O( R, C ); 00405 for ( int i = 0; i < R*C; ++i ) 00406 O.e[i] = e[i] - M.e[i]; 00407 return O; 00408 } 00409 //----------------------------------------------------------------------------- 00410 template <typename T> 00411 Matrixp<T> Matrixp<T>::operator* ( Matrixp<T> const &M ) const 00412 { 00413 assert ( C == M.R ); // cols must equals rows 00414 Matrixp<T> O( R, M.C, Math<T>::ZERO ); 00415 for ( int r = 0; r < R; ++r ) { 00416 for ( int c = 0; c < M.C; ++c ) { 00417 for ( int i = 0; i < C; ++i ) { 00418 O.e[r*M.C + c] += e[r*C + i] * M.e[i*M.C + c]; 00419 } 00420 } 00421 } 00422 return O; 00423 } 00424 //----------------------------------------------------------------------------- 00425 template <typename T> 00426 Matrixp<T> Matrixp<T>::operator* ( T s ) const 00427 { 00428 Matrixp<T> O( R, C ); 00429 for ( int i = 0; i < R*C; ++i ) 00430 O.e[i] = e[i] * s; 00431 return O; 00432 } 00433 //----------------------------------------------------------------------------- 00434 template <typename T> 00435 Matrixp<T> Matrixp<T>::operator/ ( T s ) const 00436 { 00437 Matrixp<T> O( R, C ); 00438 for ( int i = 0; i < R*C; ++i ) 00439 O.e[i] = e[i] / s; 00440 return O; 00441 } 00442 //----------------------------------------------------------------------------- 00443 template <typename T> 00444 inline void Matrixp<T>::MultLeft ( Matrixp<T> const &M ) 00445 { 00446 *this = M * (*this); 00447 } 00448 //----------------------------------------------------------------------------- 00449 template <typename T> 00450 inline void Matrixp<T>::MultRight ( Matrixp<T> const &M ) 00451 { 00452 *this *= M; 00453 } 00454 /* 00455 //----------------------------------------------------------------------------- 00456 // Matrixp * Vectorp 00457 template <typename T> 00458 Vectorp<T> Matrixp<T>::operator* ( Vectorp<T> const &V ) const 00459 { 00460 Vectorp<T> O( R ); 00461 for ( int r = 0, i = 0; r < R; ++r, i+=C ) { 00462 for ( int c = 0; c < C; ++c ) { 00463 O[r] += e[i + c] * V[c]; 00464 } 00465 } 00466 return O; 00467 } 00468 //*/ 00469 //============================================================================= 00470 // Helper Fn Members -------------------------------------------------------- 00471 //----------------------------------------------------------------------------- 00472 // Check that row and column numbers are in the valid ranges. 00473 template< typename T > 00474 bool Matrixp< T >::CheckRanges( int r, int c ) const 00475 { 00476 assert( 0 <= r && r < R ); 00477 assert( 0 <= c && c < C ); 00478 return true; 00479 } 00480 //============================================================================= 00481 END_NAMESPACE_TAPs 00482 //345678901234567890123456789012345678901234567890123456789012345678901234567890 00483 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8