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 <mrpt/math/math_frwds.h>
00036 #include <mrpt/math/CArray.h>
00037
00038 namespace mrpt
00039 {
00040 namespace math
00041 {
00042
00043 template <typename U> U myStaticCast(double val) { return static_cast<U>(val); }
00044 template <> bool myStaticCast(double val);
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 template <class T>
00061 class CMatrixTemplate
00062 {
00063 public:
00064
00065 typedef T value_type;
00066 typedef T& reference;
00067 typedef const T& const_reference;
00068 typedef std::size_t size_type;
00069 typedef std::ptrdiff_t difference_type;
00070
00071
00072 protected:
00073 T **m_Val;
00074 size_t m_Rows, m_Cols;
00075
00076
00077
00078 void realloc(size_t row, size_t col, bool newElementsToZero = false)
00079 {
00080 if (row!=m_Rows || col!=m_Cols || m_Val==NULL)
00081 {
00082 size_t r;
00083 bool doZeroColumns = newElementsToZero && (col>m_Cols);
00084 size_t sizeZeroColumns = sizeof(T)*(col-m_Cols);
00085
00086
00087 for (r=row;r<m_Rows;r++)
00088 mrpt::system::os::aligned_free( m_Val[r] );
00089
00090
00091 if (!row)
00092 { mrpt::system::os::aligned_free(m_Val); m_Val=NULL; }
00093 else m_Val = static_cast<T**> (mrpt::system::os::aligned_realloc(m_Val, sizeof(T*) * row, 16 ) );
00094
00095
00096 size_t row_size = col * sizeof(T);
00097
00098
00099 for (r=0;r<row;r++)
00100 {
00101 if (r<m_Rows)
00102 {
00103
00104 m_Val[r] = static_cast<T*> (mrpt::system::os::aligned_realloc( m_Val[r], row_size, 16));
00105
00106 if (doZeroColumns)
00107 {
00108
00109 ::memset(&m_Val[r][m_Cols],0,sizeZeroColumns);
00110 }
00111 }
00112 else
00113 {
00114
00115 m_Val[r] = static_cast<T*> ( mrpt::system::os::aligned_calloc( row_size, 16 ));
00116 }
00117 }
00118
00119
00120 m_Rows = row;
00121 m_Cols = col;
00122 }
00123 }
00124
00125
00126 public:
00127
00128
00129
00130 template<size_t N> inline void ASSERT_ENOUGHROOM(size_t r,size_t c) const {
00131 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00132 ASSERT_((r>=N)&&(r+N<getRowCount())&&(c>=N)&&(c+N<getColCount()));
00133 #endif
00134 }
00135
00136 void fillAll(const T &val) {
00137 for (size_t r=0;r<m_Rows;r++)
00138 for (size_t c=0;c<m_Cols;c++)
00139 m_Val[r][c]=val;
00140 }
00141
00142
00143
00144
00145 void extractCol(size_t nCol, std::vector<T> &out, int startingRow = 0) const
00146 {
00147 size_t i,n;
00148 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00149 if (nCol>=m_Cols)
00150 THROW_EXCEPTION("extractCol: Column index out of bounds");
00151 #endif
00152
00153 n = m_Rows - startingRow;
00154 out.resize( n );
00155
00156 for (i=0;i<n;i++)
00157 out[i] = m_Val[i+startingRow][nCol];
00158 }
00159
00160
00161
00162
00163 void extractCol(size_t nCol, CMatrixTemplate<T> &out, int startingRow = 0) const
00164 {
00165 size_t i,n;
00166 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00167 if (nCol>=m_Cols)
00168 THROW_EXCEPTION("extractCol: Column index out of bounds");
00169 #endif
00170
00171 n = m_Rows - startingRow;
00172 out.setSize(n,1);
00173
00174 for (i=0;i<n;i++)
00175 out(i,0) = m_Val[i+startingRow][nCol];
00176 }
00177
00178
00179
00180
00181 void swapCols(size_t nCol1, size_t nCol2)
00182 {
00183 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00184 if (nCol1>=m_Cols || nCol2>=m_Cols)
00185 THROW_EXCEPTION("swapCols: Column index out of bounds");
00186 #endif
00187 const size_t n = m_Rows;
00188 for (size_t i=0;i<n;i++)
00189 std::swap( m_Val[i][nCol1], m_Val[i][nCol2] );
00190 }
00191
00192
00193
00194
00195 inline void swapRows(size_t nRow1, size_t nRow2)
00196 {
00197 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00198 if (nRow1>=m_Rows || nRow2>=m_Rows)
00199 THROW_EXCEPTION("swapCols: Row index out of bounds");
00200 #endif
00201 std::swap(CMatrixTemplate<T>::m_Val[nRow1], CMatrixTemplate<T>::m_Val[nRow2] );
00202 }
00203
00204
00205
00206
00207 template <class F>
00208 void extractRow(size_t nRow, std::vector<F> &out, size_t startingCol = 0) const
00209 {
00210 size_t i,n;
00211 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00212 if (nRow>=m_Rows)
00213 THROW_EXCEPTION("extractRow: Row index out of bounds");
00214 #endif
00215 n = m_Cols - startingCol ;
00216 out.resize( n );
00217
00218 for (i=0;i<n;i++)
00219 out[i] = static_cast<F> ( m_Val[nRow][i+startingCol] );
00220 }
00221
00222
00223
00224
00225 template <class F>
00226 void extractRow(size_t nRow, CMatrixTemplate<F> &out, size_t startingCol = 0) const
00227 {
00228 size_t i,n;
00229 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00230 if (nRow>=m_Rows)
00231 THROW_EXCEPTION("extractRow: Row index out of bounds");
00232 #endif
00233 n = m_Cols - startingCol ;
00234 out.setSize(1,n);
00235
00236 for (i=0;i<n;i++)
00237 out(0,i) = static_cast<F>( m_Val[nRow][i+startingCol] );
00238 }
00239
00240
00241
00242 CMatrixTemplate (const CMatrixTemplate& m) : m_Val(NULL),m_Rows(0),m_Cols(0)
00243 {
00244 (*this) = m;
00245 }
00246
00247 CMatrixTemplate (size_t row = 3, size_t col = 3) : m_Val(NULL),m_Rows(0),m_Cols(0)
00248 {
00249 realloc(row,col);
00250 }
00251
00252
00253
00254 CMatrixTemplate (const CMatrixTemplate& m, const size_t cropRowCount, const size_t cropColCount) : m_Val(NULL),m_Rows(0),m_Cols(0)
00255 {
00256 ASSERT_(m.m_Rows>=cropRowCount)
00257 ASSERT_(m.m_Cols>=cropColCount)
00258
00259 realloc( cropRowCount, cropColCount );
00260
00261 for (size_t i=0; i < m_Rows; i++)
00262 for (size_t j=0; j < m_Cols; j++)
00263 m_Val[i][j] = m.m_Val[i][j];
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 template <typename V, size_t N>
00275 CMatrixTemplate (size_t row, size_t col, V (&theArray)[N] ) : m_Val(NULL),m_Rows(0),m_Cols(0)
00276 {
00277 MRPT_COMPILE_TIME_ASSERT(N!=0)
00278 realloc(row,col);
00279 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)))
00280 size_t idx=0;
00281 for (size_t i=0; i < m_Rows; i++)
00282 for (size_t j=0; j < m_Cols; j++)
00283 m_Val[i][j] = static_cast<T>(theArray[idx++]);
00284
00285 }
00286
00287
00288
00289 template <typename V>
00290 CMatrixTemplate(size_t row, size_t col, const V &theVector ) : m_Val(NULL),m_Rows(0),m_Cols(0)
00291 {
00292 const size_t N = theVector.size();
00293 realloc(row,col);
00294 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)))
00295
00296 typename V::const_iterator it = theVector.begin();
00297 for (size_t i=0; i < m_Rows; i++)
00298 for (size_t j=0; j < m_Cols; j++)
00299 m_Val[i][j] = static_cast<T>( *(it++) );
00300
00301 }
00302
00303
00304
00305 virtual ~CMatrixTemplate()
00306 {
00307 realloc(0,0);
00308 }
00309
00310
00311
00312 CMatrixTemplate& operator = (const CMatrixTemplate& m)
00313 {
00314 realloc( m.m_Rows, m.m_Cols );
00315
00316 for (size_t i=0; i < m_Rows; i++)
00317 for (size_t j=0; j < m_Cols; j++)
00318 m_Val[i][j] = m.m_Val[i][j];
00319
00320 return *this;
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 template <typename V, size_t N>
00334 CMatrixTemplate& operator = (V (&theArray)[N] )
00335 {
00336 MRPT_COMPILE_TIME_ASSERT(N!=0)
00337
00338 if (m_Rows*m_Cols != N)
00339 {
00340 THROW_EXCEPTION(format("Mismatch between matrix size %lu x %lu and array of length %lu",m_Rows,m_Cols,N))
00341 }
00342 size_t idx=0;
00343 for (size_t i=0; i < m_Rows; i++)
00344 for (size_t j=0; j < m_Cols; j++)
00345 m_Val[i][j] = static_cast<T>(theArray[idx++]);
00346
00347 return *this;
00348 }
00349
00350
00351
00352
00353
00354 inline size_t getRowCount() const { return m_Rows; }
00355
00356
00357
00358
00359 inline size_t getColCount() const { return m_Cols; }
00360
00361
00362 inline const CMatrixTemplateSize & size() const
00363 {
00364 static CMatrixTemplateSize dims;
00365 dims[0]=m_Rows;
00366 dims[1]=m_Cols;
00367 return dims;
00368 }
00369
00370
00371 void setSize(size_t row, size_t col,bool zeroNewElements=false)
00372 {
00373 realloc(row,col,zeroNewElements);
00374 }
00375
00376
00377 inline void resize(const CMatrixTemplateSize &siz,bool zeroNewElements=false)
00378 {
00379 setSize(siz[0],siz[1],zeroNewElements);
00380 }
00381
00382
00383
00384 inline T& operator () (size_t row, size_t col)
00385 {
00386 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00387 if (row >= m_Rows || col >= m_Cols)
00388 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)) );
00389 #endif
00390 return m_Val[row][col];
00391 }
00392
00393
00394
00395 inline const T &operator () (size_t row, size_t col) const
00396 {
00397 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00398 if (row >= m_Rows || col >= m_Cols)
00399 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)) );
00400 #endif
00401 return m_Val[row][col];
00402 }
00403
00404
00405
00406
00407 inline T& operator () (size_t ith)
00408 {
00409 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00410 ASSERT_(m_Rows==1 || m_Cols==1);
00411 #endif
00412 if (m_Rows==1)
00413 {
00414
00415 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00416 if (ith >= m_Cols)
00417 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00418 #endif
00419 return m_Val[0][ith];
00420 }
00421 else
00422 {
00423
00424 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00425 if (ith >= m_Rows)
00426 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00427 #endif
00428 return m_Val[ith][0];
00429 }
00430 }
00431
00432
00433
00434
00435 inline T operator () (size_t ith) const
00436 {
00437 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00438 ASSERT_(m_Rows==1 || m_Cols==1);
00439 #endif
00440 if (m_Rows==1)
00441 {
00442
00443 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00444 if (ith >= m_Cols)
00445 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00446 #endif
00447 return m_Val[0][ith];
00448 }
00449 else
00450 {
00451
00452 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00453 if (ith >= m_Rows)
00454 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00455 #endif
00456 return m_Val[ith][0];
00457 }
00458 }
00459
00460
00461
00462 inline void set_unsafe(size_t row, size_t col,const T &v)
00463 {
00464 #ifdef _DEBUG
00465 if (row >= m_Rows || col >= m_Cols)
00466 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)) );
00467 #endif
00468 m_Val[row][col] = v;
00469 }
00470
00471
00472
00473 inline const T &get_unsafe(size_t row, size_t col) const
00474 {
00475 #ifdef _DEBUG
00476 if (row >= m_Rows || col >= m_Cols)
00477 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)) );
00478 #endif
00479 return m_Val[row][col];
00480 }
00481
00482
00483
00484 inline T &get_unsafe(size_t row,size_t col)
00485 {
00486 #ifdef _DEBUG
00487 if (row >= m_Rows || col >= m_Cols)
00488 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)) );
00489 #endif
00490 return m_Val[row][col];
00491 }
00492
00493
00494
00495 inline T* get_unsafe_row(size_t row)
00496 {
00497 #ifdef _DEBUG
00498 if (row >= m_Rows)
00499 THROW_EXCEPTION( format("Row index %"PRIuPTR" out of range. Matrix is %"PRIuPTR"x%"PRIuPTR,static_cast<unsigned long>(row),static_cast<unsigned long>(m_Rows),static_cast<unsigned long>(m_Cols)) );
00500 #endif
00501 return m_Val[row];
00502 }
00503
00504
00505
00506 inline const T* get_unsafe_row(size_t row) const {
00507 return m_Val[row];
00508 }
00509
00510
00511
00512
00513
00514
00515 inline void extractRows(size_t firstRow,size_t lastRow,CMatrixTemplate<T> &out) const {
00516 extractMatrix(firstRow,0,lastRow-firstRow+1,m_Cols,out);
00517 }
00518
00519
00520
00521
00522
00523
00524 inline void extractColumns(size_t firstCol,size_t lastCol,CMatrixTemplate<T> &out) const {
00525 extractMatrix(0,firstCol,m_Rows,lastCol-firstCol+1,out);
00526 }
00527
00528
00529
00530
00531
00532 void insertRow(size_t nRow, const std::vector<T> &in)
00533 {
00534 if (nRow>=m_Rows) THROW_EXCEPTION("insertRow: Row index out of bounds");
00535
00536 size_t n = in.size();
00537 ASSERT_(m_Cols>=in.size());
00538
00539 for (size_t i=0;i<n;i++)
00540 m_Val[nRow][i] = in[i];
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 void appendRow(const std::vector<T> &in)
00557 {
00558 size_t i,n, row;
00559
00560 n = m_Cols;
00561 row = m_Rows;
00562
00563 if (m_Cols==0 || m_Rows==0)
00564 {
00565 ASSERT_(!in.empty());
00566 n=m_Cols=in.size();
00567 }
00568 else
00569 {
00570 ASSERT_(in.size()==m_Cols);
00571 }
00572
00573 realloc( row+1,n );
00574
00575 for (i=0;i<n;i++)
00576 m_Val[row][i] = in[i];
00577 }
00578
00579
00580
00581
00582
00583
00584
00585 void appendCol(const std::vector<T> &in) {
00586 size_t r=m_Rows,c=m_Cols;
00587 if (m_Cols==0||m_Rows==0) {
00588 ASSERT_(!in.empty());
00589 r=in.size();
00590 c=0;
00591 } else ASSERT_(in.size()==m_Rows);
00592 realloc(r,c+1);
00593 for (size_t i=0;i<m_Rows;i++) m_Val[i][m_Cols-1]=in[i];
00594 }
00595
00596
00597
00598
00599
00600 void insertCol(size_t nCol, const std::vector<T> &in)
00601 {
00602 if (nCol>=m_Cols) THROW_EXCEPTION("insertCol: Row index out of bounds");
00603
00604 size_t n = in.size();
00605 ASSERT_( m_Rows >= in.size() );
00606
00607 for (size_t i=0;i<n;i++)
00608 m_Val[i][nCol] = in[i];
00609 }
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619 template <class MAT_R>
00620 void insertMatrix(const size_t nRow,const size_t nCol, const MAT_R &in)
00621 {
00622 const size_t nrows = in.getRowCount();
00623 const size_t ncols = in.getColCount();
00624 if ( (nRow+nrows > m_Rows) || (nCol+ncols >m_Cols) )
00625 THROW_EXCEPTION("insertMatrix: Row or Col index out of bounds");
00626 for (size_t i=nRow;i<nRow+nrows;i++)
00627 for(size_t j=nCol;j<nCol+ncols;j++)
00628 set_unsafe(i,j, static_cast<typename MAT_R::value_type> (in.get_unsafe(i-nRow,j-nCol) ) );
00629 }
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 template <class MAT_R>
00640 void insertMatrixTranspose(const size_t nRow,const size_t nCol, const MAT_R &in)
00641 {
00642 const size_t ncols = in.getRowCount();
00643 const size_t nrows = in.getColCount();
00644 if ( (nRow+nrows > m_Rows) || (nCol+ncols >m_Cols) )
00645 THROW_EXCEPTION("insertMatrix: Row or Col index out of bounds");
00646 for (size_t i=nRow;i<nRow+nrows;i++)
00647 for(size_t j=nCol;j<nCol+ncols;j++)
00648 set_unsafe(i,j, static_cast<typename MAT_R::value_type> ( in.get_unsafe(j-nCol,i-nRow) ) );
00649 }
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 template <size_t NROWS,size_t NCOLS>
00660 inline void insertMatrix(const size_t nRow, const size_t nCol, const CMatrixFixedNumeric<T,NROWS,NCOLS> &in) {
00661 detail::insertMatrixFixIntoDyn(*this,nRow,nCol,in);
00662 }
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672 template <size_t NROWS,size_t NCOLS>
00673 inline void insertMatrixTranspose(const size_t nRow,const size_t nCol, const CMatrixFixedNumeric<T,NROWS,NCOLS> &in) {
00674 detail::insertMatrixFixTransposeIntoDyn(*this,nRow,nCol,in);
00675 }
00676
00677
00678
00679
00680
00681
00682
00683 void insertMatrix(size_t nRow, size_t nCol, const std::vector<T> &in)
00684 {
00685 size_t j,ncols;
00686
00687 ncols = in.size();
00688 if ( (nRow+1 > m_Rows) || (nCol+ncols >m_Cols) )
00689 THROW_EXCEPTION("insertMatrix: Row or Col index out of bounds");
00690
00691 for(j = nCol ; j < nCol + ncols ; j++)
00692 set_unsafe(nRow,j, in[j-nCol] );
00693 }
00694
00695
00696
00697
00698
00699 void joinMatrix(const CMatrixTemplate<T> &left_up, const CMatrixTemplate<T> &right_up,
00700 const CMatrixTemplate<T> &left_down, const CMatrixTemplate<T> &right_down)
00701 {
00702 if ((left_up.getRowCount()!= right_up.getRowCount())||(left_up.getColCount()!=left_down.getColCount())||
00703 (left_down.getRowCount()!=right_down.getRowCount())||(right_up.getColCount()!=right_down.getColCount()))
00704 THROW_EXCEPTION("join_Matrix: Row or Col index out of bounds");
00705 setSize(left_up.getRowCount()+left_down.getRowCount(),left_up.getColCount()+right_up.getColCount());
00706 insertMatrix(0,0,left_up);
00707 insertMatrix(0,left_up.getColCount(),right_up);
00708 insertMatrix(left_up.getRowCount(),0,left_down);
00709 insertMatrix(left_up.getRowCount(),left_up.getColCount(),right_down);
00710 }
00711
00712
00713
00714
00715 void extractSubmatrix(const size_t row1,const size_t row2,const size_t col1,const size_t col2,CMatrixTemplate<T> &out) const {
00716 size_t nrows=row2-row1+1;
00717 size_t ncols=col2-col1+1;
00718 if (nrows<=0||ncols<=0) {
00719 out.realloc(0,0);
00720 return;
00721 }
00722 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00723 if (row1<0||row2>=m_Rows||col1<0||col2>=m_Cols) THROW_EXCEPTION("Indices out of range!");
00724 #endif
00725 out.realloc(nrows,ncols);
00726 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];
00727 }
00728
00729
00730
00731 inline CMatrixTemplate<T> operator() (const size_t row1,const size_t row2,const size_t col1,const size_t col2) const {
00732 CMatrixTemplate<T> val(0,0);
00733 extractSubmatrix(row1,row2,col1,col2,val);
00734 return val;
00735 }
00736
00737
00738
00739
00740
00741 void extractSubmatrixSymmetricalBlocks(
00742 const size_t block_size,
00743 const vector_size_t &block_indices,
00744 CMatrixTemplate<T> &out) const
00745 {
00746 ASSERT_(block_size>=1);
00747 ASSERT_(m_Cols==m_Rows);
00748
00749 const size_t N = block_indices.size();
00750 size_t nrows_out=N*block_size;
00751 out.realloc(nrows_out,nrows_out);
00752 if (!N) return;
00753
00754 for (size_t dst_row_blk=0;dst_row_blk<N; ++dst_row_blk )
00755 {
00756 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00757 if (block_indices[dst_row_blk]*block_size + block_size-1>=m_Cols) THROW_EXCEPTION("Indices out of range!");
00758 #endif
00759
00760 for (size_t r=0;r<block_size;r++)
00761 {
00762 const T* src_row = this->m_Val[ block_indices[dst_row_blk] * block_size + r ];
00763 T* dst = &out.m_Val[ block_size*dst_row_blk + r ][0];
00764 for (size_t dst_col_blk=0;dst_col_blk<N; ++dst_col_blk )
00765 {
00766 const T* src = src_row + block_indices[dst_col_blk] * block_size;
00767 for (size_t c=0;c<block_size;c++)
00768 *dst++ = *src++;
00769 }
00770 }
00771 }
00772 }
00773
00774
00775
00776
00777
00778 void extractSubmatrixSymmetrical(
00779 const vector_size_t &indices,
00780 CMatrixTemplate<T> &out) const
00781 {
00782 ASSERT_(m_Cols==m_Rows);
00783
00784 const size_t N = indices.size();
00785 const size_t nrows_out=N;
00786 out.realloc(nrows_out,nrows_out);
00787 if (!N) return;
00788
00789 for (size_t dst_row_blk=0;dst_row_blk<N; ++dst_row_blk )
00790 {
00791 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00792 if (indices[dst_row_blk]>=m_Cols) THROW_EXCEPTION("Indices out of range!");
00793 #endif
00794 const T* src_row = this->m_Val[ indices[dst_row_blk] ];
00795 T* dst = &out.m_Val[ dst_row_blk ][0];
00796 for (size_t dst_col_blk=0;dst_col_blk<N; ++dst_col_blk )
00797 {
00798 const T* src = src_row + indices[dst_col_blk];
00799 *dst++ = *src++;
00800 }
00801 }
00802 }
00803
00804
00805
00806
00807 void exchangeColumns(size_t col1,size_t col2) {
00808 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00809 if (col1<0||col2<0||col1>=m_Cols||col2>=m_Cols) THROW_EXCEPTION("Indices out of range!");
00810 #endif
00811 T tmp;
00812 for (size_t i=0;i<m_Rows;i++) {
00813 tmp=m_Val[i][col1];
00814 m_Val[i][col1]=m_Val[i][col2];
00815 m_Val[i][col2]=tmp;
00816 }
00817 }
00818
00819
00820 inline void exchangeRows(size_t row1,size_t row2) { swapRows(row1,row2); }
00821
00822
00823
00824 void deleteRow(size_t row) {
00825 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00826 if (row<0||row>=m_Rows) THROW_EXCEPTION("Index out of range!");
00827 #endif
00828 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];
00829 realloc(m_Rows-1,m_Cols);
00830 }
00831
00832
00833
00834 void deleteColumn(size_t col) {
00835 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00836 if (col<0||col>=m_Cols) THROW_EXCEPTION("Index out of range!");
00837 #endif
00838 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];
00839 realloc(m_Rows,m_Cols-1);
00840 }
00841
00842
00843
00844
00845
00846
00847 template <class R>
00848 void extractMatrix(size_t nRow, size_t nCol, CMatrixTemplate<R> &in) const
00849 {
00850 size_t i,j,ncols,nrows;
00851
00852 nrows = in.getRowCount();
00853 ncols = in.getColCount();
00854 if ( (nRow+nrows > CMatrixTemplate<T>::getRowCount()) || (nCol+ncols >CMatrixTemplate<T>::getColCount()) )
00855 THROW_EXCEPTION("extractMatrix: Row or Col index out of bounds");
00856
00857 for (i=nRow;i<nRow+nrows;i++)
00858 for(j=nCol;j<nCol+ncols;j++)
00859 in.set_unsafe( i-nRow,j-nCol, static_cast<R> ( CMatrixTemplate<T>::m_Val[i][j] ) );
00860 }
00861
00862
00863
00864
00865
00866
00867 void extractMatrix(size_t nRow, size_t nCol,size_t nrows, size_t ncols, CMatrixTemplate<T> &outMat) const
00868 {
00869 outMat.setSize(nrows,ncols);
00870
00871 if ( (nRow+nrows > CMatrixTemplate<T>::getRowCount()) || (nCol+ncols >CMatrixTemplate<T>::getColCount()) )
00872 THROW_EXCEPTION("extractMatrix: Row or Col index out of bounds");
00873
00874 const size_t nBytes = ncols * sizeof(T);
00875 for (size_t i=0;i<nrows;i++)
00876 ::memcpy(
00877 outMat.m_Val[i],
00878 m_Val[i+nRow]+nCol,
00879 nBytes);
00880 }
00881
00882
00883
00884
00885
00886
00887 void extractMatrix(size_t nRow, size_t nCol, std::vector<T> &in) const
00888 {
00889 size_t j,ncols,nrows;
00890
00891 ncols = in.size();
00892 nrows = 1;
00893 if ( (nRow+nrows > CMatrixTemplate<T>::getRowCount()) || (nCol+ncols >CMatrixTemplate<T>::getColCount()) )
00894 THROW_EXCEPTION("extractMatrix: Row or Col index out of bounds");
00895
00896 for(j=nCol;j<nCol+ncols;j++)
00897 in[j-nCol] = CMatrixTemplate<T>::m_Val[nRow][j];
00898 }
00899
00900
00901
00902
00903
00904
00905 template <size_t NROWS,size_t NCOLS>
00906 inline void extractMatrix(const size_t nRow, const size_t nCol, CMatrixFixedNumeric<T,NROWS,NCOLS> &outMat) const {
00907 detail::extractFixMatrixFromDynMatrix(*this,nRow,nCol,outMat);
00908 }
00909
00910
00911
00912
00913
00914
00915 std::vector<T> extractMatrix(size_t nRow, size_t nCol, size_t ncols) const
00916 {
00917 size_t j;
00918 std::vector<T> out;
00919 out.resize(ncols);
00920
00921 if ( (nRow+1 > CMatrixTemplate<T>::getRowCount()) || (nCol+ncols >CMatrixTemplate<T>::getColCount()) )
00922 THROW_EXCEPTION("extractMatrix: Row or Col index out of bounds");
00923
00924 for(j=nCol;j<nCol+ncols;j++)
00925 out[j-nCol] = CMatrixTemplate<T>::m_Val[nRow][j];
00926 return out;
00927 }
00928
00929
00930
00931
00932
00933
00934 std::string inMatlabFormat(const size_t decimal_digits = 6) const
00935 {
00936 std::stringstream s;
00937
00938 s << "[";
00939 s << std::scientific;
00940 s.precision(decimal_digits);
00941 for (size_t i=0;i<m_Rows;i++)
00942 {
00943 for (size_t j=0;j<m_Cols;j++)
00944 s << m_Val[i][j] << " ";
00945
00946 if (i<m_Rows-1) s << ";";
00947 }
00948 s << "]";
00949
00950 return s.str();
00951 }
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965 bool fromMatlabStringFormat(const std::string &s)
00966 {
00967 this->setSize(0,0);
00968
00969
00970 size_t ini = s.find_first_not_of(" \t");
00971 if (ini==std::string::npos || s[ini]!='[') return false;
00972
00973 size_t end = s.find_last_not_of(" \t");
00974 if (end==std::string::npos || s[end]!=']') return false;
00975
00976 if (ini>end) return false;
00977
00978 std::vector<T> lstElements;
00979
00980 size_t i = ini+1;
00981 size_t nRow = 0;
00982
00983 while (i<end)
00984 {
00985
00986 size_t end_row = s.find_first_of(";]",i);
00987 if (end_row==std::string::npos) { setSize(0,0); return false; }
00988
00989
00990 std::stringstream ss (s.substr(i, end_row-i ));
00991 lstElements.clear();
00992 try
00993 {
00994 while (!ss.eof())
00995 {
00996 T val;
00997 ss >> val;
00998 if (ss.bad() || ss.fail()) break;
00999 lstElements.push_back(val);
01000 }
01001 } catch (...) { }
01002
01003
01004 if (lstElements.empty())
01005 {
01006 if (nRow>0) { setSize(0,0); return false; }
01007
01008 }
01009 else
01010 {
01011 const size_t N = lstElements.size();
01012
01013
01014 if (nRow>0 && m_Cols!=N) { setSize(0,0); return false; }
01015
01016
01017 realloc( nRow+1,N );
01018
01019 for (size_t q=0;q<N;q++)
01020 m_Val[nRow][q] = lstElements[q];
01021
01022
01023 nRow++;
01024 }
01025
01026 i = end_row+1;
01027 }
01028 return true;
01029 }
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041 inline void saveToTextFile(
01042 const std::string &file,
01043 TMatrixTextFileFormat fileFormat = MATRIX_FORMAT_ENG,
01044 bool appendMRPTHeader = false,
01045 const std::string &userHeader = std::string("")
01046 ) const
01047 {
01048 detail::saveMatrixToTextFile(*this, file,fileFormat,appendMRPTHeader,userHeader);
01049 }
01050
01051
01052
01053
01054
01055 void loadFromTextFile(const std::string &file)
01056 {
01057 std::ifstream f(file.c_str());
01058 if (f.fail()) THROW_EXCEPTION_CUSTOM_MSG1("loadFromTextFile: can't open file:'%s'",file.c_str());
01059
01060 std::string str;
01061 std::vector<double> fil(512);
01062
01063 const char *ptr;
01064 char *ptrEnd;
01065 size_t i,j;
01066 size_t nCols = std::numeric_limits<size_t>::max();
01067 size_t nRows = 0;
01068
01069 CMatrixTemplate<T>::realloc(0,0);
01070
01071 while ( !f.eof() )
01072 {
01073 std::getline(f,str);
01074
01075 if (str.size() && str[0]!='#' && str[0]!='%')
01076 {
01077
01078 ptr = str.c_str();
01079
01080 ptrEnd = NULL;
01081 i=0;
01082
01083
01084 while ( ptr[0] && ptr!=ptrEnd )
01085 {
01086
01087 while (ptr[0] && (ptr[0]==' ' || ptr[0]=='\t' || ptr[0]=='\r' || ptr[0]=='\n'))
01088 ptr++;
01089
01090 if (fil.size()<=i) fil.resize(fil.size()+512);
01091
01092
01093 fil[i] = strtod(ptr,&ptrEnd);
01094
01095
01096 if (ptr!=ptrEnd)
01097 {
01098 i++;
01099 ptr = ptrEnd;
01100 ptrEnd = NULL;
01101 }
01102 };
01103
01104 if (nCols==std::numeric_limits<size_t>::max())
01105 {
01106
01107 nCols = i;
01108 CMatrixTemplate<T>::realloc(nCols,nCols);
01109 }
01110 else
01111 {
01112
01113 if (CMatrixTemplate<T>::getColCount()!=i )
01114 THROW_EXCEPTION("The matrix in the text file must have the same number of elements in each row!");
01115 }
01116
01117
01118 for (j=0;j<nCols;j++)
01119 CMatrixTemplate<T>::m_Val[nRows][j] = myStaticCast<T>(fil[j]);
01120
01121 nRows++;
01122 if (nRows >= CMatrixTemplate<T>::getRowCount() )
01123 CMatrixTemplate<T>::realloc( nRows+10, nCols );
01124
01125 }
01126
01127 }
01128
01129 if (nRows && nCols)
01130 CMatrixTemplate<T>::realloc( nRows, nCols );
01131
01132
01133 if ( !CMatrixTemplate<T>::getRowCount() || !CMatrixTemplate<T>::getColCount() )
01134 THROW_EXCEPTION("loadFromTextFile: Error loading from text file");
01135 }
01136
01137
01138
01139
01140
01141
01142
01143
01144 void removeColumns( const mrpt::vector_size_t &idxsToRemove, bool vectorIsAlreadySorted = false)
01145 {
01146 MRPT_START
01147
01148 if (idxsToRemove.empty()) return;
01149 ASSERT_(idxsToRemove.size()<=m_Cols);
01150 if (idxsToRemove.size()==m_Cols)
01151 {
01152 this->setSize(m_Rows,0);
01153 return;
01154 }
01155
01156 const vector_size_t *idxs = &idxsToRemove;
01157 vector_size_t auxSortedIdxs;
01158
01159 if (!vectorIsAlreadySorted)
01160 {
01161 auxSortedIdxs = idxsToRemove;
01162 std::sort(auxSortedIdxs.begin(),auxSortedIdxs.end());
01163 idxs = &idxsToRemove;
01164 }
01165
01166 size_t newColCount = m_Cols;
01167
01168 for (vector_size_t::const_reverse_iterator i=idxs->rbegin();i!=idxs->rend();++i)
01169 {
01170 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
01171 if (*i>=m_Cols) THROW_EXCEPTION("removeColumns: Column index out of bounds");
01172 #endif
01173 for (size_t row=0;row<m_Rows;row++)
01174 {
01175
01176 for (size_t c=*i;c<newColCount;c++)
01177 m_Val[row][c] = m_Val[row][c+1];
01178 }
01179 newColCount--;
01180 }
01181
01182 m_Cols = newColCount;
01183
01184 MRPT_END
01185 }
01186
01187
01188
01189 void getAsVector(std::vector<T> &out) const {
01190 out.clear();
01191 out.reserve(m_Rows*m_Cols);
01192 for (size_t i=0;i<m_Rows;i++) out.insert(out.end(),&(m_Val[i][0]),&(m_Val[i][m_Cols]));
01193 }
01194
01195
01196
01197 CMatrixTemplate<T> operator()(const std::vector<size_t> &rows,const std::vector<size_t> &cols) const {
01198 struct gtN {
01199 size_t N;
01200 gtN(size_t el):N(el) {}
01201 bool operator()(size_t el) {
01202 return el>=N;
01203 }
01204 };
01205 ASSERT_((find_if(rows.begin(),rows.end(),gtN(m_Rows))!=rows.end())||(find_if(cols.begin(),cols.end(),gtN(m_Cols))!=cols.end()));
01206 size_t nR=rows.size(),nC=cols.size();
01207 CMatrixTemplate<T> res(nR,nC);
01208 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]];
01209 return res;
01210 }
01211
01212
01213
01214 void removeRowsAndCols(const std::set<size_t> &rows,const std::set<size_t> &cols) {
01215 struct gtN {
01216 size_t N;
01217 gtN(size_t el):N(el) {}
01218 bool operator()(size_t el) {
01219 return el>=N;
01220 }
01221 };
01222 ASSERT_((find_if(rows.begin(),rows.end(),gtN(m_Rows))==rows.end())||(find_if(cols.begin(),cols.end(),gtN(m_Cols))==cols.end()));
01223 if (rows.empty()&&cols.empty()) return;
01224
01225 size_t newRows=m_Rows-rows.size();
01226 size_t newCols=m_Cols-cols.size();
01227 #ifdef _DEBUG
01228 ASSERT_(newRows<=m_Rows);
01229 ASSERT_(newCols<=m_Cols);
01230 #endif
01231 if (newRows==0||newCols==0) {
01232 realloc(newRows,newCols);
01233 return;
01234 }
01235
01236
01237
01238 std::vector<size_t> rowsOffset;
01239 rowsOffset.reserve(newRows);
01240 std::vector<size_t> colsOffset;
01241 colsOffset.reserve(newCols);
01242 std::set<size_t>::const_iterator it1=rows.begin();
01243 size_t next=0;
01244 while (it1!=rows.end()) {
01245 if (next<*it1) rowsOffset.push_back(next);
01246 else ++it1;
01247 ++next;
01248 }
01249 for (;next<m_Rows;++next) rowsOffset.push_back(next);
01250 it1=cols.begin();
01251 next=0;
01252 while (it1!=cols.end()) {
01253 if (next<*it1) colsOffset.push_back(next);
01254 else ++it1;
01255 ++next;
01256 }
01257 for (;next<m_Cols;++next) colsOffset.push_back(next);
01258
01259 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]];
01260 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]];
01261 else {
01262 for (size_t j=*cols.begin();j<newCols;++j) m_Val[0][j]=m_Val[rowsOffset[0]][colsOffset[j]];
01263 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]];
01264 }
01265
01266 realloc(newRows,newCols);
01267 }
01268
01269
01270
01271
01272
01273 void insertRowsAndCols(const std::multiset<size_t> &rows,const std::multiset<size_t> &cols,const T &defaultValue=T()) {
01274 size_t newRows=m_Rows+rows.size();
01275 size_t newCols=m_Cols+cols.size();
01276 std::vector<size_t> rowsOffset(m_Rows);
01277 std::vector<size_t> insertedRows(rows.size());
01278 std::vector<size_t> colsOffset(m_Cols);
01279 std::vector<size_t> insertedCols(cols.size());
01280
01281 size_t iOffset=0;
01282 size_t iInserted=0;
01283 std::multiset<size_t>::const_iterator itInserted=rows.begin();
01284 for (size_t i=0;i<newRows;++i) {
01285 if (itInserted==rows.end()) rowsOffset[iOffset++]=i;
01286 else if (*itInserted<=iOffset) {
01287 insertedRows[iInserted++]=i;
01288 itInserted++;
01289 } else rowsOffset[iOffset++]=i;
01290 }
01291 iOffset=0;
01292 iInserted=0;
01293 itInserted=cols.begin();
01294 for (size_t i=0;i<newCols;++i) {
01295 if (itInserted==cols.end()) colsOffset[iOffset++]=i;
01296 else if (*itInserted<=iOffset) {
01297 insertedCols[iInserted++]=i;
01298 itInserted++;
01299 } else colsOffset[iOffset++]=i;
01300 }
01301
01302 T **newVal=static_cast<T **>(mrpt::system::os::aligned_calloc(sizeof(T *)*newRows,16));
01303 size_t rowSize=sizeof(T)*newCols;
01304 for (size_t i=0;i<newRows;++i) newVal[i]=static_cast<T *>(mrpt::system::os::aligned_calloc(rowSize,16));
01305
01306 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];
01307
01308 for (size_t i=0;i<m_Rows;++i) for (size_t j=0;j<insertedCols.size();++j) newVal[rowsOffset[i]][insertedCols[j]]=defaultValue;
01309 for (size_t i=0;i<insertedRows.size();++i) for (size_t j=0;j<newCols;++j) newVal[insertedRows[i]][j]=defaultValue;
01310
01311 for (size_t i=0;i<m_Rows;++i) mrpt::system::os::aligned_free(m_Val[i]);
01312 mrpt::system::os::aligned_free(m_Val);
01313
01314 m_Val=newVal;
01315 m_Rows=newRows;
01316 m_Cols=newCols;
01317 }
01318
01319
01320
01321
01322
01323 template<size_t N,typename ReturnType> inline ReturnType getVicinity(size_t c,size_t r) const {
01324 return detail::getVicinity<CMatrixTemplate<T>,T,ReturnType,N>::get(c,r,*this);
01325 }
01326
01327
01328 };
01329
01330
01331 }
01332 }
01333
01334
01335 #endif