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/matrix_adaptors.h>
00037 #include <mrpt/math/CArray.h>
00038
00039 namespace mrpt
00040 {
00041 namespace math
00042 {
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 template <class T>
00060 class CMatrixTemplate
00061 {
00062 public:
00063
00064 typedef T value_type;
00065 typedef T& reference;
00066 typedef const T& const_reference;
00067 typedef std::size_t size_type;
00068 typedef std::ptrdiff_t difference_type;
00069
00070
00071 protected:
00072 T **m_Val;
00073 size_t m_Rows, m_Cols;
00074
00075
00076
00077 void realloc(size_t row, size_t col, bool newElementsToZero = false)
00078 {
00079 if (row!=m_Rows || col!=m_Cols || m_Val==NULL)
00080 {
00081 size_t r;
00082 bool doZeroColumns = newElementsToZero && (col>m_Cols);
00083 size_t sizeZeroColumns = sizeof(T)*(col-m_Cols);
00084
00085
00086 for (r=row;r<m_Rows;r++)
00087 mrpt::system::os::aligned_free( m_Val[r] );
00088
00089
00090 if (!row)
00091 { mrpt::system::os::aligned_free(m_Val); m_Val=NULL; }
00092 else m_Val = static_cast<T**> (mrpt::system::os::aligned_realloc(m_Val, sizeof(T*) * row, 16 ) );
00093
00094
00095 size_t row_size = col * sizeof(T);
00096
00097
00098 for (r=0;r<row;r++)
00099 {
00100 if (r<m_Rows)
00101 {
00102
00103 m_Val[r] = static_cast<T*> (mrpt::system::os::aligned_realloc( m_Val[r], row_size, 16));
00104
00105 if (doZeroColumns)
00106 {
00107
00108 ::memset(&m_Val[r][m_Cols],0,sizeZeroColumns);
00109 }
00110 }
00111 else
00112 {
00113
00114 m_Val[r] = static_cast<T*> ( mrpt::system::os::aligned_calloc( row_size, 16 ));
00115 }
00116 }
00117
00118 m_Rows = row;
00119 m_Cols = col;
00120 }
00121 }
00122
00123 public:
00124
00125
00126
00127 template<size_t N> inline void ASSERT_ENOUGHROOM(size_t r,size_t c) const {
00128 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00129 ASSERT_((r>=N)&&(r+N<getRowCount())&&(c>=N)&&(c+N<getColCount()));
00130 #endif
00131 }
00132
00133 void fillAll(const T &val) {
00134 for (size_t r=0;r<m_Rows;r++)
00135 for (size_t c=0;c<m_Cols;c++)
00136 m_Val[r][c]=val;
00137 }
00138
00139
00140 inline void swap(CMatrixTemplate<T> &o)
00141 {
00142 std::swap(m_Val, o.m_Val );
00143 std::swap(m_Rows, o.m_Rows );
00144 std::swap(m_Cols, o.m_Cols );
00145 }
00146
00147
00148 CMatrixTemplate (const CMatrixTemplate& m) : m_Val(NULL),m_Rows(0),m_Cols(0)
00149 {
00150 (*this) = m;
00151 }
00152
00153 CMatrixTemplate (size_t row = 1, size_t col = 1) : m_Val(NULL),m_Rows(0),m_Cols(0)
00154 {
00155 realloc(row,col);
00156 }
00157
00158
00159
00160 CMatrixTemplate (const CMatrixTemplate& m, const size_t cropRowCount, const size_t cropColCount) : m_Val(NULL),m_Rows(0),m_Cols(0)
00161 {
00162 ASSERT_(m.m_Rows>=cropRowCount)
00163 ASSERT_(m.m_Cols>=cropColCount)
00164 realloc( cropRowCount, cropColCount );
00165 for (size_t i=0; i < m_Rows; i++)
00166 for (size_t j=0; j < m_Cols; j++)
00167 m_Val[i][j] = m.m_Val[i][j];
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 template <typename V, size_t N>
00179 CMatrixTemplate (size_t row, size_t col, V (&theArray)[N] ) : m_Val(NULL),m_Rows(0),m_Cols(0)
00180 {
00181 MRPT_COMPILE_TIME_ASSERT(N!=0)
00182 realloc(row,col);
00183 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)))
00184 size_t idx=0;
00185 for (size_t i=0; i < m_Rows; i++)
00186 for (size_t j=0; j < m_Cols; j++)
00187 m_Val[i][j] = static_cast<T>(theArray[idx++]);
00188 }
00189
00190
00191
00192 template <typename V>
00193 CMatrixTemplate(size_t row, size_t col, const V &theVector ) : m_Val(NULL),m_Rows(0),m_Cols(0)
00194 {
00195 const size_t N = theVector.size();
00196 realloc(row,col);
00197 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)))
00198 typename V::const_iterator it = theVector.begin();
00199 for (size_t i=0; i < m_Rows; i++)
00200 for (size_t j=0; j < m_Cols; j++)
00201 m_Val[i][j] = static_cast<T>( *(it++) );
00202 }
00203
00204
00205 virtual ~CMatrixTemplate() { realloc(0,0); }
00206
00207
00208 CMatrixTemplate& operator = (const CMatrixTemplate& m)
00209 {
00210 realloc( m.m_Rows, m.m_Cols );
00211 for (size_t i=0; i < m_Rows; i++)
00212 for (size_t j=0; j < m_Cols; j++)
00213 m_Val[i][j] = m.m_Val[i][j];
00214 return *this;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 template <typename V, size_t N>
00228 CMatrixTemplate& operator = (V (&theArray)[N] )
00229 {
00230 MRPT_COMPILE_TIME_ASSERT(N!=0)
00231 if (m_Rows*m_Cols != N)
00232 {
00233 THROW_EXCEPTION(format("Mismatch between matrix size %lu x %lu and array of length %lu",m_Rows,m_Cols,N))
00234 }
00235 size_t idx=0;
00236 for (size_t i=0; i < m_Rows; i++)
00237 for (size_t j=0; j < m_Cols; j++)
00238 m_Val[i][j] = static_cast<T>(theArray[idx++]);
00239 return *this;
00240 }
00241
00242
00243
00244
00245 inline size_t getRowCount() const { return m_Rows; }
00246
00247
00248
00249
00250 inline size_t getColCount() const { return m_Cols; }
00251
00252
00253 inline CMatrixTemplateSize size() const
00254 {
00255 CMatrixTemplateSize dims;
00256 dims[0]=m_Rows;
00257 dims[1]=m_Cols;
00258 return dims;
00259 }
00260
00261
00262 void setSize(size_t row, size_t col,bool zeroNewElements=false)
00263 {
00264 realloc(row,col,zeroNewElements);
00265 }
00266
00267
00268 inline void resize(const CMatrixTemplateSize &siz,bool zeroNewElements=false)
00269 {
00270 setSize(siz[0],siz[1],zeroNewElements);
00271 }
00272
00273
00274
00275 inline T& operator () (size_t row, size_t col)
00276 {
00277 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00278 if (row >= m_Rows || col >= m_Cols)
00279 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)) );
00280 #endif
00281 return m_Val[row][col];
00282 }
00283
00284
00285
00286 inline const T &operator () (size_t row, size_t col) const
00287 {
00288 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00289 if (row >= m_Rows || col >= m_Cols)
00290 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)) );
00291 #endif
00292 return m_Val[row][col];
00293 }
00294
00295
00296
00297
00298 inline T& operator () (size_t ith)
00299 {
00300 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00301 ASSERT_(m_Rows==1 || m_Cols==1);
00302 #endif
00303 if (m_Rows==1)
00304 {
00305
00306 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00307 if (ith >= m_Cols)
00308 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00309 #endif
00310 return m_Val[0][ith];
00311 }
00312 else
00313 {
00314
00315 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00316 if (ith >= m_Rows)
00317 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00318 #endif
00319 return m_Val[ith][0];
00320 }
00321 }
00322
00323
00324
00325
00326 inline T operator () (size_t ith) const
00327 {
00328 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00329 ASSERT_(m_Rows==1 || m_Cols==1);
00330 #endif
00331 if (m_Rows==1)
00332 {
00333
00334 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00335 if (ith >= m_Cols)
00336 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00337 #endif
00338 return m_Val[0][ith];
00339 }
00340 else
00341 {
00342
00343 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00344 if (ith >= m_Rows)
00345 THROW_EXCEPTION_CUSTOM_MSG1( "Index %u out of range!",static_cast<unsigned>(ith) );
00346 #endif
00347 return m_Val[ith][0];
00348 }
00349 }
00350
00351
00352
00353 inline void set_unsafe(size_t row, size_t col,const T &v)
00354 {
00355 #ifdef _DEBUG
00356 if (row >= m_Rows || col >= m_Cols)
00357 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)) );
00358 #endif
00359 m_Val[row][col] = v;
00360 }
00361
00362
00363
00364 inline const T &get_unsafe(size_t row, size_t col) const
00365 {
00366 #ifdef _DEBUG
00367 if (row >= m_Rows || col >= m_Cols)
00368 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)) );
00369 #endif
00370 return m_Val[row][col];
00371 }
00372
00373
00374
00375 inline T &get_unsafe(size_t row,size_t col)
00376 {
00377 #ifdef _DEBUG
00378 if (row >= m_Rows || col >= m_Cols)
00379 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)) );
00380 #endif
00381 return m_Val[row][col];
00382 }
00383
00384
00385
00386 inline T* get_unsafe_row(size_t row)
00387 {
00388 #ifdef _DEBUG
00389 if (row >= m_Rows)
00390 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)) );
00391 #endif
00392 return m_Val[row];
00393 }
00394
00395
00396
00397 inline const T* get_unsafe_row(size_t row) const {
00398 return m_Val[row];
00399 }
00400
00401
00402
00403 inline CMatrixTemplate<T> operator() (const size_t row1,const size_t row2,const size_t col1,const size_t col2) const {
00404 CMatrixTemplate<T> val(0,0);
00405 extractSubmatrix(row1,row2,col1,col2,val);
00406 return val;
00407 }
00408
00409
00410
00411
00412 void extractSubmatrix(const size_t row1,const size_t row2,const size_t col1,const size_t col2,CMatrixTemplate<T> &out) const
00413 {
00414 size_t nrows=row2-row1+1;
00415 size_t ncols=col2-col1+1;
00416 if (nrows<=0||ncols<=0) {
00417 out.realloc(0,0);
00418 return;
00419 }
00420 if (row1<0||row2>=m_Rows||col1<0||col2>=m_Cols) THROW_EXCEPTION("Indices out of range!");
00421 out.realloc(nrows,ncols);
00422 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];
00423 }
00424
00425 template <class Derived>
00426 void extractSubmatrix(const size_t row1,const size_t row2,const size_t col1,const size_t col2,Eigen::MatrixBase<Derived> &out) const
00427 {
00428 size_t nrows=row2-row1+1;
00429 size_t ncols=col2-col1+1;
00430 if (nrows<=0||ncols<=0) {
00431 out = typename Eigen::MatrixBase<Derived>::PlainObject();
00432 return;
00433 }
00434 if (row1<0||row2>=m_Rows||col1<0||col2>=m_Cols) THROW_EXCEPTION("Indices out of range!");
00435 out.resize(nrows,ncols);
00436 for (size_t i=0;i<nrows;i++) for (size_t j=0;j<ncols;j++) out.coeffRef(i,j)=m_Val[i+row1][j+col1];
00437 }
00438
00439
00440
00441
00442
00443
00444
00445 inline void extractRows(size_t firstRow,size_t lastRow,CMatrixTemplate<T> &out) const {
00446 out.setSize(lastRow-firstRow+1,m_Cols);
00447 detail::extractMatrix(*this,firstRow,0,out);
00448 }
00449
00450
00451
00452
00453
00454
00455 inline void extractColumns(size_t firstCol,size_t lastCol,CMatrixTemplate<T> &out) const {
00456 out.setSize(m_Rows,lastCol-firstCol+1);
00457 detail::extractMatrix(*this,0,firstCol,out);
00458 }
00459
00460
00461
00462
00463 void extractCol(size_t nCol, std::vector<T> &out, int startingRow = 0) const
00464 {
00465 size_t i,n;
00466 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00467 if (nCol>=m_Cols)
00468 THROW_EXCEPTION("extractCol: Column index out of bounds");
00469 #endif
00470
00471 n = m_Rows - startingRow;
00472 out.resize( n );
00473
00474 for (i=0;i<n;i++)
00475 out[i] = m_Val[i+startingRow][nCol];
00476 }
00477
00478
00479
00480
00481 void extractCol(size_t nCol, CMatrixTemplate<T> &out, int startingRow = 0) const
00482 {
00483 size_t i,n;
00484 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00485 if (nCol>=m_Cols)
00486 THROW_EXCEPTION("extractCol: Column index out of bounds");
00487 #endif
00488
00489 n = m_Rows - startingRow;
00490 out.setSize(n,1);
00491
00492 for (i=0;i<n;i++)
00493 out(i,0) = m_Val[i+startingRow][nCol];
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 void appendRow(const std::vector<T> &in)
00510 {
00511 size_t i,n, row;
00512
00513 n = m_Cols;
00514 row = m_Rows;
00515
00516 if (m_Cols==0 || m_Rows==0)
00517 {
00518 ASSERT_(!in.empty());
00519 n=m_Cols=in.size();
00520 }
00521 else
00522 {
00523 ASSERT_(in.size()==m_Cols);
00524 }
00525
00526 realloc( row+1,n );
00527
00528 for (i=0;i<n;i++)
00529 m_Val[row][i] = in[i];
00530 }
00531
00532
00533
00534
00535
00536
00537
00538 void appendCol(const std::vector<T> &in) {
00539 size_t r=m_Rows,c=m_Cols;
00540 if (m_Cols==0||m_Rows==0) {
00541 ASSERT_(!in.empty());
00542 r=in.size();
00543 c=0;
00544 } else ASSERT_(in.size()==m_Rows);
00545 realloc(r,c+1);
00546 for (size_t i=0;i<m_Rows;i++) m_Val[i][m_Cols-1]=in[i];
00547 }
00548
00549
00550
00551
00552
00553 void insertCol(size_t nCol, const std::vector<T> &in)
00554 {
00555 if (nCol>=m_Cols) THROW_EXCEPTION("insertCol: Row index out of bounds");
00556
00557 size_t n = in.size();
00558 ASSERT_( m_Rows >= in.size() );
00559
00560 for (size_t i=0;i<n;i++)
00561 m_Val[i][nCol] = in[i];
00562 }
00563
00564
00565
00566 void getAsVector(std::vector<T> &out) const {
00567 out.clear();
00568 out.reserve(m_Rows*m_Cols);
00569 for (size_t i=0;i<m_Rows;i++) out.insert(out.end(),&(m_Val[i][0]),&(m_Val[i][m_Cols]));
00570 }
00571
00572 };
00573
00574
00575 }
00576 }
00577
00578
00579 #endif