00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef CMatrixTemplateNumeric_H
00029 #define CMatrixTemplateNumeric_H
00030
00031 #include <mrpt/math/CMatrixTemplate.h>
00032 #include <mrpt/system/os.h>
00033 #include <cmath>
00034 #include <limits>
00035
00036 namespace mrpt
00037 {
00038 namespace math
00039 {
00040 using namespace mrpt::system;
00041 template <class T> class CVectorTemplate;
00042
00045 enum TMatrixTextFileFormat
00046 {
00047 MATRIX_FORMAT_ENG = 0,
00048 MATRIX_FORMAT_FIXED = 1,
00049 MATRIX_FORMAT_INT = 2
00050 };
00051
00052
00108 template <class T>
00109 class MRPTDLLIMPEXP CMatrixTemplateNumeric : public CMatrixTemplate<T>
00110 {
00111 public:
00114 template <class R>
00115 CMatrixTemplateNumeric(const CMatrixTemplate<R>& m)
00116 {
00117 CMatrixTemplate<T>::realloc( m.getRowCount(), m.getColCount() );
00118
00119 for (size_t i=0; i < CMatrixTemplate<T>::getRowCount(); i++)
00120 for (size_t j=0; j < CMatrixTemplate<T>::getColCount(); j++)
00121 CMatrixTemplate<T>::m_Val[i][j] = static_cast<T> (m.get_unsafe(i,j));
00122 }
00123
00125 CMatrixTemplateNumeric(size_t row = 1, size_t col = 1);
00126
00135 template <typename V, size_t N>
00136 CMatrixTemplateNumeric(size_t row, size_t col, V (&theArray)[N] ) : CMatrixTemplate<T>( row, col, theArray )
00137 { }
00138
00141 virtual ~CMatrixTemplateNumeric()
00142 { }
00143
00146 template <class R>
00147 CMatrixTemplateNumeric<T>& operator = (const CMatrixTemplateNumeric<R>& m)
00148 {
00149 CMatrixTemplate<T>::realloc( m.getRowCount(), m.getColCount() );
00150
00151 for (size_t i=0; i < CMatrixTemplate<T>::getRowCount(); i++)
00152 for (size_t j=0; j < CMatrixTemplate<T>::getColCount(); j++)
00153 CMatrixTemplate<T>::m_Val[i][j] = static_cast<T>(m.get_unsafe(i,j));
00154 return *this;
00155 }
00156
00167 template <typename V, size_t N>
00168 CMatrixTemplateNumeric& operator = (V (&theArray)[N] )
00169 {
00170 CMatrixTemplate<T>::operator = (theArray);
00171 return *this;
00172 }
00173
00176 CMatrixTemplateNumeric<T>& operator = (const CMatrixTemplateNumeric<T>& m);
00177
00181 void setSize(size_t row, size_t col);
00182
00186 void resize(size_t row, size_t col);
00187
00188
00199 void saveToTextFile(
00200 const std::string &file,
00201 TMatrixTextFileFormat fileFormat = MATRIX_FORMAT_ENG,
00202 bool appendMRPTHeader = false,
00203 const std::string &userHeader = std::string("")
00204 ) const;
00205
00210 void loadFromTextFile(const std::string &file);
00211
00217 void laplacian( CMatrixTemplateNumeric<T> &ret ) const;
00218
00228 void svd(CMatrixTemplateNumeric<T> &U, std::vector<T> &W,CMatrixTemplateNumeric<T> &V) const;
00229
00236 void eigenVectors(CMatrixTemplateNumeric<T> &Z, CMatrixTemplateNumeric<T> &D) const;
00237
00243 CMatrixTemplateNumeric<T> largestEigenvector(
00244 T resolution = 0.01f,
00245 size_t maxIterations = 6,
00246 int *out_Iterations = NULL,
00247 float *out_estimatedResolution = NULL ) const;
00248
00252 CMatrixTemplateNumeric<T>& Sqrt();
00253
00257 CMatrixTemplateNumeric<T>& Abs();
00258
00262 CMatrixTemplateNumeric<T>& Square();
00263
00268 template <class F>
00269 CMatrixTemplateNumeric<T>& applyToAllElements( F function )
00270 {
00271 for (size_t i=0; i < CMatrixTemplate<T>::m_Rows; i++)
00272 for (size_t j=0; j < CMatrixTemplate<T>::m_Cols; j++)
00273 CMatrixTemplate<T>::m_Val[i][j] = function( CMatrixTemplate<T>::m_Val[i][j] );
00274 return *this;
00275 }
00276
00279 CMatrixTemplateNumeric<T> operator + ();
00280
00283 CMatrixTemplateNumeric<T> operator - ();
00284
00287 CMatrixTemplateNumeric<T>& operator += (const CMatrixTemplateNumeric<T>& m);
00288
00291 CMatrixTemplateNumeric<T>& addAt(const CMatrixTemplateNumeric<T>& m);
00292
00295 CMatrixTemplateNumeric<T>& addAAt(const CMatrixTemplateNumeric<T>& m);
00296
00299 CMatrixTemplateNumeric<T>& operator -= (const CMatrixTemplateNumeric<T>& m);
00300
00303 CMatrixTemplateNumeric<T>& operator *= (const T& c);
00304
00307 CMatrixTemplateNumeric<T>& operator *= (const CMatrixTemplateNumeric<T>& m);
00308
00311 void multiply(const CMatrixTemplateNumeric<T>& m1, const CMatrixTemplateNumeric<T>& m2);
00312
00315 void multiply(const CMatrixTemplateNumeric<T>& m1, const CVectorTemplate<T>& m2);
00316
00319 void multiply_ABt(const CMatrixTemplateNumeric<T>& m1, const CMatrixTemplateNumeric<T>& m2);
00320
00323 void multiply_AAt( const CMatrixTemplateNumeric<T>& m1 );
00324
00327 void multiply_AtA( const CMatrixTemplateNumeric<T>& m1 );
00328
00331 void multiply_Ab( const std::vector<T>& a, std::vector<T>& out_v );
00332
00335 void multiply_Atb( const std::vector<T>& a, std::vector<T>& out_v );
00336
00337
00340 void multiply_result_is_symmetric(const CMatrixTemplateNumeric<T>& m1, const CMatrixTemplateNumeric<T>& m2);
00341
00345 void multiplySubMatrix (
00346 const CMatrixTemplateNumeric<T> &A,
00347 CMatrixTemplateNumeric<T> &outResult,
00348 const size_t &A_cols_offset,
00349 const size_t &A_rows_offset,
00350 const size_t &A_col_count );
00351
00354 CMatrixTemplateNumeric<T>& operator /= (const CMatrixTemplateNumeric<T>& m);
00355
00358 CMatrixTemplateNumeric<T>& operator /= (const T& c);
00359
00362 CMatrixTemplateNumeric<T>& operator += (const T& c);
00363
00366 CMatrixTemplateNumeric<T>& operator -= (const T& c);
00367
00370 CMatrixTemplateNumeric<T>& operator ^= (const unsigned int& pow);
00371
00374 void scalarPow(T s);
00375
00378 void zeros(const size_t& row, const size_t& col);
00379
00382 void zeros();
00383
00386 void ones(const size_t& row, const size_t& col);
00387
00390 void ones();
00391
00394 void unit (const size_t& row);
00395
00398 void unit();
00399
00402 CMatrixTemplateNumeric<T> solve (const CMatrixTemplateNumeric<T>& v);
00403
00406 CMatrixTemplateNumeric<T> adj() const;
00407
00411 CMatrixTemplateNumeric<T> inv() const;
00412
00416 void inv_fast( CMatrixTemplateNumeric<T> &out_inv );
00417
00420 T det() const;
00421
00424 size_t rank(T eps=0.0) const;
00425
00428 T norm() const;
00429
00432 T cofact (size_t row, size_t col) const;
00433
00436 T cond();
00437
00440 bool isSingular() const;
00441
00444 bool isDiagonal() const;
00445
00448 bool isScalar() const;
00449
00452 bool isUnit() const;
00453
00456 bool isNull() const;
00457
00460 bool isSymmetric() const;
00461
00464 bool isSkewSymmetric() const;
00465
00468 bool isUpperTriangular() const;
00469
00472 bool isLowerTriangular() const;
00473
00477 void matrix_floor();
00478
00482 void matrix_floor(CMatrixTemplateNumeric<T> &out);
00483
00487 void matrix_ceil();
00488
00492 void find_index_max_value(size_t &umax, size_t &vmax, T &max_val) const;
00493
00496 T maximumDiagonal() const;
00497
00500 T maximum() const;
00501
00504 T minimum() const;
00505
00509 void find_index_min_value(size_t &umin, size_t &vmin, T &min_val) const;
00510
00514 void force_symmetry();
00515
00519 void mean( std::vector<T> &outMeanVector ) const;
00520
00524 void meanAndStd(
00525 std::vector<T> &outMeanVector,
00526 std::vector<T> &outStdVector ) const;
00527
00531 void meanAndStdAll(
00532 T &outMean,
00533 T &outStd ) const;
00534
00535 void asCol(CMatrixTemplateNumeric<T> &aux) const;
00536
00537 void asRow(CMatrixTemplateNumeric<T> &aux) const;
00538
00546 void findElementsPassingMahalanobisThreshold(
00547 double stdTimes,
00548 std::vector<size_t> &rowIndexes,
00549 std::vector<size_t> &colIndexes,
00550 bool below = false ) const;
00551
00555 inline void normalize( T minVal=0,T maxVal=1)
00556 {
00557 adjustRange(minVal,maxVal);
00558 }
00559
00562 void adjustRange( T minVal=0,T maxVal=1);
00563
00567 T sumAll() const;
00568
00573 T sum(
00574 size_t firstRow = 0,
00575 size_t firstCol = 0,
00576 size_t lastRow = std::numeric_limits<size_t>::max(),
00577 size_t lastCol = std::numeric_limits<size_t>::max() ) const;
00578
00582 void multiplyByMatrixAndByTransposeNonSymmetric(
00583 const CMatrixTemplateNumeric<T> &C,
00584 CMatrixTemplateNumeric<T> &R,
00585 bool accumOnOutput = false,
00586 bool substractInsteadOfSum = false
00587 ) const;
00588
00593 void multiplyABC(
00594 const CMatrixTemplateNumeric<T> &A,
00595 const CMatrixTemplateNumeric<T> &B,
00596 const CMatrixTemplateNumeric<T> &C);
00597
00601 void multiplyABCt(
00602 const CMatrixTemplateNumeric<T> &A,
00603 const CMatrixTemplateNumeric<T> &B,
00604 const CMatrixTemplateNumeric<T> &C);
00605
00622 void multiplyByMatrixAndByTranspose(
00623 const CMatrixTemplateNumeric<T> &C,
00624 CMatrixTemplateNumeric<T> &R,
00625 bool allowSubMatrixMultiplication = false,
00626 size_t subMatrixOffset = 0,
00627 bool accumResultInOutput = false ) const;
00628
00637 T multiplyByMatrixAndByTransposeScalar(
00638 const CMatrixTemplateNumeric<T> &C ) const;
00639
00640 private:
00642 int pivot(size_t row);
00643
00644 };
00645
00646
00649 template <class T>
00650 bool operator == (const CMatrixTemplateNumeric<T>& m1, const CMatrixTemplateNumeric<T>& m2)
00651 {
00652 if (m1.getRowCount() != m2.getRowCount() || m1.getColCount() != m2.getColCount())
00653 return false;
00654
00655 for (size_t i=0; i < m1.getRowCount(); i++)
00656 for (size_t j=0; j < m1.getColCount(); j++)
00657 if (m1(i,j) != m2(i,j))
00658 return false;
00659
00660 return true;
00661 }
00662
00665 template <class T>
00666 bool operator != (const CMatrixTemplateNumeric<T>& m1, const CMatrixTemplateNumeric<T>& m2)
00667 {
00668 return !(m1 == m2);
00669 }
00670
00673 template <class T>
00674 CMatrixTemplateNumeric<T> operator + (const CMatrixTemplateNumeric<T>& m1, const CMatrixTemplateNumeric<T>& m2)
00675 {
00676 CMatrixTemplateNumeric<T> temp(m1);
00677 temp += m2;
00678 return temp;
00679 }
00680
00683 template <class T>
00684 CMatrixTemplateNumeric<T> operator - (const CMatrixTemplateNumeric<T>& m1, const CMatrixTemplateNumeric<T>& m2)
00685 {
00686 CMatrixTemplateNumeric<T> temp(m1);
00687 temp -= m2;
00688 return temp;
00689 }
00690
00693 template <class T>
00694 CMatrixTemplateNumeric<T> operator * (const CMatrixTemplateNumeric<T>& m, const T& no)
00695 {
00696 CMatrixTemplateNumeric<T> temp(m);
00697 temp*=no;
00698 return temp;
00699 }
00700
00703 template <class T>
00704 CMatrixTemplateNumeric<T> operator * (const T& no, const CMatrixTemplateNumeric<T>& m)
00705 {
00706 CMatrixTemplateNumeric<T> temp(m);
00707 temp*=no;
00708 return temp;
00709 }
00710
00713 template <class T>
00714 CMatrixTemplateNumeric<T> operator * (const CMatrixTemplateNumeric<T>& m1, const CMatrixTemplateNumeric<T>& m2)
00715 {
00716 CMatrixTemplateNumeric<T> res(m1);
00717 res*=m2;
00718 return res;
00719 }
00720
00723 template <class T>
00724 CMatrixTemplateNumeric<T> operator * (const CMatrixTemplateNumeric<T>& m1, const CVectorTemplate<T>& m2)
00725 {
00726 CMatrixTemplateNumeric<T> res(m1.getRowCount(),1);
00727 res.multiply(m1,m2);
00728 return res;
00729 }
00730
00733 template <class T>
00734 CMatrixTemplateNumeric<T> operator / (const CMatrixTemplateNumeric<T>& m, const T& no)
00735 {
00736 return (m * (T(1) / no));
00737 }
00738
00741 template <class T>
00742 CMatrixTemplateNumeric<T> operator / (const T& no, const CMatrixTemplateNumeric<T>& m)
00743 {
00744 return (!m * no);
00745 }
00746
00749 template <class T>
00750 CMatrixTemplateNumeric<T> operator / (const CMatrixTemplateNumeric<T>& m1, const CMatrixTemplateNumeric<T>& m2)
00751 {
00752 return (m1 * !m2);
00753 }
00754
00757 template <class T>
00758 CMatrixTemplateNumeric<T> operator ^ (const CMatrixTemplateNumeric<T>& m, const unsigned int& pow)
00759 {
00760 CMatrixTemplateNumeric<T> temp(m);
00761 temp ^= pow;
00762 return temp;
00763 }
00764
00767 template <class T>
00768 CMatrixTemplateNumeric<T> operator ~ (const CMatrixTemplateNumeric<T>& m)
00769 {
00770 CMatrixTemplateNumeric<T> temp(m.getColCount(),m.getRowCount());
00771
00772 for (size_t i=0; i < m.getRowCount(); i++)
00773 for (size_t j=0; j < m.getColCount(); j++)
00774 {
00775 T x = m(i,j);
00776 temp(j,i) = x;
00777 }
00778 return temp;
00779 }
00780
00783 template <class T>
00784 CMatrixTemplateNumeric<T> operator ! (const CMatrixTemplateNumeric<T> &m)
00785 {
00786 return m.inv();
00787 }
00788
00791 #define DEBUG_SAVE_MATRIX(M) \
00792 { \
00793 char auxStr[100]; \
00794 os::sprintf(auxStr,99,"%s.txt",#M); \
00795 M.saveToTextFile(auxStr); \
00796 } \
00797
00798
00803 typedef CMatrixTemplateNumeric<float> CMatrixFloat;
00804
00809 typedef CMatrixTemplateNumeric<double> CMatrixDouble;
00810
00814 typedef CMatrixTemplateNumeric<unsigned int> CMatrixUInt;
00815
00819 typedef CMatrixTemplate<bool> CMatrixBool;
00820
00821 #ifdef HAVE_LONG_DOUBLE
00822
00825 typedef CMatrixTemplateNumeric<long double> CMatrixLongDouble;
00826 #else
00827
00830 typedef CMatrixTemplateNumeric<double> CMatrixLongDouble;
00831 #endif
00832
00833 }
00834 }
00835
00836 #endif