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