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 CMatrixFixedNumeric_H
00029 #define CMatrixFixedNumeric_H
00030
00031 #include <mrpt/math/CArray.h>
00032 #include <mrpt/math/math_frwds.h>
00033 #include <mrpt/math/matrices_metaprogramming.h>
00034 #include <mrpt/math/CMatrixViews.h>
00035
00036 namespace mrpt
00037 {
00038 namespace math
00039 {
00040 using namespace mrpt::system;
00041 using namespace mrpt::poses;
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 template <typename T,size_t NROWS,size_t NCOLS>
00054 class CMatrixFixedNumeric
00055 {
00056 public:
00057 typedef CArray<T,NROWS*NCOLS> array_type;
00058
00059
00060 typedef T value_type;
00061 typedef T& reference;
00062 typedef const T& const_reference;
00063 typedef std::size_t size_type;
00064 typedef std::ptrdiff_t difference_type;
00065
00066
00067 typedef CMatrixFixedNumeric<T,NROWS,NCOLS> mrpt_autotype;
00068 DECLARE_MRPT_CONTAINER_TYPES
00069 DECLARE_MRPT_CONTAINER_IS_MATRIX_FIXED(NROWS,NCOLS)
00070
00071 DECLARE_COMMON_MATRIX_MEMBERS(T)
00072
00073
00074
00075
00076 typedef typename array_type::iterator iterator;
00077 typedef typename array_type::const_iterator const_iterator;
00078 typedef typename array_type::reverse_iterator reverse_iterator;
00079 typedef typename array_type::const_reverse_iterator const_reverse_iterator;
00080
00081 inline iterator begin() { return m_Val.begin(); }
00082 inline iterator end() { return m_Val.end(); }
00083 inline const_iterator begin() const { return m_Val.begin(); }
00084 inline const_iterator end() const { return m_Val.end(); }
00085
00086 inline reverse_iterator rbegin() { return m_Val.rbegin(); }
00087 inline reverse_iterator rend() { return m_Val.rend(); }
00088 inline const_reverse_iterator rbegin() const { return m_Val.rbegin(); }
00089 inline const_reverse_iterator rend() const { return m_Val.rend(); }
00090
00091
00092
00093
00094
00095 #if MRPT_HAS_SSE2 && defined(MRPT_USE_SSE2)
00096 MRPT_ALIGN16
00097 #endif
00098 array_type m_Val;
00099
00100 public:
00101
00102 CMatrixFixedNumeric() {
00103 #if defined(_DEBUG) && MRPT_HAS_SSE2 && defined(MRPT_USE_SSE2)
00104 if ((uintptr_t(m_Val) & 0x0f) != 0 )
00105 THROW_EXCEPTION("16-unaligned memory!")
00106 #endif
00107 if (NROWS*NCOLS) ::memset(&m_Val[0],0,sizeof(T)*NROWS*NCOLS);
00108 }
00109
00110
00111
00112
00113 CMatrixFixedNumeric(bool ,bool, bool ) {
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 template <typename V, size_t N>
00125 CMatrixFixedNumeric ( V (&theArray)[N] )
00126 {
00127 MRPT_COMPILE_TIME_ASSERT(N!=0)
00128 MRPT_COMPILE_TIME_ASSERT(N==NROWS * NCOLS)
00129 if (sizeof(V)==sizeof(T))
00130 ::memcpy(&m_Val[0],theArray,sizeof(m_Val));
00131 else
00132 for (size_t i=0;i<N;i++)
00133 m_Val[i] = static_cast<T>(theArray[i]);
00134 }
00135
00136
00137
00138 template <size_t N,size_t M>
00139 explicit CMatrixFixedNumeric(const CMatrixFixedNumeric<T,N,M> &B)
00140 {
00141 ::memset(&m_Val[0],0,sizeof(m_Val));
00142 const size_t nr = std::min(NROWS,N);
00143 const size_t nc = std::min(NCOLS,M);
00144 for (size_t r=0;r<nr;r++)
00145 ::memcpy(&m_Val[0]+NCOLS*r, &B.m_Val[0]+M*r, sizeof(T)*nc );
00146 }
00147
00148
00149
00150 template <typename R>
00151 explicit CMatrixFixedNumeric(const CMatrixFixedNumeric<R,NROWS,NCOLS> &B)
00152 {
00153 for (size_t r=0;r<NROWS;r++)
00154 for (size_t c=0;c<NCOLS;c++)
00155 get_unsafe(r,c) = static_cast<T>( B.get_unsafe(r,c) );
00156 }
00157
00158
00159
00160
00161 template <typename R>
00162 explicit CMatrixFixedNumeric(const CMatrixTemplate<R> &B, bool clipToFixedMatrixSize = false )
00163 {
00164 if (!clipToFixedMatrixSize) {
00165 *this = B;
00166 }
00167 else
00168 {
00169 ::memset(&m_Val[0],0,sizeof(m_Val));
00170 const size_t nr = std::min(NROWS,B.getRowCount());
00171 const size_t nc = std::min(NCOLS,B.getColCount());
00172 for (size_t r=0;r<nr;r++)
00173 for (size_t c=0;c<nc;c++)
00174 get_unsafe(r,c) = B.get_unsafe(r,c);
00175 }
00176 }
00177
00178
00179
00180
00181 CMatrixFixedNumeric<T,NROWS,NCOLS>& operator =(const CMatrixTemplate<T> &B)
00182 {
00183 ASSERT_( NROWS==B.getRowCount() )
00184 ASSERT_( NCOLS==B.getColCount() )
00185 for (size_t r=0;r<NROWS;r++)
00186 ::memcpy(&m_Val[0]+r*NCOLS, B.get_unsafe_row(r), sizeof(T)*NCOLS);
00187 return *this;
00188 }
00189
00190
00191
00192
00193 template <typename R>
00194 CMatrixFixedNumeric<T,NROWS,NCOLS>& operator =(const CMatrixTemplate<R> &B)
00195 {
00196 ASSERT_( NROWS==B.getRowCount() )
00197 ASSERT_( NCOLS==B.getColCount() )
00198 for (size_t r=0;r<NROWS;r++)
00199 for (size_t c=0;c<NCOLS;c++)
00200 get_unsafe(r,c) = B.get_unsafe(r,c);
00201 return *this;
00202 }
00203
00204
00205 static inline size_t getRowCount() { return NROWS; }
00206
00207
00208 static inline size_t getColCount() { return NCOLS; }
00209
00210
00211 static inline const CMatrixTemplateSize & size() {
00212 static size_t dims_arr[] = {NROWS, NCOLS};
00213 static const CMatrixTemplateSize dims(dims_arr);
00214 return dims;
00215 }
00216
00217
00218 static inline void setSize(const size_t nRows, const size_t nCols) {
00219 if (nRows!=NROWS || nCols!=NCOLS)
00220 throw std::logic_error(format("Try to change the size of a %ux%u fixed-sized matrix to %ux%u.",static_cast<unsigned>(NROWS),static_cast<unsigned>(NCOLS),static_cast<unsigned>(nRows),static_cast<unsigned>(nCols)));
00221 }
00222
00223 static inline void resize(const size_t nRows_times_nCols) {
00224 if (nRows_times_nCols!=NROWS*NCOLS)
00225 throw std::logic_error(format("Try to change the size of a %ux%u fixed-sized matrix to %u elements.",static_cast<unsigned>(NROWS),static_cast<unsigned>(NCOLS),static_cast<unsigned>(nRows_times_nCols)));
00226 }
00227
00228
00229
00230
00231
00232 CMatrixFixedNumeric(const CPoint2D &p) { matrixFromPoseOrPoint(*this,p); }
00233
00234 CMatrixFixedNumeric(const CPoint3D &p) { matrixFromPoseOrPoint(*this,p); }
00235
00236 CMatrixFixedNumeric(const CPose2D &p) { matrixFromPoseOrPoint(*this,p); }
00237
00238 CMatrixFixedNumeric(const CPose3D &p) { matrixFromPoseOrPoint(*this,p); }
00239
00240
00241 inline CMatrixFixedNumeric<T,NROWS,NCOLS> & operator = (const CPoint2D &p) {
00242 return matrixFromPoseOrPoint(*this,p);
00243 }
00244
00245 inline CMatrixFixedNumeric<T,NROWS,NCOLS> & operator = (const CPoint3D &p) {
00246 return matrixFromPoseOrPoint(*this,p);
00247 }
00248
00249 inline CMatrixFixedNumeric<T,NROWS,NCOLS> & operator = (const CPose2D &p) {
00250 return matrixFromPoseOrPoint(*this,p);
00251 }
00252
00253 inline CMatrixFixedNumeric<T,NROWS,NCOLS> & operator = (const CPose3D &p) {
00254 return matrixFromPoseOrPoint(*this,p);
00255 }
00256
00257
00258
00259
00260 inline void unit() {
00261 ::memset(&m_Val[0],0,sizeof(m_Val));
00262 for (size_t i=0;i<NROWS * NCOLS;i+=(NROWS+1))
00263 m_Val[i] = 1;
00264 }
00265
00266
00267 inline void zeros() {
00268 ::memset(&m_Val[0],0,sizeof(m_Val));
00269 }
00270
00271
00272 inline void zeros(size_t N, size_t M) {
00273 ASSERT_(N==NROWS && M==NCOLS);
00274 this->zeros();
00275 }
00276
00277
00278 inline T get_unsafe(const size_t row, const size_t col) const {
00279 #ifdef _DEBUG
00280 if (row >= NROWS || col >= NCOLS)
00281 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>(NROWS),static_cast<unsigned long>(NCOLS)) );
00282 #endif
00283 return m_Val[NCOLS*row+col];
00284 }
00285
00286
00287 inline T& get_unsafe(const size_t row, const size_t col) {
00288 #ifdef _DEBUG
00289 if (row >= NROWS || col >= NCOLS)
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>(NROWS),static_cast<unsigned long>(NCOLS)) );
00291 #endif
00292 return m_Val[NCOLS*row+col];
00293 }
00294
00295
00296 inline void set_unsafe(const size_t row, const size_t col, const T val) {
00297 #ifdef _DEBUG
00298 if (row >= NROWS || col >= NCOLS)
00299 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>(NROWS),static_cast<unsigned long>(NCOLS)) );
00300 #endif
00301 m_Val[NCOLS*row+col] = val;
00302 }
00303
00304
00305
00306 inline T& operator () (const size_t row, const size_t col)
00307 {
00308 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00309 if (row >= NROWS || col >= NCOLS)
00310 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>(NROWS),static_cast<unsigned long>(NCOLS)) );
00311 #endif
00312 return m_Val[NCOLS*row+col];
00313 }
00314
00315
00316
00317 inline T operator () (const size_t row, const size_t col) const
00318 {
00319 #if defined(_DEBUG) || (MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00320 if (row >= NROWS || col >= NCOLS)
00321 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>(NROWS),static_cast<unsigned long>(NCOLS)) );
00322 #endif
00323 return m_Val[NCOLS*row+col];
00324 }
00325
00326
00327
00328
00329 std::string inMatlabFormat() const
00330 {
00331 std::stringstream s;
00332 s << "[";
00333 s << std::scientific;
00334 for (size_t i=0;i<NROWS;i++)
00335 {
00336 for (size_t j=0;j<NCOLS;j++)
00337 s << get_unsafe(i,j) << " ";
00338 if (i<NROWS-1) s << ";";
00339 }
00340 s << "]";
00341 return s.str();
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 bool fromMatlabStringFormat(const std::string &s)
00356 {
00357 CMatrixTemplate<T> M;
00358 if (!M.fromMatlabStringFormat(s)) return false;
00359 if (M.getColCount()!=NCOLS || M.getRowCount()!=NROWS) return false;
00360 *this = M;
00361 return true;
00362 }
00363
00364
00365 void force_symmetry() {
00366 for (size_t i=0;i<NROWS;i++)
00367 for (size_t j=i+1;j<NCOLS;j++)
00368 get_unsafe(i,j) = get_unsafe(j,i);
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378 void loadFromTextFile(const std::string &file)
00379 {
00380
00381 std::ifstream f(file.c_str());
00382 if (f.fail()) THROW_EXCEPTION_CUSTOM_MSG1("loadFromTextFile: can't open file:'%s'",file.c_str());
00383
00384 std::string str;
00385 std::vector<double> fil(512);
00386
00387 const char *ptr;
00388 char *ptrEnd;
00389 size_t i;
00390 size_t nRows = 0;
00391
00392 while ( !f.eof() )
00393 {
00394 std::getline(f,str);
00395
00396 if (str.size() && str[0]!='#' && str[0]!='%')
00397 {
00398
00399 ptr = str.c_str();
00400
00401 ptrEnd = NULL;
00402 i=0;
00403
00404
00405 while ( ptr[0] && ptr!=ptrEnd )
00406 {
00407
00408 while (ptr[0] && (ptr[0]==' ' || ptr[0]=='\t' || ptr[0]=='\r' || ptr[0]=='\n'))
00409 ptr++;
00410
00411 if (fil.size()<=i) fil.resize(fil.size()+512);
00412
00413
00414 fil[i] = strtod(ptr,&ptrEnd);
00415
00416
00417 if (ptr!=ptrEnd)
00418 {
00419 i++;
00420 ptr = ptrEnd;
00421 ptrEnd = NULL;
00422 }
00423 };
00424
00425
00426 if (i!=NCOLS) THROW_EXCEPTION(format("The matrix in the text file does not match fixed matrix size %ux%u",static_cast<unsigned>(NROWS),static_cast<unsigned>(NCOLS)));
00427 if (nRows>=NROWS) THROW_EXCEPTION(format("The matrix in the text file does not match fixed matrix size %ux%u",static_cast<unsigned>(NROWS),static_cast<unsigned>(NCOLS)));
00428
00429
00430 for (size_t j=0;j<NCOLS;j++)
00431 get_unsafe(nRows,j) = static_cast<T>(fil[j]);
00432
00433 nRows++;
00434 }
00435 }
00436
00437
00438 if (!nRows)
00439 THROW_EXCEPTION("loadFromTextFile: Error loading from text file");
00440 }
00441
00442
00443
00444 void multiplyColumnByScalar(
00445 size_t c,
00446 T scalar)
00447 {
00448 ASSERT_( c < NCOLS );
00449 T *c1 = &m_Val[0]+c;
00450 for(unsigned int k = 0; k < NCOLS; k++)
00451 {
00452 *c1 *= scalar;
00453 c1 += NCOLS;
00454 }
00455 }
00456
00457 inline void swapRows(size_t i1,size_t i2)
00458 {
00459 ASSERT_( i1 < NROWS && i2 < NROWS );
00460 T tmprow[NCOLS];
00461 ::memcpy(tmprow, &m_Val[0]+i1*NCOLS, sizeof(tmprow));
00462 ::memcpy(&m_Val[0]+i1*NCOLS,&m_Val[0]+i2*NCOLS, sizeof(tmprow));
00463 ::memcpy(&m_Val[0]+i2*NCOLS,tmprow, sizeof(tmprow));
00464 }
00465
00466 void swapCols(size_t i1,size_t i2)
00467 {
00468 ASSERT_( i1 < NCOLS && i2 < NCOLS );
00469 T *c1 = &m_Val[0]+i1, *c2 = &m_Val[0]+i2;
00470
00471 for( unsigned int k = 0; k < NROWS; k++)
00472 {
00473 T aux = *c1;
00474 *c1 = *c2;
00475 *c2 = aux;
00476
00477 c1 += NCOLS;
00478 c2 += NCOLS;
00479 }
00480 }
00481
00482 template<size_t N> inline void ASSERT_ENOUGHROOM(size_t r,size_t c) const {
00483 #if defined(_DEBUG)||(MRPT_ALWAYS_CHECKS_DEBUG_MATRICES)
00484 ASSERT_((r>=N)&&(r<NROWS-N)&&(c>=N)&&(c<NCOLS-N));
00485 #endif
00486 }
00487
00488 template<size_t N,typename ReturnType> inline ReturnType getVicinity(size_t c,size_t r) const {
00489 return detail::getVicinity<CMatrixFixedNumeric<T,NROWS,NCOLS>,T,ReturnType,N>::get(c,r,*this);
00490 }
00491
00492 };
00493
00494
00495
00496 typedef CMatrixFixedNumeric<double,2,2> CMatrixDouble22;
00497 typedef CMatrixFixedNumeric<double,3,3> CMatrixDouble33;
00498 typedef CMatrixFixedNumeric<double,4,4> CMatrixDouble44;
00499 typedef CMatrixFixedNumeric<double,6,6> CMatrixDouble66;
00500 typedef CMatrixFixedNumeric<double,1,3> CMatrixDouble13;
00501 typedef CMatrixFixedNumeric<double,3,1> CMatrixDouble31;
00502 typedef CMatrixFixedNumeric<double,1,2> CMatrixDouble12;
00503 typedef CMatrixFixedNumeric<double,2,1> CMatrixDouble21;
00504 typedef CMatrixFixedNumeric<double,6,1> CMatrixDouble61;
00505 typedef CMatrixFixedNumeric<double,1,6> CMatrixDouble16;
00506
00507 typedef CMatrixFixedNumeric<float,2,2> CMatrixFloat22;
00508 typedef CMatrixFixedNumeric<float,3,3> CMatrixFloat33;
00509 typedef CMatrixFixedNumeric<float,4,4> CMatrixFloat44;
00510 typedef CMatrixFixedNumeric<float,6,6> CMatrixFloat66;
00511 typedef CMatrixFixedNumeric<float,1,3> CMatrixFloat13;
00512 typedef CMatrixFixedNumeric<float,3,1> CMatrixFloat31;
00513 typedef CMatrixFixedNumeric<float,1,2> CMatrixFloat12;
00514 typedef CMatrixFixedNumeric<float,2,1> CMatrixFloat21;
00515 typedef CMatrixFixedNumeric<float,6,1> CMatrixFloat61;
00516 typedef CMatrixFixedNumeric<float,1,6> CMatrixFloat16;
00517
00518
00519
00520
00521
00522
00523
00524 template <typename T,size_t NROWS,size_t NCOLS> CMatrixFixedNumeric<T,NROWS,NCOLS> & matrixFromPoseOrPoint(CMatrixFixedNumeric<T,NROWS,NCOLS>&M, const CPoint2D &p) { THROW_EXCEPTION("Matrix of the wrong size") }
00525 template <typename T,size_t NROWS,size_t NCOLS> CMatrixFixedNumeric<T,NROWS,NCOLS> & matrixFromPoseOrPoint(CMatrixFixedNumeric<T,NROWS,NCOLS>&M, const CPoint3D &p) { THROW_EXCEPTION("Matrix of the wrong size") }
00526 template <typename T,size_t NROWS,size_t NCOLS> CMatrixFixedNumeric<T,NROWS,NCOLS> & matrixFromPoseOrPoint(CMatrixFixedNumeric<T,NROWS,NCOLS>&M, const CPose2D &p) { THROW_EXCEPTION("Matrix of the wrong size") }
00527 template <typename T,size_t NROWS,size_t NCOLS> CMatrixFixedNumeric<T,NROWS,NCOLS> & matrixFromPoseOrPoint(CMatrixFixedNumeric<T,NROWS,NCOLS>&M, const CPose3D &p) { THROW_EXCEPTION("Matrix of the wrong size") }
00528
00529 template <> CMatrixDouble21 & matrixFromPoseOrPoint(CMatrixDouble21 &M, const CPoint2D &p);
00530 template <> CMatrixDouble31 & matrixFromPoseOrPoint(CMatrixDouble31 &M, const CPoint3D &p);
00531 template <> CMatrixDouble31 & matrixFromPoseOrPoint(CMatrixDouble31 &M, const CPose2D &p);
00532 template <> CMatrixDouble61 & matrixFromPoseOrPoint(CMatrixDouble61 &M, const CPose3D &p);
00533 template <> CMatrixDouble12 & matrixFromPoseOrPoint(CMatrixDouble12 &M, const CPoint2D &p);
00534 template <> CMatrixDouble13 & matrixFromPoseOrPoint(CMatrixDouble13 &M, const CPoint3D &p);
00535 template <> CMatrixDouble13 & matrixFromPoseOrPoint(CMatrixDouble13 &M, const CPose2D &p);
00536 template <> CMatrixDouble16 & matrixFromPoseOrPoint(CMatrixDouble16 &M, const CPose3D &p);
00537
00538
00539
00540 namespace detail {
00541
00542
00543
00544 template<typename T,size_t D> class VicinityTraits<CMatrixFixedNumeric<T,D,D> > {
00545 public:
00546 inline static void initialize(CMatrixFixedNumeric<T,D,D> &mat,size_t N) {
00547 ASSERT_(N==D);
00548 }
00549 inline static void insertInContainer(CMatrixFixedNumeric<T,D,D> &mat,size_t r,size_t c,const T &t) {
00550 mat.get_unsafe(r,c)=t;
00551 }
00552 };
00553 }
00554
00555
00556 }
00557 }
00558
00559 #endif