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 CMatrixTemplate_H
00029 #define CMatrixTemplate_H
00030
00031 #include <mrpt/utils/utils_defs.h>
00032 #include <mrpt/system/memory.h>
00033 #include <mrpt/system/datetime.h>
00034
00035 #include <vector>
00036 #include <set>
00037 #include <algorithm>
00038
00039
00040 namespace mrpt
00041 {
00042 namespace math
00043 {
00044
00045 template<typename T> class CMatrixTemplate;
00046
00047
00048 namespace detail {
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 template<typename T> class VicinityTraits;
00059
00060
00061
00062 template<typename T> class VicinityTraits<CMatrixTemplate<T> > {
00063 public:
00064 inline static void initialize(CMatrixTemplate<T> &mat,size_t N) {
00065 mat.setSize(N,N,true);
00066 }
00067 inline static void insertInContainer(CMatrixTemplate<T> &mat,size_t r,size_t c,const T &t) {
00068 mat.get_unsafe(r,c)=t;
00069 }
00070 };
00071
00072
00073
00074 template<typename T> class VicinityTraits<std::vector<T> > {
00075 public:
00076 inline static void initialize(std::vector<T> &vec,size_t N) {
00077 vec.reserve(N*N);
00078 }
00079 inline static void insertInContainer(std::vector<T> &vec,size_t,size_t,const T &t) {
00080 vec.push_back(t);
00081 }
00082 };
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 template<typename MatrixType,typename T,typename ReturnType,size_t D> struct getVicinity;
00094
00095
00096
00097
00098
00099
00100
00101
00102 template<typename MatrixType,typename T,typename ReturnType> struct getVicinity<MatrixType,T,ReturnType,4> {
00103 public:
00104 static ReturnType get(size_t r,size_t c,const MatrixType &mat) {
00105 mat.ASSERT_ENOUGHROOM<1>(r,c);
00106 ReturnType res;
00107 VicinityTraits<ReturnType>::initialize(res,3);
00108 VicinityTraits<ReturnType>::insertInContainer(res,0,1,mat.get_unsafe(r-1,c));
00109 VicinityTraits<ReturnType>::insertInContainer(res,1,0,mat.get_unsafe(r,c-1));
00110 VicinityTraits<ReturnType>::insertInContainer(res,1,2,mat.get_unsafe(r,c+1));
00111 VicinityTraits<ReturnType>::insertInContainer(res,2,1,mat.get_unsafe(r+1,c));
00112 return res;
00113 }
00114 };
00115
00116
00117
00118
00119
00120
00121
00122
00123 template<typename MatrixType,typename T,typename ReturnType> struct getVicinity<MatrixType,T,ReturnType,5> {
00124 public:
00125 static ReturnType get(size_t r,size_t c,const MatrixType &mat) {
00126 mat.ASSERT_ENOUGHROOM<1>(r,c);
00127 ReturnType res;
00128 VicinityTraits<ReturnType>::initialize(res,3);
00129 VicinityTraits<ReturnType>::insertInContainer(res,0,1,mat.get_unsafe(r-1,c));
00130 for (int i=-1;i<=1;++i) VicinityTraits<ReturnType>::insertInContainer(res,1,i+1,mat.get_unsafe(r,c+i));
00131 VicinityTraits<ReturnType>::insertInContainer(res,2,1,mat.get_unsafe(r+1,c));
00132 return res;
00133 }
00134 };
00135
00136
00137
00138
00139
00140
00141
00142
00143 template<typename MatrixType,typename T,typename ReturnType> struct getVicinity<MatrixType,T,ReturnType,8> {
00144 public:
00145 static ReturnType get(size_t r,size_t c,const MatrixType &mat) {
00146 mat.ASSERT_ENOUGHROOM<1>(r,c);
00147 ReturnType res;
00148 VicinityTraits<ReturnType>::initialize(res,3);
00149 for (int i=-1;i<=1;++i) for (int j=-1;j<=1;++j) if (i||j) VicinityTraits<ReturnType>::insertInContainer(res,i+1,j+1,mat.get_unsafe(r+i,c+j));
00150 return res;
00151 }
00152 };
00153
00154
00155
00156
00157
00158
00159
00160
00161 template<typename MatrixType,typename T,typename ReturnType> struct getVicinity<MatrixType,T,ReturnType,9> {
00162 public:
00163 static ReturnType get(size_t r,size_t c,const MatrixType &mat) {
00164 mat.ASSERT_ENOUGHROOM<1>(r,c);
00165 ReturnType res;
00166 VicinityTraits<ReturnType>::initialize(res,3);
00167 for (int i=-1;i<=1;++i) for (int j=-1;j<=1;++j) VicinityTraits<ReturnType>::insertInContainer(res,i+1,j+1,mat.get_unsafe(r+i,c+j));
00168 return res;
00169 }
00170 };
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 template<typename MatrixType,typename T,typename ReturnType> struct getVicinity<MatrixType,T,ReturnType,12> {
00182 public:
00183 static ReturnType get(size_t r,size_t c,const MatrixType &mat) {
00184 mat.ASSERT_ENOUGHROOM<2>(r,c);
00185 ReturnType res;
00186 VicinityTraits<ReturnType>::initialize(res,5);
00187 VicinityTraits<ReturnType>::insertInContainer(res,0,2,mat.get_unsafe(r-2,c));
00188 for (int i=-1;i<=1;++i) VicinityTraits<ReturnType>::insertInContainer(res,1,i+2,mat.get_unsafe(r-1,c+i));
00189 for (int i=-2;i<=2;++i) if (i) VicinityTraits<ReturnType>::insertInContainer(res,2,i+2,mat.get_unsafe(r,c+i));
00190 for (int i=-1;i<=1;++i) VicinityTraits<ReturnType>::insertInContainer(res,3,i+2,mat.get_unsafe(r+1,c+i));
00191 VicinityTraits<ReturnType>::insertInContainer(res,4,2,mat.get_unsafe(r+2,c));
00192 return res;
00193 }
00194 };
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 template<typename MatrixType,typename T,typename ReturnType> struct getVicinity<MatrixType,T,ReturnType,13> {
00206 public:
00207 static ReturnType get(size_t r,size_t c,const MatrixType &mat) {
00208 mat.ASSERT_ENOUGHROOM<2>(r,c);
00209 ReturnType res;
00210 VicinityTraits<ReturnType>::initialize(res,5);
00211 VicinityTraits<ReturnType>::insertInContainer(res,0,2,mat.get_unsafe(r-2,c));
00212 for (int i=-1;i<=1;++i) VicinityTraits<ReturnType>::insertInContainer(res,1,i+2,mat.get_unsafe(r-1,c+i));
00213 for (int i=-2;i<=2;++i) VicinityTraits<ReturnType>::insertInContainer(res,2,i+2,mat.get_unsafe(r,c+i));
00214 for (int i=-1;i<=1;++i) VicinityTraits<ReturnType>::insertInContainer(res,3,i+2,mat.get_unsafe(r+1,c+i));
00215 VicinityTraits<ReturnType>::insertInContainer(res,4,2,mat.get_unsafe(r+2,c));
00216 return res;
00217 }
00218 };
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 template<typename MatrixType,typename T,typename ReturnType> struct getVicinity<MatrixType,T,ReturnType,20> {
00230 public:
00231 static ReturnType get(size_t r,size_t c,const MatrixType &mat) {
00232 mat.ASSERT_ENOUGHROOM<2>(r,c);
00233 ReturnType res;
00234 VicinityTraits<ReturnType>::initialize(res,5);
00235 for (int i=-1;i<=1;++i) VicinityTraits<ReturnType>::insertInContainer(res,0,i+2,mat.get_unsafe(r-2,c+i));
00236 for (int i=-2;i<=2;++i) VicinityTraits<ReturnType>::insertInContainer(res,1,i+2,mat.get_unsafe(r-1,c+i));
00237 for (int i=-2;i<=2;++i) if (i) VicinityTraits<ReturnType>::insertInContainer(res,2,i+2,mat.get_unsafe(r,c+i));
00238 for (int i=-2;i<=2;++i) VicinityTraits<ReturnType>::insertInContainer(res,3,i+2,mat.get_unsafe(r+1,c+i));
00239 for (int i=-1;i<=1;++i) VicinityTraits<ReturnType>::insertInContainer(res,4,i+2,mat.get_unsafe(r+2,c+i));
00240 return res;
00241 }
00242 };
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 template<typename MatrixType,typename T,typename ReturnType> struct getVicinity<MatrixType,T,ReturnType,21> {
00254 public:
00255 static ReturnType get(size_t r,size_t c,const MatrixType &mat) {
00256 mat.ASSERT_ENOUGHROOM<2>(r,c);
00257 ReturnType res;
00258 VicinityTraits<ReturnType>::initialize(res,5);
00259 for (int i=-1;i<=1;++i) VicinityTraits<ReturnType>::insertInContainer(res,0,i+2,mat.get_unsafe(r-2,c+i));
00260 for (int i=-2;i<=2;++i) VicinityTraits<ReturnType>::insertInContainer(res,1,i+2,mat.get_unsafe(r-1,c+i));
00261 for (int i=-2;i<=2;++i) VicinityTraits<ReturnType>::insertInContainer(res,2,i+2,mat.get_unsafe(r,c+i));
00262 for (int i=-2;i<=2;++i) VicinityTraits<ReturnType>::insertInContainer(res,3,i+2,mat.get_unsafe(r+1,c+i));
00263 for (int i=-1;i<=1;++i) VicinityTraits<ReturnType>::insertInContainer(res,4,i+2,mat.get_unsafe(r+2,c+i));
00264 return res;
00265 }
00266 };
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 template<typename MatrixType,typename T,typename ReturnType> struct getVicinity<MatrixType,T,ReturnType,24> {
00278 public:
00279 static ReturnType get(size_t r,size_t c,const MatrixType &mat) {
00280 mat.ASSERT_ENOUGHROOM<2>(r,c);
00281 ReturnType res;
00282 VicinityTraits<ReturnType>::initialize(res,5);
00283 for (int i=-2;i<=2;++i) for (int j=-2;j<=2;++j) if (i||j) VicinityTraits<ReturnType>::insertInContainer(res,i+2,j+2,mat.get_unsafe(r+i,c+j));
00284 return res;
00285 }
00286 };
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 template<typename MatrixType,typename T,typename ReturnType> struct getVicinity<MatrixType,T,ReturnType,25> {
00298 public:
00299 static ReturnType get(size_t r,size_t c,const MatrixType &mat) {
00300 mat.ASSERT_ENOUGHROOM<2>(r,c);
00301 ReturnType res;
00302 VicinityTraits<ReturnType>::initialize(res,5);
00303 for (int i=-2;i<=2;++i) for (int j=-2;j<=2;++j) VicinityTraits<ReturnType>::insertInContainer(res,i+2,j+2,mat.get_unsafe(r+i,c+j));
00304 return res;
00305 }
00306 };
00307 }
00308
00309 template <typename U> U myStaticCast(double val) { return static_cast<U>(val); }
00310 template <> bool myStaticCast(double val);
00311
00312
00313
00314 enum TMatrixTextFileFormat
00315 {
00316 MATRIX_FORMAT_ENG = 0,
00317 MATRIX_FORMAT_FIXED = 1,
00318 MATRIX_FORMAT_INT = 2
00319 };
00320
00321
00322 template <class T> class CMatrixTemplate;
00323 template <typename T,size_t NROWS,size_t NCOLS> class CMatrixFixedNumeric;
00324 template <class MAT> void saveMatrixToTextFile(const MAT &theMatrix, const std::string &file, TMatrixTextFileFormat fileFormat = MATRIX_FORMAT_ENG, bool appendMRPTHeader = false, const std::string &userHeader = std::string("") );
00325 template <typename T,size_t NROWS,size_t NCOLS> void insertMatrixFixTransposeIntoDyn(CMatrixTemplate<T> &M,const size_t nRow,const size_t nCol,const CMatrixFixedNumeric<T,NROWS,NCOLS> &in);
00326 template <typename T,size_t NROWS,size_t NCOLS> void insertMatrixFixIntoDyn(CMatrixTemplate<T> &M,const size_t nRow,const size_t nCol,const CMatrixFixedNumeric<T,NROWS,NCOLS> &in);
00327 template <typename T,size_t NROWS,size_t NCOLS> void extractFixMatrixFromDynMatrix(const CMatrixTemplate<T> &M,const size_t nRow,const size_t nCol, CMatrixFixedNumeric<T,NROWS,NCOLS> &outMat);
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 template <class T>
00344 class CMatrixTemplate
00345 {
00346 public:
00347 typedef T value_type;
00348
00349 protected:
00350 T **m_Val;
00351 size_t m_Rows, m_Cols;
00352
00353
00354
00355 void realloc(size_t row, size_t col, bool newElementsToZero = false)
00356 {
00357 if (row!=m_Rows || col!=m_Cols || m_Val==NULL)
00358 {
00359 size_t r;
00360 bool doZeroColumns = newElementsToZero && (col>m_Cols);
00361 size_t sizeZeroColumns = sizeof(T)*(col-m_Cols);
00362
00363
00364 for (r=row;r<m_Rows;r++)
00365 mrpt::system::os::aligned_free( m_Val[r] );
00366
00367
00368 if (!row)
00369 { mrpt::system::os::aligned_free(m_Val); m_Val=NULL; }
00370 else m_Val = static_cast<T**> (mrpt::system::os::aligned_realloc(m_Val, sizeof(T*) * row, 16 ) );
00371
00372
00373 size_t row_size = col * sizeof(T);
00374
00375
00376 for (r=0;r<row;r++)
00377 {
00378 if (r<m_Rows)
00379 {
00380
00381 m_Val[r] = static_cast<T*> (mrpt::system::os::aligned_realloc( m_Val[r], row_size, 16));
00382
00383 if (doZeroColumns)
00384 {
00385
00386 ::memset(&m_Val[r][m_Cols],0,sizeZeroColumns);
00387 }
00388 }
00389 else
00390 {
00391
00392 m_Val[r] = static_cast<T*> ( mrpt::system::os::aligned_calloc( row_size, 16 ));
00393 }
00394 }
00395
00396
00397 m_Rows = row;
00398 m_Cols = col;
00399 }
00400 }
00401
00402
00403 public:
00404
00405
00406
00407 template<size_t N> inline void ASSERT_ENOUGHROOM(size_t r,size_t c) const {
00408 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00409 ASSERT_((r>=N)&&(r<getRowCount()-N)&&(c>=N)&&(c<getColCount()-N));
00410 #endif
00411 }
00412
00413
00414
00415
00416 void extractCol(size_t nCol, std::vector<T> &out, int startingRow = 0) const
00417 {
00418 size_t i,n;
00419 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00420 if (nCol>=m_Cols)
00421 THROW_EXCEPTION("extractCol: Column index out of bounds");
00422 #endif
00423
00424 n = m_Rows - startingRow;
00425 out.resize( n );
00426
00427 for (i=0;i<n;i++)
00428 out[i] = m_Val[i+startingRow][nCol];
00429 }
00430
00431
00432
00433
00434 void extractCol(size_t nCol, CMatrixTemplate<T> &out, int startingRow = 0) const
00435 {
00436 size_t i,n;
00437 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00438 if (nCol>=m_Cols)
00439 THROW_EXCEPTION("extractCol: Column index out of bounds");
00440 #endif
00441
00442 n = m_Rows - startingRow;
00443 out.setSize(n,1);
00444
00445 for (i=0;i<n;i++)
00446 out(i,0) = m_Val[i+startingRow][nCol];
00447 }
00448
00449
00450
00451
00452 void swapCols(size_t nCol1, size_t nCol2)
00453 {
00454 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00455 if (nCol1>=m_Cols || nCol2>=m_Cols)
00456 THROW_EXCEPTION("swapCols: Column index out of bounds");
00457 #endif
00458 const size_t n = m_Rows;
00459 for (size_t i=0;i<n;i++)
00460 std::swap( m_Val[i][nCol1], m_Val[i][nCol2] );
00461 }
00462
00463
00464
00465
00466 void swapRows(size_t nRow1, size_t nRow2)
00467 {
00468 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00469 if (nRow1>=m_Rows || nRow2>=m_Rows)
00470 THROW_EXCEPTION("swapCols: Row index out of bounds");
00471 #endif
00472 const size_t n = m_Cols;
00473 for (size_t i=0;i<n;i++)
00474 std::swap( m_Val[nRow1][i], m_Val[nRow2][i] );
00475 }
00476
00477
00478
00479
00480 template <class F>
00481 void extractRow(size_t nRow, std::vector<F> &out, size_t startingCol = 0) const
00482 {
00483 size_t i,n;
00484 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00485 if (nRow>=m_Rows)
00486 THROW_EXCEPTION("extractRow: Row index out of bounds");
00487 #endif
00488 n = m_Cols - startingCol ;
00489 out.resize( n );
00490
00491 for (i=0;i<n;i++)
00492 out[i] = static_cast<F> ( m_Val[nRow][i+startingCol] );
00493 }
00494
00495
00496
00497
00498 template <class F>
00499 void extractRow(size_t nRow, CMatrixTemplate<F> &out, size_t startingCol = 0) const
00500 {
00501 size_t i,n;
00502 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00503 if (nRow>=m_Rows)
00504 THROW_EXCEPTION("extractRow: Row index out of bounds");
00505 #endif
00506 n = m_Cols - startingCol ;
00507 out.setSize(1,n);
00508
00509 for (i=0;i<n;i++)
00510 out(0,i) = static_cast<F>( m_Val[nRow][i+startingCol] );
00511 }
00512
00513
00514
00515 CMatrixTemplate (const CMatrixTemplate& m) : m_Val(NULL),m_Rows(0),m_Cols(0)
00516 {
00517 (*this) = m;
00518 }
00519
00520 CMatrixTemplate (size_t row = 3, size_t col = 3) : m_Val(NULL),m_Rows(0),m_Cols(0)
00521 {
00522 realloc(row,col);
00523 }
00524
00525
00526
00527 CMatrixTemplate (const CMatrixTemplate& m, const size_t cropRowCount, const size_t cropColCount) : m_Val(NULL),m_Rows(0),m_Cols(0)
00528 {
00529 ASSERT_(m.m_Rows>=cropRowCount)
00530 ASSERT_(m.m_Cols>=cropColCount)
00531
00532 realloc( cropRowCount, cropColCount );
00533
00534 for (size_t i=0; i < m_Rows; i++)
00535 for (size_t j=0; j < m_Cols; j++)
00536 m_Val[i][j] = m.m_Val[i][j];
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 template <typename V, size_t N>
00548 CMatrixTemplate (size_t row, size_t col, V (&theArray)[N] ) : m_Val(NULL),m_Rows(0),m_Cols(0)
00549 {
00550 MRPT_COMPILE_TIME_ASSERT(N!=0)
00551 realloc(row,col);
00552 if (m_Rows*m_Cols != N) THROW_EXCEPTION(format("Mismatch between matrix size %lu x %lu and array of length %lu",static_cast<long unsigned>(m_Rows),static_cast<long unsigned>(m_Cols),static_cast<long unsigned>(N)))
00553 size_t idx=0;
00554 for (size_t i=0; i < m_Rows; i++)
00555 for (size_t j=0; j < m_Cols; j++)
00556 m_Val[i][j] = static_cast<T>(theArray[idx++]);
00557
00558 }
00559
00560
00561
00562 template <typename V>
00563 CMatrixTemplate(size_t row, size_t col, const V &theVector ) : m_Val(NULL),m_Rows(0),m_Cols(0)
00564 {
00565 const size_t N = theVector.size();
00566 realloc(row,col);
00567 if (m_Rows*m_Cols != N) THROW_EXCEPTION(format("Mismatch between matrix size %lu x %lu and array of length %lu",static_cast<long unsigned>(m_Rows),static_cast<long unsigned>(m_Cols),static_cast<long unsigned>(N)))
00568
00569 typename V::const_iterator it = theVector.begin();
00570 for (size_t i=0; i < m_Rows; i++)
00571 for (size_t j=0; j < m_Cols; j++)
00572 m_Val[i][j] = static_cast<T>( *(it++) );
00573
00574 }
00575
00576
00577
00578 virtual ~CMatrixTemplate()
00579 {
00580 realloc(0,0);
00581 }
00582
00583
00584
00585 CMatrixTemplate& operator = (const CMatrixTemplate& m)
00586 {
00587 realloc( m.m_Rows, m.m_Cols );
00588
00589 for (size_t i=0; i < m_Rows; i++)
00590 for (size_t j=0; j < m_Cols; j++)
00591 m_Val[i][j] = m.m_Val[i][j];
00592
00593 return *this;
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606 template <typename V, size_t N>
00607 CMatrixTemplate& operator = (V (&theArray)[N] )
00608 {
00609 MRPT_COMPILE_TIME_ASSERT(N!=0)
00610
00611 if (m_Rows*m_Cols != N)
00612 {
00613 THROW_EXCEPTION(format("Mismatch between matrix size %lu x %lu and array of length %lu",m_Rows,m_Cols,N))
00614 }
00615 size_t idx=0;
00616 for (size_t i=0; i < m_Rows; i++)
00617 for (size_t j=0; j < m_Cols; j++)
00618 m_Val[i][j] = static_cast<T>(theArray[idx++]);
00619
00620 return *this;
00621 }
00622
00623
00624
00625
00626
00627 inline size_t getRowCount() const
00628 {
00629 return m_Rows;
00630 }
00631
00632
00633
00634
00635 inline size_t getColCount() const
00636 {
00637 return m_Cols;
00638 }
00639
00640
00641
00642 void setSize(size_t row, size_t col,bool zeroNewElements=false)
00643 {
00644 realloc(row,col,zeroNewElements);
00645 }
00646
00647
00648
00649 inline bool IsSquare () const
00650 {
00651 return ( m_Rows == m_Cols );
00652 }
00653
00654
00655
00656 inline T& operator () (size_t row, size_t col)
00657 {
00658 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00659 if (row >= m_Rows || col >= m_Cols)
00660 THROW_EXCEPTION( format("Indexes (%lu,%lu) out of range. Matrix is %lux%lu",static_cast<unsigned long>(row),static_cast<unsigned long>(col),static_cast<unsigned long>(m_Rows),static_cast<unsigned long>(m_Cols)) );
00661 #endif
00662 return m_Val[row][col];
00663 }
00664
00665
00666
00667 inline const T &operator () (size_t row, size_t col) const
00668 {
00669 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00670 if (row >= m_Rows || col >= m_Cols)
00671 THROW_EXCEPTION( format("Indexes (%lu,%lu) out of range. Matrix is %lux%lu",static_cast<unsigned long>(row),static_cast<unsigned long>(col),static_cast<unsigned long>(m_Rows),static_cast<unsigned long>(m_Cols)) );
00672 #endif
00673 return m_Val[row][col];
00674 }
00675
00676
00677
00678
00679 inline T& operator () (size_t ith)
00680 {
00681 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00682 ASSERT_(m_Rows==1 || m_Cols==1);
00683 #endif
00684 if (m_Rows==1)
00685 {
00686
00687 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00688 if (ith >= m_Cols)
00689 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00690 #endif
00691 return m_Val[0][ith];
00692 }
00693 else
00694 {
00695
00696 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00697 if (ith >= m_Rows)
00698 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00699 #endif
00700 return m_Val[ith][0];
00701 }
00702 }
00703
00704
00705
00706
00707 inline T operator () (size_t ith) const
00708 {
00709 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00710 ASSERT_(m_Rows==1 || m_Cols==1);
00711 #endif
00712 if (m_Rows==1)
00713 {
00714
00715 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00716 if (ith >= m_Cols)
00717 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00718 #endif
00719 return m_Val[0][ith];
00720 }
00721 else
00722 {
00723
00724 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00725 if (ith >= m_Rows)
00726 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00727 #endif
00728 return m_Val[ith][0];
00729 }
00730 }
00731
00732
00733
00734 inline void set_unsafe(size_t row, size_t col,const T &v)
00735 {
00736 #ifdef _DEBUG
00737 if (row >= m_Rows || col >= m_Cols)
00738 THROW_EXCEPTION( format("Indexes (%lu,%lu) out of range. Matrix is %lux%lu",static_cast<unsigned long>(row),static_cast<unsigned long>(col),static_cast<unsigned long>(m_Rows),static_cast<unsigned long>(m_Cols)) );
00739 #endif
00740 m_Val[row][col] = v;
00741 }
00742
00743
00744
00745 inline T get_unsafe(size_t row, size_t col) const
00746 {
00747 #ifdef _DEBUG
00748 if (row >= m_Rows || col >= m_Cols)
00749 THROW_EXCEPTION( format("Indexes (%lu,%lu) out of range. Matrix is %lux%lu",static_cast<unsigned long>(row),static_cast<unsigned long>(col),static_cast<unsigned long>(m_Rows),static_cast<unsigned long>(m_Cols)) );
00750 #endif
00751 return m_Val[row][col];
00752 }
00753
00754
00755
00756 inline T &get_unsafe(size_t row,size_t col)
00757 {
00758 #ifdef _DEBUG
00759 if (row >= m_Rows || col >= m_Cols)
00760 THROW_EXCEPTION( format("Indexes (%lu,%lu) out of range. Matrix is %lux%lu",static_cast<unsigned long>(row),static_cast<unsigned long>(col),static_cast<unsigned long>(m_Rows),static_cast<unsigned long>(m_Cols)) );
00761 #endif
00762 return m_Val[row][col];
00763 }
00764
00765
00766
00767 inline T* get_unsafe_row(size_t row)
00768 {
00769 #ifdef _DEBUG
00770 if (row >= m_Rows)
00771 THROW_EXCEPTION( format("Row index %u out of range. Matrix is %ux%u",static_cast<unsigned long>(row),static_cast<unsigned long>(m_Rows),static_cast<unsigned long>(m_Cols)) );
00772 #endif
00773 return m_Val[row];
00774 }
00775
00776
00777
00778 inline const T* get_unsafe_row(size_t row) const {
00779 return m_Val[row];
00780 }
00781
00782
00783
00784
00785
00786
00787 inline void extractRows(size_t firstRow,size_t lastRow,CMatrixTemplate<T> &out) const {
00788 extractMatrix(firstRow,0,lastRow-firstRow+1,m_Cols,out);
00789 }
00790
00791
00792
00793
00794
00795
00796 inline void extractColumns(size_t firstCol,size_t lastCol,CMatrixTemplate<T> &out) const {
00797 extractMatrix(0,firstCol,m_Rows,lastCol-firstCol+1,out);
00798 }
00799
00800
00801
00802
00803
00804 void insertRow(size_t nRow, const std::vector<T> &in)
00805 {
00806 if (nRow>=m_Rows) THROW_EXCEPTION("insertRow: Row index out of bounds");
00807
00808 size_t n = in.size();
00809 ASSERT_(m_Cols>=in.size());
00810
00811 for (size_t i=0;i<n;i++)
00812 m_Val[nRow][i] = in[i];
00813 }
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828 void appendRow(const std::vector<T> &in)
00829 {
00830 size_t i,n, row;
00831
00832 n = m_Cols;
00833 row = m_Rows;
00834
00835 if (m_Cols==0 || m_Rows==0)
00836 {
00837 ASSERT_(!in.empty());
00838 n=m_Cols=in.size();
00839 }
00840 else
00841 {
00842 ASSERT_(in.size()==m_Cols);
00843 }
00844
00845 realloc( row+1,n );
00846
00847 for (i=0;i<n;i++)
00848 m_Val[row][i] = in[i];
00849 }
00850
00851
00852
00853
00854
00855
00856
00857 void appendCol(const std::vector<T> &in) {
00858 size_t r=m_Rows,c=m_Cols;
00859 if (m_Cols==0||m_Rows==0) {
00860 ASSERT_(!in.empty());
00861 r=in.size();
00862 c=0;
00863 } else ASSERT_(in.size()==m_Rows);
00864 realloc(r,c+1);
00865 for (size_t i=0;i<m_Rows;i++) m_Val[i][m_Cols-1]=in[i];
00866 }
00867
00868
00869
00870
00871
00872 void insertCol(size_t nCol, const std::vector<T> &in)
00873 {
00874 if (nCol>=m_Cols) THROW_EXCEPTION("insertCol: Row index out of bounds");
00875
00876 size_t n = in.size();
00877 ASSERT_( m_Rows >= in.size() );
00878
00879 for (size_t i=0;i<n;i++)
00880 m_Val[i][nCol] = in[i];
00881 }
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891 template <class MAT_R>
00892 void insertMatrix(const size_t nRow,const size_t nCol, const MAT_R &in)
00893 {
00894 const size_t nrows = in.getRowCount();
00895 const size_t ncols = in.getColCount();
00896 if ( (nRow+nrows > m_Rows) || (nCol+ncols >m_Cols) )
00897 THROW_EXCEPTION("insertMatrix: Row or Col index out of bounds");
00898 for (size_t i=nRow;i<nRow+nrows;i++)
00899 for(size_t j=nCol;j<nCol+ncols;j++)
00900 set_unsafe(i,j, static_cast<typename MAT_R::value_type> (in.get_unsafe(i-nRow,j-nCol) ) );
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911 template <class MAT_R>
00912 void insertMatrixTranspose(const size_t nRow,const size_t nCol, const MAT_R &in)
00913 {
00914 const size_t ncols = in.getRowCount();
00915 const size_t nrows = in.getColCount();
00916 if ( (nRow+nrows > m_Rows) || (nCol+ncols >m_Cols) )
00917 THROW_EXCEPTION("insertMatrix: Row or Col index out of bounds");
00918 for (size_t i=nRow;i<nRow+nrows;i++)
00919 for(size_t j=nCol;j<nCol+ncols;j++)
00920 set_unsafe(i,j, static_cast<typename MAT_R::value_type> ( in.get_unsafe(j-nCol,i-nRow) ) );
00921 }
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 template <size_t NROWS,size_t NCOLS>
00932 void insertMatrix(const size_t nRow, const size_t nCol, const CMatrixFixedNumeric<T,NROWS,NCOLS> &in) {
00933 mrpt::math::insertMatrixFixIntoDyn(*this,nRow,nCol,in);
00934 }
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944 template <size_t NROWS,size_t NCOLS>
00945 void insertMatrixTranspose(const size_t nRow,const size_t nCol, const CMatrixFixedNumeric<T,NROWS,NCOLS> &in) {
00946 mrpt::math::insertMatrixFixTransposeIntoDyn(*this,nRow,nCol,in);
00947 }
00948
00949
00950
00951
00952
00953
00954
00955 void insertMatrix(size_t nRow, size_t nCol, const std::vector<T> &in)
00956 {
00957 size_t j,ncols;
00958
00959 ncols = in.size();
00960 if ( (nRow+1 > m_Rows) || (nCol+ncols >m_Cols) )
00961 THROW_EXCEPTION("insertMatrix: Row or Col index out of bounds");
00962
00963 for(j = nCol ; j < nCol + ncols ; j++)
00964 set_unsafe(nRow,j, in[j-nCol] );
00965 }
00966
00967
00968
00969
00970
00971 void joinMatrix(const CMatrixTemplate<T> &left_up, const CMatrixTemplate<T> &right_up,
00972 const CMatrixTemplate<T> &left_down, const CMatrixTemplate<T> &right_down)
00973 {
00974 if ((left_up.getRowCount()!= right_up.getRowCount())||(left_up.getColCount()!=left_down.getColCount())||
00975 (left_down.getRowCount()!=right_down.getRowCount())||(right_up.getColCount()!=right_down.getColCount()))
00976 THROW_EXCEPTION("join_Matrix: Row or Col index out of bounds");
00977 setSize(left_up.getRowCount()+left_down.getRowCount(),left_up.getColCount()+right_up.getColCount());
00978 insertMatrix(0,0,left_up);
00979 insertMatrix(0,left_up.getColCount(),right_up);
00980 insertMatrix(left_up.getRowCount(),0,left_down);
00981 insertMatrix(left_up.getRowCount(),left_up.getColCount(),right_down);
00982 }
00983
00984
00985
00986 void fill( const T &val)
00987 {
00988 for (size_t r=0;r<m_Rows;r++)
00989 for (size_t c=0;c<m_Cols;c++)
00990 m_Val[r][c]= val;
00991 }
00992
00993
00994
00995
00996 void extractSubmatrix(const size_t row1,const size_t row2,const size_t col1,const size_t col2,CMatrixTemplate<T> &out) const {
00997 size_t nrows=row2-row1+1;
00998 size_t ncols=col2-col1+1;
00999 if (nrows<=0||ncols<=0) {
01000 out.realloc(0,0);
01001 return;
01002 }
01003 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
01004 if (row1<0||row2>=m_Rows||col1<0||col2>=m_Cols) THROW_EXCEPTION("Indices out of range!");
01005 #endif
01006 out.realloc(nrows,ncols);
01007 for (size_t i=0;i<nrows;i++) for (size_t j=0;j<ncols;j++) out.m_Val[i][j]=m_Val[i+row1][j+col1];
01008 }
01009
01010
01011
01012 inline CMatrixTemplate<T> operator() (const size_t row1,const size_t row2,const size_t col1,const size_t col2) const {
01013 CMatrixTemplate<T> val(0,0);
01014 extractSubmatrix(row1,row2,col1,col2,val);
01015 return val;
01016 }
01017
01018
01019
01020
01021
01022 void extractSubmatrixSymmetricalBlocks(
01023 const size_t block_size,
01024 const vector_size_t &block_indices,
01025 CMatrixTemplate<T> &out) const
01026 {
01027 ASSERT_(block_size>=1);
01028 ASSERT_(m_Cols==m_Rows);
01029
01030 const size_t N = block_indices.size();
01031 size_t nrows_out=N*block_size;
01032 out.realloc(nrows_out,nrows_out);
01033 if (!N) return;
01034
01035 for (size_t dst_row_blk=0;dst_row_blk<N; ++dst_row_blk )
01036 {
01037 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
01038 if (block_indices[dst_row_blk]*block_size + block_size-1>=m_Cols) THROW_EXCEPTION("Indices out of range!");
01039 #endif
01040
01041 for (size_t r=0;r<block_size;r++)
01042 {
01043 const T* src_row = this->m_Val[ block_indices[dst_row_blk] * block_size + r ];
01044 T* dst = &out.m_Val[ block_size*dst_row_blk + r ][0];
01045 for (size_t dst_col_blk=0;dst_col_blk<N; ++dst_col_blk )
01046 {
01047 const T* src = src_row + block_indices[dst_col_blk] * block_size;
01048 for (size_t c=0;c<block_size;c++)
01049 *dst++ = *src++;
01050 }
01051 }
01052 }
01053 }
01054
01055
01056
01057
01058
01059 void extractSubmatrixSymmetrical(
01060 const vector_size_t &indices,
01061 CMatrixTemplate<T> &out) const
01062 {
01063 ASSERT_(m_Cols==m_Rows);
01064
01065 const size_t N = indices.size();
01066 const size_t nrows_out=N;
01067 out.realloc(nrows_out,nrows_out);
01068 if (!N) return;
01069
01070 for (size_t dst_row_blk=0;dst_row_blk<N; ++dst_row_blk )
01071 {
01072 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
01073 if (indices[dst_row_blk]>=m_Cols) THROW_EXCEPTION("Indices out of range!");
01074 #endif
01075 const T* src_row = this->m_Val[ indices[dst_row_blk] ];
01076 T* dst = &out.m_Val[ dst_row_blk ][0];
01077 for (size_t dst_col_blk=0;dst_col_blk<N; ++dst_col_blk )
01078 {
01079 const T* src = src_row + indices[dst_col_blk];
01080 *dst++ = *src++;
01081 }
01082 }
01083 }
01084
01085
01086
01087
01088 void exchangeColumns(size_t col1,size_t col2) {
01089 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
01090 if (col1<0||col2<0||col1>=m_Cols||col2>=m_Cols) THROW_EXCEPTION("Indices out of range!");
01091 #endif
01092 T tmp;
01093 for (size_t i=0;i<m_Rows;i++) {
01094 tmp=m_Val[i][col1];
01095 m_Val[i][col1]=m_Val[i][col2];
01096 m_Val[i][col2]=tmp;
01097 }
01098 }
01099
01100
01101
01102 void exchangeRows(size_t row1,size_t row2) {
01103 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
01104 if (row1<0||row2<0||row1>=m_Rows||row2>=m_Rows) THROW_EXCEPTION("Indices out of range!");
01105 #endif
01106 T tmp;
01107 for (size_t i=0;i<m_Cols;i++) {
01108 tmp=m_Val[row1][i];
01109 m_Val[row1][i]=m_Val[row2][i];
01110 m_Val[row2][i]=tmp;
01111 }
01112 }
01113
01114
01115
01116 void deleteRow(size_t row) {
01117 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
01118 if (row<0||row>=m_Rows) THROW_EXCEPTION("Index out of range!");
01119 #endif
01120 for (size_t i=row;i<m_Rows-1;i++) for (size_t j=0;j<m_Cols;j++) m_Val[i][j]=m_Val[i+1][j];
01121 realloc(m_Rows-1,m_Cols);
01122 }
01123
01124
01125
01126 void deleteColumn(size_t col) {
01127 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
01128 if (col<0||col>=m_Cols) THROW_EXCEPTION("Index out of range!");
01129 #endif
01130 for (size_t i=0;i<m_Rows;i++) for (size_t j=col;j<m_Cols-1;j++) m_Val[i][j]=m_Val[i][j+1];
01131 realloc(m_Rows,m_Cols-1);
01132 }
01133
01134
01135
01136
01137
01138
01139 template <class R>
01140 void extractMatrix(size_t nRow, size_t nCol, CMatrixTemplate<R> &in) const
01141 {
01142 size_t i,j,ncols,nrows;
01143
01144 nrows = in.getRowCount();
01145 ncols = in.getColCount();
01146 if ( (nRow+nrows > CMatrixTemplate<T>::getRowCount()) || (nCol+ncols >CMatrixTemplate<T>::getColCount()) )
01147 THROW_EXCEPTION("extractMatrix: Row or Col index out of bounds");
01148
01149 for (i=nRow;i<nRow+nrows;i++)
01150 for(j=nCol;j<nCol+ncols;j++)
01151 in.set_unsafe( i-nRow,j-nCol, static_cast<R> ( CMatrixTemplate<T>::m_Val[i][j] ) );
01152 }
01153
01154
01155
01156
01157
01158
01159 void extractMatrix(size_t nRow, size_t nCol,size_t nrows, size_t ncols, CMatrixTemplate<T> &outMat) const
01160 {
01161 outMat.setSize(nrows,ncols);
01162
01163 if ( (nRow+nrows > CMatrixTemplate<T>::getRowCount()) || (nCol+ncols >CMatrixTemplate<T>::getColCount()) )
01164 THROW_EXCEPTION("extractMatrix: Row or Col index out of bounds");
01165
01166 const size_t nBytes = ncols * sizeof(T);
01167 for (size_t i=0;i<nrows;i++)
01168 ::memcpy(
01169 outMat.m_Val[i],
01170 m_Val[i+nRow]+nCol,
01171 nBytes);
01172 }
01173
01174
01175
01176
01177
01178
01179 void extractMatrix(size_t nRow, size_t nCol, std::vector<T> &in) const
01180 {
01181 size_t j,ncols,nrows;
01182
01183 ncols = in.size();
01184 nrows = 1;
01185 if ( (nRow+nrows > CMatrixTemplate<T>::getRowCount()) || (nCol+ncols >CMatrixTemplate<T>::getColCount()) )
01186 THROW_EXCEPTION("extractMatrix: Row or Col index out of bounds");
01187
01188 for(j=nCol;j<nCol+ncols;j++)
01189 in[j-nCol] = CMatrixTemplate<T>::m_Val[nRow][j];
01190 }
01191
01192
01193
01194
01195
01196
01197 template <size_t NROWS,size_t NCOLS>
01198 void extractMatrix(const size_t nRow, const size_t nCol, CMatrixFixedNumeric<T,NROWS,NCOLS> &outMat) const {
01199 mrpt::math::extractFixMatrixFromDynMatrix(*this,nRow,nCol,outMat);
01200 }
01201
01202
01203
01204
01205
01206
01207 std::vector<T> extractMatrix(size_t nRow, size_t nCol, size_t ncols) const
01208 {
01209 size_t j;
01210 std::vector<T> out;
01211 out.resize(ncols);
01212
01213 if ( (nRow+1 > CMatrixTemplate<T>::getRowCount()) || (nCol+ncols >CMatrixTemplate<T>::getColCount()) )
01214 THROW_EXCEPTION("extractMatrix: Row or Col index out of bounds");
01215
01216 for(j=nCol;j<nCol+ncols;j++)
01217 out[j-nCol] = CMatrixTemplate<T>::m_Val[nRow][j];
01218 return out;
01219 }
01220
01221
01222
01223
01224
01225
01226 std::string inMatlabFormat(const size_t decimal_digits = 6) const
01227 {
01228 std::stringstream s;
01229
01230 s << "[";
01231 s << std::scientific;
01232 s.precision(decimal_digits);
01233 for (size_t i=0;i<m_Rows;i++)
01234 {
01235 for (size_t j=0;j<m_Cols;j++)
01236 s << m_Val[i][j] << " ";
01237
01238 if (i<m_Rows-1) s << ";";
01239 }
01240 s << "]";
01241
01242 return s.str();
01243 }
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257 bool fromMatlabStringFormat(const std::string &s)
01258 {
01259 this->setSize(0,0);
01260
01261
01262 size_t ini = s.find_first_not_of(" \t");
01263 if (ini==std::string::npos || s[ini]!='[') return false;
01264
01265 size_t end = s.find_last_not_of(" \t");
01266 if (end==std::string::npos || s[end]!=']') return false;
01267
01268 if (ini>end) return false;
01269
01270 std::vector<T> lstElements;
01271
01272 size_t i = ini+1;
01273 size_t nRow = 0;
01274
01275 while (i<end)
01276 {
01277
01278 size_t end_row = s.find_first_of(";]",i);
01279 if (end_row==std::string::npos) { setSize(0,0); return false; }
01280
01281
01282 std::stringstream ss (s.substr(i, end_row-i ));
01283 lstElements.clear();
01284 try
01285 {
01286 while (!ss.eof())
01287 {
01288 T val;
01289 ss >> val;
01290 if (ss.bad() || ss.fail()) break;
01291 lstElements.push_back(val);
01292 }
01293 } catch (...) { }
01294
01295
01296 if (lstElements.empty())
01297 {
01298 if (nRow>0) { setSize(0,0); return false; }
01299
01300 }
01301 else
01302 {
01303 const size_t N = lstElements.size();
01304
01305
01306 if (nRow>0 && m_Cols!=N) { setSize(0,0); return false; }
01307
01308
01309 realloc( nRow+1,N );
01310
01311 for (size_t q=0;q<N;q++)
01312 m_Val[nRow][q] = lstElements[q];
01313
01314
01315 nRow++;
01316 }
01317
01318 i = end_row+1;
01319 }
01320 return true;
01321 }
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333 void saveToTextFile(
01334 const std::string &file,
01335 TMatrixTextFileFormat fileFormat = MATRIX_FORMAT_ENG,
01336 bool appendMRPTHeader = false,
01337 const std::string &userHeader = std::string("")
01338 ) const
01339 {
01340 mrpt::math::saveMatrixToTextFile(*this, file,fileFormat,appendMRPTHeader,userHeader);
01341 }
01342
01343
01344
01345
01346
01347 void loadFromTextFile(const std::string &file)
01348 {
01349 std::ifstream f(file.c_str());
01350 if (f.fail()) THROW_EXCEPTION_CUSTOM_MSG1("loadFromTextFile: can't open file:'%s'",file.c_str());
01351
01352 std::string str;
01353 std::vector<double> fil(512);
01354
01355 const char *ptr;
01356 char *ptrEnd;
01357 size_t i,j;
01358 size_t nCols = std::numeric_limits<size_t>::max();
01359 size_t nRows = 0;
01360
01361 CMatrixTemplate<T>::realloc(0,0);
01362
01363 while ( !f.eof() )
01364 {
01365 std::getline(f,str);
01366
01367 if (str.size() && str[0]!='#' && str[0]!='%')
01368 {
01369
01370 ptr = str.c_str();
01371
01372 ptrEnd = NULL;
01373 i=0;
01374
01375
01376 while ( ptr[0] && ptr!=ptrEnd )
01377 {
01378
01379 while (ptr[0] && (ptr[0]==' ' || ptr[0]=='\t' || ptr[0]=='\r' || ptr[0]=='\n'))
01380 ptr++;
01381
01382 if (fil.size()<=i) fil.resize(fil.size()+512);
01383
01384
01385 fil[i] = strtod(ptr,&ptrEnd);
01386
01387
01388 if (ptr!=ptrEnd)
01389 {
01390 i++;
01391 ptr = ptrEnd;
01392 ptrEnd = NULL;
01393 }
01394 };
01395
01396 if (nCols==std::numeric_limits<size_t>::max())
01397 {
01398
01399 nCols = i;
01400 CMatrixTemplate<T>::realloc(nCols,nCols);
01401 }
01402 else
01403 {
01404
01405 if (CMatrixTemplate<T>::getColCount()!=i )
01406 THROW_EXCEPTION("The matrix in the text file must have the same number of elements in each row!");
01407 }
01408
01409
01410 for (j=0;j<nCols;j++)
01411 CMatrixTemplate<T>::m_Val[nRows][j] = myStaticCast<T>(fil[j]);
01412
01413 nRows++;
01414 if (nRows >= CMatrixTemplate<T>::getRowCount() )
01415 CMatrixTemplate<T>::realloc( nRows+10, nCols );
01416
01417 }
01418
01419 }
01420
01421 if (nRows && nCols)
01422 CMatrixTemplate<T>::realloc( nRows, nCols );
01423
01424
01425 if ( !CMatrixTemplate<T>::getRowCount() || !CMatrixTemplate<T>::getColCount() )
01426 THROW_EXCEPTION("loadFromTextFile: Error loading from text file");
01427 }
01428
01429
01430
01431
01432
01433
01434
01435
01436 void removeColumns( const mrpt::vector_size_t &idxsToRemove, bool vectorIsAlreadySorted = false)
01437 {
01438 MRPT_START
01439
01440 if (idxsToRemove.empty()) return;
01441 ASSERT_(idxsToRemove.size()<=m_Cols);
01442 if (idxsToRemove.size()==m_Cols)
01443 {
01444 this->setSize(m_Rows,0);
01445 return;
01446 }
01447
01448 const vector_size_t *idxs = &idxsToRemove;
01449 vector_size_t auxSortedIdxs;
01450
01451 if (!vectorIsAlreadySorted)
01452 {
01453 auxSortedIdxs = idxsToRemove;
01454 std::sort(auxSortedIdxs.begin(),auxSortedIdxs.end());
01455 idxs = &idxsToRemove;
01456 }
01457
01458 size_t newColCount = m_Cols;
01459
01460 for (vector_size_t::const_reverse_iterator i=idxs->rbegin();i!=idxs->rend();++i)
01461 {
01462 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
01463 if (*i>=m_Cols) THROW_EXCEPTION("removeColumns: Column index out of bounds");
01464 #endif
01465 for (size_t row=0;row<m_Rows;row++)
01466 {
01467
01468 for (size_t c=*i;c<newColCount;c++)
01469 m_Val[row][c] = m_Val[row][c+1];
01470 }
01471 newColCount--;
01472 }
01473
01474 m_Cols = newColCount;
01475
01476 MRPT_END
01477 }
01478
01479
01480
01481 void getAsVector(std::vector<T> &out) const {
01482 out.clear();
01483 out.reserve(m_Rows*m_Cols);
01484 for (size_t i=0;i<m_Rows;i++) out.insert(out.end(),&(m_Val[i][0]),&(m_Val[i][m_Cols]));
01485 }
01486
01487
01488
01489 CMatrixTemplate<T> operator()(const std::vector<size_t> &rows,const std::vector<size_t> &cols) const {
01490 struct gtN {
01491 size_t N;
01492 gtN(size_t el):N(el) {}
01493 bool operator()(size_t el) {
01494 return el>=N;
01495 }
01496 };
01497 ASSERT_((find_if(rows.begin(),rows.end(),gtN(m_Rows))!=rows.end())||(find_if(cols.begin(),cols.end(),gtN(m_Cols))!=cols.end()));
01498 size_t nR=rows.size(),nC=cols.size();
01499 CMatrixTemplate<T> res(nR,nC);
01500 for (size_t i=0;i<nR;++i) for (size_t j=0;j<nC;++j) res(i,j)=m_Val[rows[i]][cols[i]];
01501 return res;
01502 }
01503
01504
01505
01506 void removeRowsAndCols(const std::set<size_t> &rows,const std::set<size_t> &cols) {
01507 struct gtN {
01508 size_t N;
01509 gtN(size_t el):N(el) {}
01510 bool operator()(size_t el) {
01511 return el>=N;
01512 }
01513 };
01514 ASSERT_((find_if(rows.begin(),rows.end(),gtN(m_Rows))==rows.end())||(find_if(cols.begin(),cols.end(),gtN(m_Cols))==cols.end()));
01515 if (rows.empty()&&cols.empty()) return;
01516
01517 size_t newRows=m_Rows-rows.size();
01518 size_t newCols=m_Cols-cols.size();
01519 #ifdef _DEBUG
01520 ASSERT_(newRows<=m_Rows);
01521 ASSERT_(newCols<=m_Cols);
01522 #endif
01523 if (newRows==0||newCols==0) {
01524 realloc(newRows,newCols);
01525 return;
01526 }
01527
01528
01529
01530 std::vector<size_t> rowsOffset;
01531 rowsOffset.reserve(newRows);
01532 std::vector<size_t> colsOffset;
01533 colsOffset.reserve(newCols);
01534 std::set<size_t>::const_iterator it1=rows.begin();
01535 size_t next=0;
01536 while (it1!=rows.end()) {
01537 if (next<*it1) rowsOffset.push_back(next);
01538 else ++it1;
01539 ++next;
01540 }
01541 for (;next<m_Rows;++next) rowsOffset.push_back(next);
01542 it1=cols.begin();
01543 next=0;
01544 while (it1!=cols.end()) {
01545 if (next<*it1) colsOffset.push_back(next);
01546 else ++it1;
01547 ++next;
01548 }
01549 for (;next<m_Cols;++next) colsOffset.push_back(next);
01550
01551 if (cols.empty()) for (size_t i=*rows.begin();i<newRows;++i) for (size_t j=0;j<newCols;++j) m_Val[i][j]=m_Val[rowsOffset[i]][colsOffset[j]];
01552 else if (rows.empty()) for (size_t i=0;i<newRows;++i) for (size_t j=*cols.begin();j<newCols;++j) m_Val[i][j]=m_Val[rowsOffset[i]][colsOffset[j]];
01553 else {
01554 for (size_t j=*cols.begin();j<newCols;++j) m_Val[0][j]=m_Val[rowsOffset[0]][colsOffset[j]];
01555 for (size_t i=1;i<newRows;++i) for (size_t j=0;j<newCols;++j) m_Val[i][j]=m_Val[rowsOffset[i]][colsOffset[j]];
01556 }
01557
01558 realloc(newRows,newCols);
01559 }
01560
01561
01562
01563
01564
01565 void insertRowsAndCols(const std::multiset<size_t> &rows,const std::multiset<size_t> &cols,const T &defaultValue=T()) {
01566 size_t newRows=m_Rows+rows.size();
01567 size_t newCols=m_Cols+cols.size();
01568 std::vector<size_t> rowsOffset(m_Rows);
01569 std::vector<size_t> insertedRows(rows.size());
01570 std::vector<size_t> colsOffset(m_Cols);
01571 std::vector<size_t> insertedCols(cols.size());
01572
01573 size_t iOffset=0;
01574 size_t iInserted=0;
01575 std::multiset<size_t>::const_iterator itInserted=rows.begin();
01576 for (size_t i=0;i<newRows;++i) {
01577 if (itInserted==rows.end()) rowsOffset[iOffset++]=i;
01578 else if (*itInserted<=iOffset) {
01579 insertedRows[iInserted++]=i;
01580 itInserted++;
01581 } else rowsOffset[iOffset++]=i;
01582 }
01583 iOffset=0;
01584 iInserted=0;
01585 itInserted=cols.begin();
01586 for (size_t i=0;i<newCols;++i) {
01587 if (itInserted==cols.end()) colsOffset[iOffset++]=i;
01588 else if (*itInserted<=iOffset) {
01589 insertedCols[iInserted++]=i;
01590 itInserted++;
01591 } else colsOffset[iOffset++]=i;
01592 }
01593
01594 T **newVal=static_cast<T **>(mrpt::system::os::aligned_calloc(sizeof(T *)*newRows,16));
01595 size_t rowSize=sizeof(T)*newCols;
01596 for (size_t i=0;i<newRows;++i) newVal[i]=static_cast<T *>(mrpt::system::os::aligned_calloc(rowSize,16));
01597
01598 for (size_t i=0;i<m_Rows;++i) for (size_t j=0;j<m_Cols;++j) newVal[rowsOffset[i]][colsOffset[j]]=m_Val[i][j];
01599
01600 for (size_t i=0;i<m_Rows;++i) for (size_t j=0;j<insertedCols.size();++j) newVal[rowsOffset[i]][insertedCols[j]]=defaultValue;
01601 for (size_t i=0;i<insertedRows.size();++i) for (size_t j=0;j<newCols;++j) newVal[insertedRows[i]][j]=defaultValue;
01602
01603 for (size_t i=0;i<m_Rows;++i) mrpt::system::os::aligned_free(m_Val[i]);
01604 mrpt::system::os::aligned_free(m_Val);
01605
01606 m_Val=newVal;
01607 m_Rows=newRows;
01608 m_Cols=newCols;
01609 }
01610
01611
01612
01613
01614
01615 template<size_t N,typename ReturnType> inline ReturnType getVicinity(size_t c,size_t r) const {
01616 return detail::getVicinity<CMatrixTemplate<T>,T,ReturnType,N>::get(c,r,*this);
01617 }
01618
01619 };
01620
01621
01622
01623
01624 template <class T>
01625 std::ostream& operator << (std::ostream& ostrm, const CMatrixTemplate<T>& m)
01626 {
01627 ostrm << std::setprecision(4);
01628
01629 for (size_t i=0; i < m.getRowCount(); i++)
01630 {
01631 for (size_t j=0; j < m.getColCount(); j++)
01632 {
01633 ostrm << std::setw(13) << m(i,j);
01634 }
01635 ostrm << std::endl;
01636 }
01637 return ostrm;
01638 }
01639
01640
01641 template <class T>
01642 inline size_t size( const CMatrixTemplate<T>& m, int dim )
01643 {
01644 if (dim==1)
01645 return m.getRowCount();
01646 else if (dim==2)
01647 return m.getColCount();
01648 else THROW_EXCEPTION_CUSTOM_MSG1("size: Matrix dimensions are 1 & 2 only (called with i=%i)",dim);
01649 }
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659 template <class MAT>
01660 void saveMatrixToTextFile(
01661 const MAT &theMatrix,
01662 const std::string &file,
01663 TMatrixTextFileFormat fileFormat,
01664 bool appendMRPTHeader,
01665 const std::string &userHeader
01666 )
01667 {
01668 using namespace mrpt::system;
01669
01670 MRPT_START;
01671
01672 FILE *f=os::fopen(file.c_str(),"wt");
01673 if (!f)
01674 THROW_EXCEPTION_CUSTOM_MSG1("saveToTextFile: Error opening file '%s' for writing a matrix as text.", file.c_str());
01675
01676 if (!userHeader.empty())
01677 fprintf(f,"%s",userHeader.c_str() );
01678
01679 if (appendMRPTHeader)
01680 fprintf(f,"%% File generated with MRPT %s at %s\n%%-----------------------------------------------------------------\n",
01681 mrpt::system::MRPT_getVersion().c_str(),
01682 mrpt::system::dateTimeLocalToString( mrpt::system::now() ).c_str() );
01683
01684 for (size_t i=0; i < theMatrix.getRowCount(); i++)
01685 {
01686 for (size_t j=0; j < theMatrix.getColCount(); j++)
01687 {
01688 switch(fileFormat)
01689 {
01690 case MATRIX_FORMAT_ENG: os::fprintf(f,"%.16e",static_cast<double>(theMatrix(i,j))); break;
01691 case MATRIX_FORMAT_FIXED: os::fprintf(f,"%.16f",static_cast<double>(theMatrix(i,j))); break;
01692 case MATRIX_FORMAT_INT: os::fprintf(f,"%i",static_cast<int>(theMatrix(i,j))); break;
01693 default:
01694 THROW_EXCEPTION("Unsupported value for the parameter 'fileFormat'!");
01695 };
01696
01697 if (j<(theMatrix.getColCount()-1)) os::fprintf(f," ");
01698 }
01699 os::fprintf(f,"\n");
01700 }
01701 os::fclose(f);
01702 MRPT_END;
01703 }
01704
01705
01706
01707
01708 template<typename A,typename T> class AccessorIterator {
01709 protected:
01710 A *base;
01711 int pos;
01712 public:
01713
01714 typedef std::random_access_iterator_tag iterator_category;
01715 typedef T value_type;
01716 typedef int difference_type;
01717 typedef T *pointer;
01718 typedef T &reference;
01719
01720 inline AccessorIterator(A &obj,size_t N):base(&obj),pos(N) {}
01721 inline T &operator*() const {
01722 return (*base)[pos];
01723 }
01724 inline AccessorIterator<A,T> &operator++() {
01725 ++pos;
01726 return *this;
01727 }
01728 inline AccessorIterator<A,T> operator++(int) {
01729 AccessorIterator<A,T> it=*this;
01730 ++*this;
01731 return it;
01732 }
01733 inline AccessorIterator<A,T> &operator--() {
01734 --pos;
01735 return *this;
01736 }
01737 inline AccessorIterator<A,T> operator--(int) {
01738 AccessorIterator<A,T> it=*this;
01739 --*this;
01740 return it;
01741 }
01742 inline AccessorIterator<A,T> &operator+=(int off) {
01743 pos+=off;
01744 return *this;
01745 }
01746 inline AccessorIterator<A,T> operator+(int off) const {
01747 AccessorIterator<A,T> it=*this;
01748 it+=off;
01749 return it;
01750 }
01751 inline AccessorIterator<A,T> &operator-=(int off) {
01752 pos-=off;
01753 return *this;
01754 }
01755 inline AccessorIterator<A,T> operator-(int off) const {
01756 AccessorIterator<A,T> it=*this;
01757 it-=off;
01758 return it;
01759 }
01760 inline int operator-(const AccessorIterator<A,T> &it) const {
01761 return pos-it.pos;
01762 }
01763 inline T &operator[](int off) const {
01764 return (*base)[pos+off];
01765 }
01766 inline bool operator==(const AccessorIterator<A,T> &it) const {
01767 return (pos==it.pos)&&(base==it.base);
01768 }
01769 inline bool operator!=(const AccessorIterator<A,T> &it) const {
01770 return !(operator==(it));
01771 }
01772 };
01773
01774
01775
01776
01777 template<typename A,typename T> class ReverseAccessorIterator {
01778 protected:
01779 A *base;
01780 int pos;
01781 public:
01782
01783 typedef std::random_access_iterator_tag iterator_category;
01784 typedef T value_type;
01785 typedef int difference_type;
01786 typedef T *pointer;
01787 typedef T &reference;
01788
01789 inline ReverseAccessorIterator(A &obj,size_t N):base(&obj),pos(N) {}
01790 inline T &operator*() const {
01791 return (*base)[pos];
01792 }
01793 inline ReverseAccessorIterator<A,T> &operator++() {
01794 --pos;
01795 return *this;
01796 }
01797 inline ReverseAccessorIterator<A,T> operator++(int) {
01798 ReverseAccessorIterator<A,T> it=*this;
01799 ++*this;
01800 return it;
01801 }
01802 inline ReverseAccessorIterator<A,T> &operator--() {
01803 ++pos;
01804 return *this;
01805 }
01806 inline ReverseAccessorIterator<A,T> operator--(int) {
01807 ReverseAccessorIterator<A,T> it=*this;
01808 --*this;
01809 return it;
01810 }
01811 inline ReverseAccessorIterator<A,T> &operator+=(int off) {
01812 pos-=off;
01813 return *this;
01814 }
01815 inline ReverseAccessorIterator<A,T> operator+(int off) const {
01816 ReverseAccessorIterator<A,T> it=*this;
01817 it+=off;
01818 return it;
01819 }
01820 inline AccessorIterator<A,T> &operator-=(int off) {
01821 pos+=off;
01822 return *this;
01823 }
01824 inline AccessorIterator<A,T> operator-(int off) const {
01825 ReverseAccessorIterator<A,T> it=*this;
01826 it-=off;
01827 return it;
01828 }
01829 inline int operator-(const ReverseAccessorIterator<A,T> &it) const {
01830 return it.pos-pos;
01831 }
01832 inline T &operator[](int off) const {
01833 return (*base)[pos-off];
01834 }
01835 inline bool operator==(const ReverseAccessorIterator<A,T> &it) const {
01836 return (pos==it.pos)&&(&base==&it.base);
01837 }
01838 inline bool operator!=(const ReverseAccessorIterator<A,T> &it) const {
01839 return !(operator==(it));
01840 }
01841 };
01842
01843
01844
01845
01846 template <typename T> class CMatrixColumnAccessor {
01847 protected:
01848 CMatrixTemplate<T> *m_mat;
01849 size_t m_colInd;
01850 public:
01851 inline CMatrixColumnAccessor(CMatrixTemplate<T>& mat, size_t colIdx) : m_mat(&mat), m_colInd(colIdx) { ASSERT_(colIdx<mat.getColCount()) }
01852 inline CMatrixColumnAccessor() {}
01853 inline T & operator[](const size_t i) { return (*m_mat)(i,m_colInd); }
01854 inline const T &operator[](const size_t i) const { return (*m_mat)(i,m_colInd); }
01855 typedef AccessorIterator<CMatrixColumnAccessor<T>,T> iterator;
01856 typedef AccessorIterator<const CMatrixColumnAccessor<T>,const T> const_iterator;
01857 typedef ReverseAccessorIterator<CMatrixColumnAccessor<T>,T> reverse_iterator;
01858 typedef ReverseAccessorIterator<const CMatrixColumnAccessor<T>,const T> const_reverse_iterator;
01859 inline iterator begin() {
01860 return iterator(*this,0);
01861 }
01862 inline const_iterator begin() const {
01863 return const_iterator(*this,0);
01864 }
01865 inline iterator end() {
01866 return iterator(*this,m_mat->getRowCount());
01867 }
01868 inline const_iterator end() const {
01869 return const_iterator(*this,m_mat->getRowCount());
01870 }
01871 inline reverse_iterator rbegin() {
01872 return reverse_iterator(*this,m_mat->getRowCount()-1);
01873 }
01874 inline const_reverse_iterator rbegin() const {
01875 return const_reverse_iterator(*this,m_mat->getRowCount()-1);
01876 }
01877 inline reverse_iterator rend() {
01878 return reverse_iterator(*this,-1);
01879 }
01880 inline const_reverse_iterator rend() const {
01881 return const_reverse_iterator(*this,-1);
01882 }
01883 inline size_t size() const {
01884 return m_mat->getRowCount();
01885 }
01886 };
01887
01888
01889
01890
01891 template<typename T>
01892 class CMatrixColumnAccessorExtended {
01893 protected:
01894 CMatrixTemplate<T> *m_mat;
01895 size_t m_colInd;
01896 size_t m_rowOffset;
01897 size_t m_elementsSpace;
01898 size_t howMany;
01899 public:
01900 inline CMatrixColumnAccessorExtended(CMatrixTemplate<T> &mat,size_t col,size_t offset,size_t space):m_mat(&mat),m_colInd(col),m_rowOffset(offset),m_elementsSpace(space) {
01901 ASSERT_(col<mat.getColCount());
01902 howMany=(mat.getRowCount()-m_rowOffset)/m_elementsSpace;
01903 }
01904 inline CMatrixColumnAccessorExtended() {}
01905 inline T &operator[](size_t i) {
01906 return (*m_mat)(m_rowOffset+(i*m_elementsSpace),m_colInd);
01907 }
01908 inline const T &operator[](size_t i) const {
01909 return (*m_mat)(m_rowOffset+(i*m_elementsSpace),m_colInd);
01910 }
01911 typedef AccessorIterator<CMatrixColumnAccessorExtended<T>,T> iterator;
01912 typedef AccessorIterator<const CMatrixColumnAccessorExtended<T>,const T> const_iterator;
01913 typedef ReverseAccessorIterator<CMatrixColumnAccessorExtended<T>,T> reverse_iterator;
01914 typedef ReverseAccessorIterator<const CMatrixColumnAccessorExtended<T>,const T> const_reverse_iterator;
01915 inline iterator begin() {
01916 return iterator(*this,0);
01917 }
01918 inline const_iterator begin() const {
01919 return const_iterator(*this,0);
01920 }
01921 inline iterator end() {
01922 return iterator(*this,howMany);
01923 }
01924 inline const_iterator end() const {
01925 return const_iterator(*this,howMany);
01926 }
01927 inline reverse_iterator rbegin() {
01928 return reverse_iterator(*this,howMany-1);
01929 }
01930 inline const_reverse_iterator rbegin() const {
01931 return const_reverse_iterator(*this,howMany-1);
01932 }
01933 inline reverse_iterator rend() {
01934 return reverse_iterator(*this,-1);
01935 }
01936 inline const_reverse_iterator rend() const {
01937 return const_reverse_iterator(*this,-1);
01938 }
01939 inline size_t size() const {
01940 return howMany();
01941 }
01942 };
01943
01944
01945
01946
01947 template<class T>
01948 class CConstMatrixColumnAccessor {
01949 protected:
01950 const CMatrixTemplate<T> *m_mat;
01951 size_t m_colInd;
01952 public:
01953 inline CConstMatrixColumnAccessor(const CMatrixTemplate<T> &mat,size_t colIdx):m_mat(&mat),m_colInd(colIdx) {
01954 ASSERT_(colIdx<mat.getColCount());
01955 }
01956 inline CConstMatrixColumnAccessor() {}
01957 inline const T &operator[](size_t i) const {
01958 return (*m_mat)(i,m_colInd);
01959 }
01960 typedef AccessorIterator<const CConstMatrixColumnAccessor<T>,const T> const_iterator;
01961 typedef ReverseAccessorIterator<const CConstMatrixColumnAccessor<T>,const T> const_reverse_iterator;
01962 inline const_iterator begin() const {
01963 return const_iterator(*this,0);
01964 }
01965 inline const_iterator end() const {
01966 return const_iterator(*this,m_mat->getRowCount());
01967 }
01968 inline const_reverse_iterator rbegin() const {
01969 return const_reverse_iterator(*this,m_mat->getRowCount()-1);
01970 }
01971 inline const_reverse_iterator rend() const {
01972 return const_reverse_iterator(*this,-1);
01973 }
01974 inline size_t size() const {
01975 return m_mat->getRowCount();
01976 }
01977 };
01978
01979
01980
01981
01982 template<typename T>
01983 class CConstMatrixColumnAccessorExtended {
01984 protected:
01985 const CMatrixTemplate<T> *m_mat;
01986 size_t m_colInd;
01987 size_t m_rowOffset;
01988 size_t m_elementsSpace;
01989 size_t howMany;
01990 public:
01991 inline CConstMatrixColumnAccessorExtended(const CMatrixTemplate<T> &mat,size_t col,size_t offset,size_t space):m_mat(&mat),m_colInd(col),m_rowOffset(offset),m_elementsSpace(space) {
01992 ASSERT_(col<mat.getColCount());
01993 howMany=(mat.getRowCount()-m_rowOffset)/m_elementsSpace;
01994 }
01995 inline CConstMatrixColumnAccessorExtended() {}
01996 inline const T &operator[](size_t i) const {
01997 return (*m_mat)(m_rowOffset+(i*m_elementsSpace),m_colInd);
01998 }
01999 typedef AccessorIterator<const CConstMatrixColumnAccessorExtended<T>,const T> const_iterator;
02000 typedef ReverseAccessorIterator<const CConstMatrixColumnAccessorExtended<T>,const T> const_reverse_iterator;
02001 inline const_iterator begin() const {
02002 return const_iterator(*this,0);
02003 }
02004 inline const_iterator end() const {
02005 return const_iterator(*this,howMany);
02006 }
02007 inline const_reverse_iterator rbegin() const {
02008 return const_reverse_iterator(*this,howMany-1);
02009 }
02010 inline const_reverse_iterator rend() const {
02011 return const_reverse_iterator(*this,-1);
02012 }
02013 inline size_t size() const {
02014 return howMany;
02015 }
02016 };
02017
02018
02019
02020
02021 template <typename T>
02022 class CMatrixRowAccessor
02023 {
02024 protected:
02025 CMatrixTemplate<T> *m_mat;
02026 size_t m_rowInd;
02027 public:
02028 inline CMatrixRowAccessor(CMatrixTemplate<T>& mat, size_t rowIdx) : m_mat(&mat), m_rowInd(rowIdx) { ASSERT_(rowIdx<mat.getRowCount()) }
02029 inline CMatrixRowAccessor() {}
02030 inline T & operator[](const size_t i) { return (*m_mat)(m_rowInd,i); }
02031 inline const T & operator[](const size_t i) const { return (*m_mat)(m_rowInd,i); }
02032 typedef AccessorIterator<CMatrixRowAccessor<T>,T> iterator;
02033 typedef AccessorIterator<const CMatrixRowAccessor<T>,const T> const_iterator;
02034 typedef ReverseAccessorIterator<CMatrixRowAccessor<T>,T> reverse_iterator;
02035 typedef ReverseAccessorIterator<const CMatrixRowAccessor<T>,const T> const_reverse_iterator;
02036 inline iterator begin() {
02037 return iterator(*this,0);
02038 }
02039 inline const_iterator begin() const {
02040 return const_iterator(*this,0);
02041 }
02042 inline iterator end() {
02043 return iterator(*this,m_mat->getColCount());
02044 }
02045 inline const_iterator end() const {
02046 return const_iterator(*this,m_mat->getColCount());
02047 }
02048 inline reverse_iterator rbegin() {
02049 return reverse_iterator(*this,m_mat->getColCount()-1);
02050 }
02051 inline const_reverse_iterator rbegin() const {
02052 return const_reverse_iterator(*this,m_mat.getColCount()-1);
02053 }
02054 inline reverse_iterator rend() {
02055 return reverse_iterator(*this,-1);
02056 }
02057 inline const_reverse_iterator rend() const {
02058 return const_reverse_iterator(*this,-1);
02059 }
02060 inline size_t size() const {
02061 return m_mat->getColCount();
02062 }
02063 };
02064
02065
02066
02067
02068 template<class T>
02069 class CMatrixRowAccessorExtended {
02070 protected:
02071 CMatrixTemplate<T> *m_mat;
02072 size_t m_rowInd;
02073 size_t m_colOffset;
02074 size_t m_elementsSpace;
02075 size_t howMany;
02076 public:
02077 inline CMatrixRowAccessorExtended(CMatrixTemplate<T> &mat,size_t row,size_t offset,size_t space):m_mat(&mat),m_rowInd(row),m_colOffset(offset),m_elementsSpace(space) {
02078 ASSERT_(row<mat.getRowCount());
02079 howMany=(mat.getColCount()-m_colOffset)/m_elementsSpace;
02080 }
02081 inline CMatrixRowAccessorExtended() {}
02082 inline T &operator[](size_t i) {
02083 return (*m_mat)(m_rowInd,m_colOffset+(i*m_elementsSpace));
02084 }
02085 inline const T &operator[](size_t i) const {
02086 return (*m_mat)(m_rowInd,m_colOffset+(i*m_elementsSpace));
02087 }
02088 typedef AccessorIterator<CMatrixRowAccessorExtended<T>,T> iterator;
02089 typedef AccessorIterator<const CMatrixRowAccessorExtended<T>,const T> const_iterator;
02090 typedef ReverseAccessorIterator<CMatrixRowAccessorExtended<T>,T> reverse_iterator;
02091 typedef ReverseAccessorIterator<const CMatrixRowAccessorExtended<T>,const T> const_reverse_iterator;
02092 inline iterator begin() {
02093 return iterator(*this,0);
02094 }
02095 inline const_iterator begin() const {
02096 return const_iterator(*this,0);
02097 }
02098 inline iterator end() {
02099 return iterator(*this,howMany);
02100 }
02101 inline const_iterator end() const {
02102 return const_iterator(*this,howMany);
02103 }
02104 inline reverse_iterator rbegin() {
02105 return reverse_iterator(*this,howMany-1);
02106 }
02107 inline const_reverse_iterator rbegin() const {
02108 return const_reverse_iterator(*this,howMany-1);
02109 }
02110 inline reverse_iterator rend() {
02111 return reverse_iterator(*this,-1);
02112 }
02113 inline const_reverse_iterator rend() const {
02114 return const_reverse_iterator(*this,-1);
02115 }
02116 inline size_t size() const {
02117 return howMany;
02118 }
02119 };
02120
02121
02122
02123
02124 template<class T>
02125 class CConstMatrixRowAccessor {
02126 protected:
02127 const CMatrixTemplate<T> *m_mat;
02128 size_t m_rowInd;
02129 public:
02130 inline CConstMatrixRowAccessor(const CMatrixTemplate<T> &mat,size_t row):m_mat(&mat),m_rowInd(row) {
02131 ASSERT_(row<mat.getRowCount());
02132 }
02133 inline CConstMatrixRowAccessor() {}
02134 inline const T &operator[](size_t i) const {
02135 return (*m_mat)(m_rowInd,i);
02136 }
02137 typedef AccessorIterator<const CConstMatrixRowAccessor<T>,const T> const_iterator;
02138 typedef ReverseAccessorIterator<const CConstMatrixRowAccessor<T>,const T> const_reverse_iterator;
02139 inline const_iterator begin() const {
02140 return const_iterator(*this,0);
02141 }
02142 inline const_iterator end() const {
02143 return const_iterator(*this,m_mat->getColCount());
02144 }
02145 inline const_reverse_iterator rbegin() const {
02146 return const_reverse_iterator(*this,m_mat->getColCount()-1);
02147 }
02148 inline const_reverse_iterator rend() const {
02149 return const_reverse_iterator(*this,-1);
02150 }
02151 inline size_t size() const {
02152 return m_mat->getColCount();
02153 }
02154 };
02155
02156
02157
02158
02159 template<class T>
02160 class CConstMatrixRowAccessorExtended {
02161 protected:
02162 const CMatrixTemplate<T> *m_mat;
02163 size_t m_rowInd;
02164 size_t m_colOffset;
02165 size_t m_elementsSpace;
02166 size_t howMany;
02167 public:
02168 inline CConstMatrixRowAccessorExtended(const CMatrixTemplate<T> &mat,size_t row,size_t offset,size_t space):m_mat(&mat),m_rowInd(row),m_colOffset(offset),m_elementsSpace(space) {
02169 ASSERT_(row<mat.getRowCount());
02170 howMany=(mat.getColCount()-m_colOffset)/m_elementsSpace;
02171 }
02172 inline CConstMatrixRowAccessorExtended() {}
02173 inline const T &operator[](size_t i) const {
02174 return (*m_mat)(m_rowInd,m_colOffset+(i*m_elementsSpace));
02175 }
02176 typedef AccessorIterator<const CConstMatrixRowAccessorExtended<T>,const T> const_iterator;
02177 typedef ReverseAccessorIterator<const CConstMatrixRowAccessorExtended<T>,const T> const_reverse_iterator;
02178 inline const_iterator begin() const {
02179 return const_iterator(*this,0);
02180 }
02181 inline const_iterator end() const {
02182 return const_iterator(*this,howMany);
02183 }
02184 inline const_reverse_iterator rbegin() const {
02185 return const_reverse_iterator(*this,howMany-1);
02186 }
02187 inline const_reverse_iterator rend() const {
02188 return const_reverse_iterator(*this,-1);
02189 }
02190 inline size_t size() const {
02191 return howMany;
02192 }
02193 };
02194
02195 namespace detail {
02196 template<typename M,typename A> void getAccessors(M &mat,std::vector<A> &vec,size_t N) {
02197 vec.resize(N);
02198 for (size_t i=0;i<N;++i) vec[i]=A(mat,i);
02199 }
02200 }
02201
02202
02203
02204
02205
02206
02207
02208 template<typename T> inline void getAsVectorOfAccessors(CMatrixTemplate<T> &mat,std::vector<CMatrixRowAccessor<T> > &vec) {
02209 detail::getAccessors(mat,vec,mat.getRowCount());
02210 }
02211
02212
02213
02214
02215
02216
02217
02218 template<typename T> inline void getAsVectorOfAccessors(const CMatrixTemplate<T> &mat,std::vector<CConstMatrixRowAccessor<T> > &vec) {
02219 detail::getAccessors(mat,vec,mat.getRowCount());
02220 }
02221
02222
02223
02224
02225
02226
02227
02228 template<typename T> inline void getTransposedAsVectorOfAccessors(CMatrixTemplate<T> &mat,std::vector<CMatrixColumnAccessor<T> > &vec) {
02229 detail::getAccessors(mat,vec,mat.getColCount());
02230 }
02231
02232
02233
02234
02235
02236
02237
02238 template<typename T> inline void getTransposedAsVectorOfAccessors(const CMatrixTemplate<T> &mat,std::vector<CConstMatrixColumnAccessor<T> > &vec) {
02239 detail::getAccessors(mat,vec,mat.getColCount());
02240 }
02241
02242 }
02243 }
02244
02245 #endif