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