Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Eurobot2013 by
Matrix.h
00001 /* 00002 * Tiny Vector Matrix Library 00003 * Dense Vector Matrix Libary of Tiny size using Expression Templates 00004 * 00005 * Copyright (C) 2001 - 2007 Olaf Petzold <opetzold@users.sourceforge.net> 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 * 00021 * $Id: Matrix.h,v 1.58 2007-06-23 15:58:58 opetzold Exp $ 00022 */ 00023 00024 #ifndef TVMET_MATRIX_H 00025 #define TVMET_MATRIX_H 00026 00027 #include <iterator> // reverse_iterator 00028 00029 #include <tvmet/tvmet.h> 00030 #include <tvmet/TypePromotion.h> 00031 #include <tvmet/CommaInitializer.h> 00032 #include <tvmet/RunTimeError.h> 00033 00034 #include <tvmet/xpr/Matrix.h> 00035 #include <tvmet/xpr/MatrixRow.h> 00036 #include <tvmet/xpr/MatrixCol.h> 00037 #include <tvmet/xpr/MatrixDiag.h> 00038 00039 namespace tvmet { 00040 00041 00042 /* forwards */ 00043 template<class T, std::size_t Rows, std::size_t Cols> class Matrix; 00044 template<class T, 00045 std::size_t RowsBgn, std::size_t RowsEnd, 00046 std::size_t ColsBgn, std::size_t ColsEnd, 00047 std::size_t RowStride, std::size_t ColStride /*=1*/> 00048 class MatrixSliceConstReference; // unused here; for me only 00049 00050 00051 /** 00052 * \class MatrixConstReference Matrix.h "tvmet/Matrix.h" 00053 * \brief value iterator for ET 00054 */ 00055 template<class T, std::size_t NRows, std::size_t NCols> 00056 class MatrixConstReference 00057 : public TvmetBase < MatrixConstReference<T, NRows, NCols> > 00058 { 00059 public: 00060 typedef T value_type; 00061 typedef T* pointer; 00062 typedef const T* const_pointer; 00063 00064 /** Dimensions. */ 00065 enum { 00066 Rows = NRows, /**< Number of rows. */ 00067 Cols = NCols, /**< Number of cols. */ 00068 Size = Rows * Cols /**< Complete Size of Matrix. */ 00069 }; 00070 00071 public: 00072 /** Complexity counter. */ 00073 enum { 00074 ops = Rows * Cols 00075 }; 00076 00077 private: 00078 MatrixConstReference(); 00079 MatrixConstReference& operator=(const MatrixConstReference&); 00080 00081 public: 00082 /** Constructor. */ 00083 explicit MatrixConstReference(const Matrix<T, Rows, Cols>& rhs) 00084 : m_data(rhs.data()) 00085 { } 00086 00087 /** Constructor by a given memory pointer. */ 00088 explicit MatrixConstReference(const_pointer data) 00089 : m_data(data) 00090 { } 00091 00092 public: // access operators 00093 /** access by index. */ 00094 value_type operator()(std::size_t i, std::size_t j) const { 00095 TVMET_RT_CONDITION((i < Rows) && (j < Cols), "MatrixConstReference Bounce Violation") 00096 return m_data[i * Cols + j]; 00097 } 00098 00099 public: // debugging Xpr parse tree 00100 void print_xpr(std::ostream& os, std::size_t l=0) const { 00101 os << IndentLevel(l) 00102 << "MatrixConstReference[O=" << ops << "]<" 00103 << "T=" << typeid(value_type).name() << ">," 00104 << std::endl; 00105 } 00106 00107 private: 00108 const_pointer _tvmet_restrict m_data; 00109 }; 00110 00111 00112 /** 00113 * \class Matrix Matrix.h "tvmet/Matrix.h" 00114 * \brief A tiny matrix class. 00115 * 00116 * The array syntax A[j][j] isn't supported here. The reason is that 00117 * operator[] always takes exactly one parameter, but operator() can 00118 * take any number of parameters (in the case of a rectangular matrix, 00119 * two paramters are needed). Therefore the cleanest way to do it is 00120 * with operator() rather than with operator[]. \see C++ FAQ Lite 13.8 00121 */ 00122 template<class T, std::size_t NRows, std::size_t NCols> 00123 class Matrix 00124 { 00125 public: 00126 /** Data type of the tvmet::Matrix. */ 00127 typedef T value_type; 00128 00129 /** Reference type of the tvmet::Matrix data elements. */ 00130 typedef T& reference; 00131 00132 /** const reference type of the tvmet::Matrix data elements. */ 00133 typedef const T& const_reference; 00134 00135 /** STL iterator interface. */ 00136 typedef T* iterator; 00137 00138 /** STL const_iterator interface. */ 00139 typedef const T* const_iterator; 00140 00141 /** STL reverse iterator interface. */ 00142 typedef std::reverse_iterator<iterator> reverse_iterator; 00143 00144 /** STL const reverse iterator interface. */ 00145 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00146 00147 public: 00148 /** Dimensions. */ 00149 enum { 00150 Rows = NRows, /**< Number of rows. */ 00151 Cols = NCols, /**< Number of cols. */ 00152 Size = Rows * Cols /**< Complete Size of Matrix. */ 00153 }; 00154 00155 public: 00156 /** Complexity counter. */ 00157 enum { 00158 ops_assign = Rows * Cols, 00159 ops = ops_assign, 00160 use_meta = ops < TVMET_COMPLEXITY_M_ASSIGN_TRIGGER ? true : false 00161 }; 00162 00163 public: // STL interface 00164 /** STL iterator interface. */ 00165 iterator begin() { return m_data; } 00166 00167 /** STL iterator interface. */ 00168 iterator end() { return m_data + Size; } 00169 00170 /** STL const_iterator interface. */ 00171 const_iterator begin() const { return m_data; } 00172 00173 /** STL const_iterator interface. */ 00174 const_iterator end() const { return m_data + Size; } 00175 00176 /** STL reverse iterator interface reverse begin. */ 00177 reverse_iterator rbegin() { return reverse_iterator( end() ); } 00178 00179 /** STL const reverse iterator interface reverse begin. */ 00180 const_reverse_iterator rbegin() const { 00181 return const_reverse_iterator( end() ); 00182 } 00183 00184 /** STL reverse iterator interface reverse end. */ 00185 reverse_iterator rend() { return reverse_iterator( begin() ); } 00186 00187 /** STL const reverse iterator interface reverse end. */ 00188 const_reverse_iterator rend() const { 00189 return const_reverse_iterator( begin() ); 00190 } 00191 00192 /** The size of the matrix. */ 00193 static std::size_t size() { return Size; } 00194 00195 /** STL vector max_size() - returns allways rows()*cols(). */ 00196 static std::size_t max_size() { return Size; } 00197 00198 /** STL vector empty() - returns allways false. */ 00199 static bool empty() { return false; } 00200 00201 public: 00202 /** The number of rows of matrix. */ 00203 static std::size_t rows() { return Rows; } 00204 00205 /** The number of columns of matrix. */ 00206 static std::size_t cols() { return Cols; } 00207 00208 public: 00209 /** Default Destructor */ 00210 ~Matrix() { 00211 #if defined(TVMET_DYNAMIC_MEMORY) 00212 delete [] m_data; 00213 #endif 00214 } 00215 00216 /** Default Constructor. The allocated memory region isn't cleared. If you want 00217 a clean use the constructor argument zero. */ 00218 explicit Matrix() 00219 #if defined(TVMET_DYNAMIC_MEMORY) 00220 : m_data( new value_type[Size] ) 00221 #endif 00222 { } 00223 00224 /** Copy Constructor, not explicit! */ 00225 Matrix(const Matrix& rhs) 00226 #if defined(TVMET_DYNAMIC_MEMORY) 00227 : m_data( new value_type[Size] ) 00228 #endif 00229 { 00230 *this = XprMatrix<ConstReference, Rows, Cols>(rhs.const_ref()); 00231 } 00232 00233 /** 00234 * Constructor with STL iterator interface. The data will be copied into the matrix 00235 * self, there isn't any stored reference to the array pointer. 00236 */ 00237 template<class InputIterator> 00238 explicit Matrix(InputIterator first, InputIterator last) 00239 #if defined(TVMET_DYNAMIC_MEMORY) 00240 : m_data( new value_type[Size] ) 00241 #endif 00242 { 00243 TVMET_RT_CONDITION(static_cast<std::size_t>(std::distance(first, last)) <= Size, 00244 "InputIterator doesn't fits in size" ) 00245 std::copy(first, last, m_data); 00246 } 00247 00248 /** 00249 * Constructor with STL iterator interface. The data will be copied into the matrix 00250 * self, there isn't any stored reference to the array pointer. 00251 */ 00252 template<class InputIterator> 00253 explicit Matrix(InputIterator first, std::size_t sz) 00254 #if defined(TVMET_DYNAMIC_MEMORY) 00255 : m_data( new value_type[Size] ) 00256 #endif 00257 { 00258 TVMET_RT_CONDITION(sz <= Size, "InputIterator doesn't fits in size" ) 00259 std::copy(first, first + sz, m_data); 00260 } 00261 00262 /** Construct the matrix by value. */ 00263 explicit Matrix(value_type rhs) 00264 #if defined(TVMET_DYNAMIC_MEMORY) 00265 : m_data( new value_type[Size] ) 00266 #endif 00267 { 00268 typedef XprLiteral<value_type> expr_type; 00269 *this = XprMatrix<expr_type, Rows, Cols>(expr_type(rhs)); 00270 } 00271 00272 /** Construct a matrix by expression. */ 00273 template<class E> 00274 explicit Matrix(const XprMatrix<E, Rows, Cols>& e) 00275 #if defined(TVMET_DYNAMIC_MEMORY) 00276 : m_data( new value_type[Size] ) 00277 #endif 00278 { 00279 *this = e; 00280 } 00281 00282 /** assign a value_type on array, this can be used for a single value 00283 or a comma separeted list of values. */ 00284 CommaInitializer<Matrix, Size> operator=(value_type rhs) { 00285 return CommaInitializer<Matrix, Size>(*this, rhs); 00286 } 00287 00288 public: // access operators 00289 value_type* _tvmet_restrict data() { return m_data; } 00290 const value_type* _tvmet_restrict data() const { return m_data; } 00291 00292 public: // index access operators 00293 value_type& _tvmet_restrict operator()(std::size_t i, std::size_t j) { 00294 // Note: g++-2.95.3 does have problems on typedef reference 00295 TVMET_RT_CONDITION((i < Rows) && (j < Cols), "Matrix Bounce Violation") 00296 return m_data[i * Cols + j]; 00297 } 00298 00299 value_type operator()(std::size_t i, std::size_t j) const { 00300 TVMET_RT_CONDITION((i < Rows) && (j < Cols), "Matrix Bounce Violation") 00301 return m_data[i * Cols + j]; 00302 } 00303 00304 public: // ET interface 00305 typedef MatrixConstReference<T, Rows, Cols> ConstReference; 00306 00307 typedef MatrixSliceConstReference< 00308 T, 00309 0, Rows, 0, Cols, 00310 Rows, 1 00311 > SliceConstReference; 00312 00313 /** Return a const Reference of the internal data */ 00314 ConstReference const_ref() const { return ConstReference(*this); } 00315 00316 /** 00317 * Return a sliced const Reference of the internal data. 00318 * \note Doesn't work since isn't implemented, but it is in 00319 * progress. Therefore this is a placeholder. */ 00320 ConstReference const_sliceref() const { return SliceConstReference(*this); } 00321 00322 /** Return the vector as const expression. */ 00323 XprMatrix<ConstReference, Rows, Cols> as_expr() const { 00324 return XprMatrix<ConstReference, Rows, Cols>(this->const_ref()); 00325 } 00326 00327 private: 00328 /** Wrapper for meta assign. */ 00329 template<class Dest, class Src, class Assign> 00330 static inline 00331 void do_assign(dispatch<true>, Dest& dest, const Src& src, const Assign& assign_fn) { 00332 meta::Matrix<Rows, Cols, 0, 0>::assign(dest, src, assign_fn); 00333 } 00334 00335 /** Wrapper for loop assign. */ 00336 template<class Dest, class Src, class Assign> 00337 static inline 00338 void do_assign(dispatch<false>, Dest& dest, const Src& src, const Assign& assign_fn) { 00339 loop::Matrix<Rows, Cols>::assign(dest, src, assign_fn); 00340 } 00341 00342 private: 00343 /** assign this to a matrix of a different type T2 using 00344 the functional assign_fn. */ 00345 template<class T2, class Assign> 00346 void assign_to(Matrix<T2, Rows, Cols>& dest, const Assign& assign_fn) const { 00347 do_assign(dispatch<use_meta>(), dest, *this, assign_fn); 00348 } 00349 00350 public: // assign operations 00351 /** assign a given matrix of a different type T2 element wise 00352 to this matrix. The operator=(const Matrix&) is compiler 00353 generated. */ 00354 template<class T2> 00355 Matrix& operator=(const Matrix<T2, Rows, Cols>& rhs) { 00356 rhs.assign_to(*this, Fcnl_assign<value_type, T2>()); 00357 return *this; 00358 } 00359 00360 /** assign a given XprMatrix element wise to this matrix. */ 00361 template <class E> 00362 Matrix& operator=(const XprMatrix<E, Rows, Cols>& rhs) { 00363 rhs.assign_to(*this, Fcnl_assign<value_type, typename E::value_type>()); 00364 return *this; 00365 } 00366 00367 private: 00368 template<class Obj, std::size_t LEN> friend class CommaInitializer; 00369 00370 /** This is a helper for assigning a comma separated initializer 00371 list. It's equal to Matrix& operator=(value_type) which does 00372 replace it. */ 00373 Matrix& assign_value(value_type rhs) { 00374 typedef XprLiteral<value_type> expr_type; 00375 *this = XprMatrix<expr_type, Rows, Cols>(expr_type(rhs)); 00376 return *this; 00377 } 00378 00379 public: // math operators with scalars 00380 // NOTE: this meaning is clear - element wise ops even if not in ns element_wise 00381 Matrix& operator+=(value_type) TVMET_CXX_ALWAYS_INLINE; 00382 Matrix& operator-=(value_type) TVMET_CXX_ALWAYS_INLINE; 00383 Matrix& operator*=(value_type) TVMET_CXX_ALWAYS_INLINE; 00384 Matrix& operator/=(value_type) TVMET_CXX_ALWAYS_INLINE; 00385 00386 Matrix& operator%=(std::size_t) TVMET_CXX_ALWAYS_INLINE; 00387 Matrix& operator^=(std::size_t) TVMET_CXX_ALWAYS_INLINE; 00388 Matrix& operator&=(std::size_t) TVMET_CXX_ALWAYS_INLINE; 00389 Matrix& operator|=(std::size_t) TVMET_CXX_ALWAYS_INLINE; 00390 Matrix& operator<<=(std::size_t) TVMET_CXX_ALWAYS_INLINE; 00391 Matrix& operator>>=(std::size_t) TVMET_CXX_ALWAYS_INLINE; 00392 00393 public: // math operators with matrizes 00394 // NOTE: access using the operators in ns element_wise, since that's what is does 00395 template <class T2> Matrix& M_add_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00396 template <class T2> Matrix& M_sub_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00397 template <class T2> Matrix& M_mul_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00398 template <class T2> Matrix& M_div_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00399 template <class T2> Matrix& M_mod_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00400 template <class T2> Matrix& M_xor_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00401 template <class T2> Matrix& M_and_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00402 template <class T2> Matrix& M_or_eq (const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00403 template <class T2> Matrix& M_shl_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00404 template <class T2> Matrix& M_shr_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00405 00406 public: // math operators with expressions 00407 // NOTE: access using the operators in ns element_wise, since that's what is does 00408 template <class E> Matrix& M_add_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00409 template <class E> Matrix& M_sub_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00410 template <class E> Matrix& M_mul_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00411 template <class E> Matrix& M_div_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00412 template <class E> Matrix& M_mod_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00413 template <class E> Matrix& M_xor_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00414 template <class E> Matrix& M_and_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00415 template <class E> Matrix& M_or_eq (const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00416 template <class E> Matrix& M_shl_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00417 template <class E> Matrix& M_shr_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00418 00419 public: // aliased math operators with expressions 00420 template <class T2> Matrix& alias_assign(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00421 template <class T2> Matrix& alias_add_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00422 template <class T2> Matrix& alias_sub_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00423 template <class T2> Matrix& alias_mul_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00424 template <class T2> Matrix& alias_div_eq(const Matrix<T2, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00425 00426 template <class E> Matrix& alias_assign(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00427 template <class E> Matrix& alias_add_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00428 template <class E> Matrix& alias_sub_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00429 template <class E> Matrix& alias_mul_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00430 template <class E> Matrix& alias_div_eq(const XprMatrix<E, Rows, Cols>&) TVMET_CXX_ALWAYS_INLINE; 00431 00432 public: // io 00433 /** Structure for info printing as Matrix<T, Rows, Cols>. */ 00434 struct Info : public TvmetBase<Info> { 00435 std::ostream& print_xpr(std::ostream& os) const { 00436 os << "Matrix<T=" << typeid(value_type).name() 00437 << ", R=" << Rows << ", C=" << Cols << ">"; 00438 return os; 00439 } 00440 }; 00441 00442 /** Get an info object of this matrix. */ 00443 static Info info() { return Info(); } 00444 00445 /** Member function for expression level printing. */ 00446 std::ostream& print_xpr(std::ostream& os, std::size_t l=0) const; 00447 00448 /** Member function for printing internal data. */ 00449 std::ostream& print_on(std::ostream& os) const; 00450 00451 private: 00452 /** The data of matrix self. */ 00453 #if defined(TVMET_DYNAMIC_MEMORY) 00454 value_type* m_data; 00455 #else 00456 value_type m_data[Size]; 00457 #endif 00458 }; 00459 00460 00461 } // namespace tvmet 00462 00463 #include <tvmet/MatrixImpl.h> 00464 #include <tvmet/MatrixFunctions.h> 00465 #include <tvmet/MatrixBinaryFunctions.h> 00466 #include <tvmet/MatrixUnaryFunctions.h> 00467 #include <tvmet/MatrixOperators.h> 00468 #include <tvmet/MatrixEval.h> 00469 #include <tvmet/AliasProxy.h> 00470 00471 #endif // TVMET_MATRIX_H 00472 00473 // Local Variables: 00474 // mode:C++ 00475 // tab-width:8 00476 // End:
Generated on Tue Jul 12 2022 18:53:25 by
1.7.2
