TAPs 0.7.7.3
TAPsMatrixp.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines