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.
PlainObjectBase.h
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> 00006 // 00007 // This Source Code Form is subject to the terms of the Mozilla 00008 // Public License v. 2.0. If a copy of the MPL was not distributed 00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00010 00011 #ifndef EIGEN_DENSESTORAGEBASE_H 00012 #define EIGEN_DENSESTORAGEBASE_H 00013 00014 #if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO) 00015 # define EIGEN_INITIALIZE_COEFFS 00016 # define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0); 00017 #elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN) 00018 # define EIGEN_INITIALIZE_COEFFS 00019 # define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=std::numeric_limits<Scalar>::quiet_NaN(); 00020 #else 00021 # undef EIGEN_INITIALIZE_COEFFS 00022 # define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00023 #endif 00024 00025 namespace Eigen { 00026 00027 namespace internal { 00028 00029 template<int MaxSizeAtCompileTime> struct check_rows_cols_for_overflow { 00030 template<typename Index> 00031 static EIGEN_ALWAYS_INLINE void run(Index, Index) 00032 { 00033 } 00034 }; 00035 00036 template<> struct check_rows_cols_for_overflow<Dynamic> { 00037 template<typename Index> 00038 static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols) 00039 { 00040 // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242 00041 // we assume Index is signed 00042 Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed 00043 bool error = (rows == 0 || cols == 0) ? false 00044 : (rows > max_index / cols); 00045 if (error) 00046 throw_std_bad_alloc(); 00047 } 00048 }; 00049 00050 template <typename Derived, 00051 typename OtherDerived = Derived, 00052 bool IsVector = bool(Derived::IsVectorAtCompileTime) && bool(OtherDerived::IsVectorAtCompileTime)> 00053 struct conservative_resize_like_impl; 00054 00055 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl; 00056 00057 } // end namespace internal 00058 00059 /** \class PlainObjectBase 00060 * \brief %Dense storage base class for matrices and arrays. 00061 * 00062 * This class can be extended with the help of the plugin mechanism described on the page 00063 * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_PLAINOBJECTBASE_PLUGIN. 00064 * 00065 * \sa \ref TopicClassHierarchy 00066 */ 00067 #ifdef EIGEN_PARSED_BY_DOXYGEN 00068 namespace internal { 00069 00070 // this is a warkaround to doxygen not being able to understand the inheritence logic 00071 // when it is hidden by the dense_xpr_base helper struct. 00072 template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase<Derived> {}; 00073 /** This class is just a workaround for Doxygen and it does not not actually exist. */ 00074 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> 00075 struct dense_xpr_base_dispatcher_for_doxygen<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > 00076 : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {}; 00077 /** This class is just a workaround for Doxygen and it does not not actually exist. */ 00078 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> 00079 struct dense_xpr_base_dispatcher_for_doxygen<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > 00080 : public ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {}; 00081 00082 } // namespace internal 00083 00084 template<typename Derived> 00085 class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen<Derived> 00086 #else 00087 template<typename Derived> 00088 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type 00089 #endif 00090 { 00091 public: 00092 enum { Options = internal::traits<Derived>::Options }; 00093 typedef typename internal::dense_xpr_base<Derived>::type Base; 00094 00095 typedef typename internal::traits<Derived>::StorageKind StorageKind; 00096 typedef typename internal::traits<Derived>::Index Index; 00097 typedef typename internal::traits<Derived>::Scalar Scalar; 00098 typedef typename internal::packet_traits<Scalar>::type PacketScalar; 00099 typedef typename NumTraits<Scalar>::Real RealScalar; 00100 typedef Derived DenseType; 00101 00102 using Base::RowsAtCompileTime; 00103 using Base::ColsAtCompileTime; 00104 using Base::SizeAtCompileTime; 00105 using Base::MaxRowsAtCompileTime; 00106 using Base::MaxColsAtCompileTime; 00107 using Base::MaxSizeAtCompileTime; 00108 using Base::IsVectorAtCompileTime; 00109 using Base::Flags; 00110 00111 template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map; 00112 friend class Eigen::Map<Derived, Unaligned>; 00113 typedef Eigen::Map<Derived, Unaligned> MapType; 00114 friend class Eigen::Map<const Derived, Unaligned>; 00115 typedef const Eigen::Map<const Derived, Unaligned> ConstMapType; 00116 friend class Eigen::Map<Derived, Aligned>; 00117 typedef Eigen::Map<Derived, Aligned> AlignedMapType; 00118 friend class Eigen::Map<const Derived, Aligned>; 00119 typedef const Eigen::Map<const Derived, Aligned> ConstAlignedMapType; 00120 template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; }; 00121 template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; }; 00122 template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, Aligned, StrideType> type; }; 00123 template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, Aligned, StrideType> type; }; 00124 00125 protected: 00126 DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage; 00127 00128 public: 00129 enum { NeedsToAlign = SizeAtCompileTime != Dynamic && (internal::traits<Derived>::Flags & AlignedBit) != 0 }; 00130 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) 00131 00132 Base& base() { return *static_cast<Base*>(this); } 00133 const Base& base() const { return *static_cast<const Base*>(this); } 00134 00135 EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); } 00136 EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); } 00137 00138 EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const 00139 { 00140 if(Flags & RowMajorBit) 00141 return m_storage.data()[colId + rowId * m_storage.cols()]; 00142 else // column-major 00143 return m_storage.data()[rowId + colId * m_storage.rows()]; 00144 } 00145 00146 EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const 00147 { 00148 return m_storage.data()[index]; 00149 } 00150 00151 EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId) 00152 { 00153 if(Flags & RowMajorBit) 00154 return m_storage.data()[colId + rowId * m_storage.cols()]; 00155 else // column-major 00156 return m_storage.data()[rowId + colId * m_storage.rows()]; 00157 } 00158 00159 EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) 00160 { 00161 return m_storage.data()[index]; 00162 } 00163 00164 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const 00165 { 00166 if(Flags & RowMajorBit) 00167 return m_storage.data()[colId + rowId * m_storage.cols()]; 00168 else // column-major 00169 return m_storage.data()[rowId + colId * m_storage.rows()]; 00170 } 00171 00172 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const 00173 { 00174 return m_storage.data()[index]; 00175 } 00176 00177 /** \internal */ 00178 template<int LoadMode> 00179 EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const 00180 { 00181 return internal::ploadt<PacketScalar, LoadMode> 00182 (m_storage.data() + (Flags & RowMajorBit 00183 ? colId + rowId * m_storage.cols() 00184 : rowId + colId * m_storage.rows())); 00185 } 00186 00187 /** \internal */ 00188 template<int LoadMode> 00189 EIGEN_STRONG_INLINE PacketScalar packet(Index index) const 00190 { 00191 return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index); 00192 } 00193 00194 /** \internal */ 00195 template<int StoreMode> 00196 EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val) 00197 { 00198 internal::pstoret<Scalar, PacketScalar, StoreMode> 00199 (m_storage.data() + (Flags & RowMajorBit 00200 ? colId + rowId * m_storage.cols() 00201 : rowId + colId * m_storage.rows()), val); 00202 } 00203 00204 /** \internal */ 00205 template<int StoreMode> 00206 EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val) 00207 { 00208 internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val); 00209 } 00210 00211 /** \returns a const pointer to the data array of this matrix */ 00212 EIGEN_STRONG_INLINE const Scalar *data () const 00213 { return m_storage.data(); } 00214 00215 /** \returns a pointer to the data array of this matrix */ 00216 EIGEN_STRONG_INLINE Scalar *data () 00217 { return m_storage.data(); } 00218 00219 /** Resizes \c *this to a \a rows x \a cols matrix. 00220 * 00221 * This method is intended for dynamic-size matrices, although it is legal to call it on any 00222 * matrix as long as fixed dimensions are left unchanged. If you only want to change the number 00223 * of rows and/or of columns, you can use resize(NoChange_t, Index), resize(Index, NoChange_t). 00224 * 00225 * If the current number of coefficients of \c *this exactly matches the 00226 * product \a rows * \a cols, then no memory allocation is performed and 00227 * the current values are left unchanged. In all other cases, including 00228 * shrinking, the data is reallocated and all previous values are lost. 00229 * 00230 * Example: \include Matrix_resize_int_int.cpp 00231 * Output: \verbinclude Matrix_resize_int_int.out 00232 * 00233 * \sa resize(Index) for vectors, resize(NoChange_t, Index), resize(Index, NoChange_t) 00234 */ 00235 EIGEN_STRONG_INLINE void resize(Index nbRows, Index nbCols) 00236 { 00237 eigen_assert( EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,nbRows==RowsAtCompileTime) 00238 && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,nbCols==ColsAtCompileTime) 00239 && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,nbRows<=MaxRowsAtCompileTime) 00240 && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,nbCols<=MaxColsAtCompileTime) 00241 && nbRows>=0 && nbCols>=0 && "Invalid sizes when resizing a matrix or array."); 00242 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(nbRows, nbCols); 00243 #ifdef EIGEN_INITIALIZE_COEFFS 00244 Index size = nbRows*nbCols; 00245 bool size_changed = size != this->size(); 00246 m_storage.resize(size, nbRows, nbCols); 00247 if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00248 #else 00249 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(nbRows, nbCols); 00250 m_storage.resize(nbRows*nbCols, nbRows, nbCols); 00251 #endif 00252 } 00253 00254 /** Resizes \c *this to a vector of length \a size 00255 * 00256 * \only_for_vectors. This method does not work for 00257 * partially dynamic matrices when the static dimension is anything other 00258 * than 1. For example it will not work with Matrix<double, 2, Dynamic>. 00259 * 00260 * Example: \include Matrix_resize_int.cpp 00261 * Output: \verbinclude Matrix_resize_int.out 00262 * 00263 * \sa resize(Index,Index), resize(NoChange_t, Index), resize(Index, NoChange_t) 00264 */ 00265 inline void resize(Index size) 00266 { 00267 EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase) 00268 eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0); 00269 #ifdef EIGEN_INITIALIZE_COEFFS 00270 bool size_changed = size != this->size(); 00271 #endif 00272 if(RowsAtCompileTime == 1) 00273 m_storage.resize(size, 1, size); 00274 else 00275 m_storage.resize(size, size, 1); 00276 #ifdef EIGEN_INITIALIZE_COEFFS 00277 if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00278 #endif 00279 } 00280 00281 /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange 00282 * as in the example below. 00283 * 00284 * Example: \include Matrix_resize_NoChange_int.cpp 00285 * Output: \verbinclude Matrix_resize_NoChange_int.out 00286 * 00287 * \sa resize(Index,Index) 00288 */ 00289 inline void resize(NoChange_t, Index nbCols) 00290 { 00291 resize(rows(), nbCols); 00292 } 00293 00294 /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange 00295 * as in the example below. 00296 * 00297 * Example: \include Matrix_resize_int_NoChange.cpp 00298 * Output: \verbinclude Matrix_resize_int_NoChange.out 00299 * 00300 * \sa resize(Index,Index) 00301 */ 00302 inline void resize(Index nbRows, NoChange_t) 00303 { 00304 resize(nbRows, cols()); 00305 } 00306 00307 /** Resizes \c *this to have the same dimensions as \a other. 00308 * Takes care of doing all the checking that's needed. 00309 * 00310 * Note that copying a row-vector into a vector (and conversely) is allowed. 00311 * The resizing, if any, is then done in the appropriate way so that row-vectors 00312 * remain row-vectors and vectors remain vectors. 00313 */ 00314 template<typename OtherDerived> 00315 EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other) 00316 { 00317 const OtherDerived& other = _other.derived (); 00318 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols()); 00319 const Index othersize = other.rows()*other.cols(); 00320 if(RowsAtCompileTime == 1) 00321 { 00322 eigen_assert(other.rows() == 1 || other.cols() == 1); 00323 resize(1, othersize); 00324 } 00325 else if(ColsAtCompileTime == 1) 00326 { 00327 eigen_assert(other.rows() == 1 || other.cols() == 1); 00328 resize(othersize, 1); 00329 } 00330 else resize(other.rows(), other.cols()); 00331 } 00332 00333 /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. 00334 * 00335 * The method is intended for matrices of dynamic size. If you only want to change the number 00336 * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or 00337 * conservativeResize(Index, NoChange_t). 00338 * 00339 * Matrices are resized relative to the top-left element. In case values need to be 00340 * appended to the matrix they will be uninitialized. 00341 */ 00342 EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, Index nbCols) 00343 { 00344 internal::conservative_resize_like_impl<Derived>::run(*this, nbRows, nbCols); 00345 } 00346 00347 /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. 00348 * 00349 * As opposed to conservativeResize(Index rows, Index cols), this version leaves 00350 * the number of columns unchanged. 00351 * 00352 * In case the matrix is growing, new rows will be uninitialized. 00353 */ 00354 EIGEN_STRONG_INLINE void conservativeResize(Index nbRows, NoChange_t) 00355 { 00356 // Note: see the comment in conservativeResize(Index,Index) 00357 conservativeResize(nbRows, cols()); 00358 } 00359 00360 /** Resizes the matrix to \a rows x \a cols while leaving old values untouched. 00361 * 00362 * As opposed to conservativeResize(Index rows, Index cols), this version leaves 00363 * the number of rows unchanged. 00364 * 00365 * In case the matrix is growing, new columns will be uninitialized. 00366 */ 00367 EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index nbCols) 00368 { 00369 // Note: see the comment in conservativeResize(Index,Index) 00370 conservativeResize(rows(), nbCols); 00371 } 00372 00373 /** Resizes the vector to \a size while retaining old values. 00374 * 00375 * \only_for_vectors. This method does not work for 00376 * partially dynamic matrices when the static dimension is anything other 00377 * than 1. For example it will not work with Matrix<double, 2, Dynamic>. 00378 * 00379 * When values are appended, they will be uninitialized. 00380 */ 00381 EIGEN_STRONG_INLINE void conservativeResize(Index size) 00382 { 00383 internal::conservative_resize_like_impl<Derived>::run(*this, size); 00384 } 00385 00386 /** Resizes the matrix to \a rows x \a cols of \c other, while leaving old values untouched. 00387 * 00388 * The method is intended for matrices of dynamic size. If you only want to change the number 00389 * of rows and/or of columns, you can use conservativeResize(NoChange_t, Index) or 00390 * conservativeResize(Index, NoChange_t). 00391 * 00392 * Matrices are resized relative to the top-left element. In case values need to be 00393 * appended to the matrix they will copied from \c other. 00394 */ 00395 template<typename OtherDerived> 00396 EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other) 00397 { 00398 internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other); 00399 } 00400 00401 /** This is a special case of the templated operator=. Its purpose is to 00402 * prevent a default operator= from hiding the templated operator=. 00403 */ 00404 EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other) 00405 { 00406 return _set(other); 00407 } 00408 00409 /** \sa MatrixBase::lazyAssign() */ 00410 template<typename OtherDerived> 00411 EIGEN_STRONG_INLINE Derived& lazyAssign (const DenseBase<OtherDerived>& other) 00412 { 00413 _resize_to_match(other); 00414 return Base::lazyAssign (other.derived()); 00415 } 00416 00417 template<typename OtherDerived> 00418 EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func) 00419 { 00420 resize(func.rows(), func.cols()); 00421 return Base::operator=(func); 00422 } 00423 00424 EIGEN_STRONG_INLINE PlainObjectBase() : m_storage() 00425 { 00426 // _check_template_params(); 00427 // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00428 } 00429 00430 #ifndef EIGEN_PARSED_BY_DOXYGEN 00431 // FIXME is it still needed ? 00432 /** \internal */ 00433 PlainObjectBase(internal::constructor_without_unaligned_array_assert) 00434 : m_storage(internal::constructor_without_unaligned_array_assert()) 00435 { 00436 // _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00437 } 00438 #endif 00439 00440 #ifdef EIGEN_HAVE_RVALUE_REFERENCES 00441 PlainObjectBase(PlainObjectBase&& other) 00442 : m_storage( std::move(other.m_storage) ) 00443 { 00444 } 00445 00446 PlainObjectBase& operator=(PlainObjectBase&& other) 00447 { 00448 using std::swap; 00449 swap(m_storage, other.m_storage); 00450 return *this; 00451 } 00452 #endif 00453 00454 /** Copy constructor */ 00455 EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other) 00456 : m_storage() 00457 { 00458 _check_template_params(); 00459 lazyAssign (other); 00460 } 00461 00462 template<typename OtherDerived> 00463 EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other) 00464 : m_storage() 00465 { 00466 _check_template_params(); 00467 lazyAssign (other); 00468 } 00469 00470 EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols) 00471 : m_storage(a_size, nbRows, nbCols) 00472 { 00473 // _check_template_params(); 00474 // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00475 } 00476 00477 /** \copydoc MatrixBase::operator=(const EigenBase<OtherDerived>&) 00478 */ 00479 template<typename OtherDerived> 00480 EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other) 00481 { 00482 _resize_to_match(other); 00483 Base::operator=(other.derived ()); 00484 return this->derived(); 00485 } 00486 00487 /** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */ 00488 template<typename OtherDerived> 00489 EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other) 00490 : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) 00491 { 00492 _check_template_params(); 00493 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.derived ().rows(), other.derived ().cols()); 00494 Base::operator=(other.derived ()); 00495 } 00496 00497 /** \name Map 00498 * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects, 00499 * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned 00500 * \a data pointers. 00501 * 00502 * \see class Map 00503 */ 00504 //@{ 00505 static inline ConstMapType Map(const Scalar* data ) 00506 { return ConstMapType(data); } 00507 static inline MapType Map(Scalar* data ) 00508 { return MapType(data); } 00509 static inline ConstMapType Map(const Scalar* data , Index size) 00510 { return ConstMapType(data, size); } 00511 static inline MapType Map(Scalar* data , Index size) 00512 { return MapType(data, size); } 00513 static inline ConstMapType Map(const Scalar* data , Index rows, Index cols) 00514 { return ConstMapType(data, rows, cols); } 00515 static inline MapType Map(Scalar* data , Index rows, Index cols) 00516 { return MapType(data, rows, cols); } 00517 00518 static inline ConstAlignedMapType MapAligned(const Scalar* data ) 00519 { return ConstAlignedMapType(data); } 00520 static inline AlignedMapType MapAligned(Scalar* data ) 00521 { return AlignedMapType(data); } 00522 static inline ConstAlignedMapType MapAligned(const Scalar* data , Index size) 00523 { return ConstAlignedMapType(data, size); } 00524 static inline AlignedMapType MapAligned(Scalar* data , Index size) 00525 { return AlignedMapType(data, size); } 00526 static inline ConstAlignedMapType MapAligned(const Scalar* data , Index rows, Index cols) 00527 { return ConstAlignedMapType(data, rows, cols); } 00528 static inline AlignedMapType MapAligned(Scalar* data , Index rows, Index cols) 00529 { return AlignedMapType(data, rows, cols); } 00530 00531 template<int Outer, int Inner> 00532 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data , const Stride<Outer, Inner>& stride) 00533 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data , stride); } 00534 template<int Outer, int Inner> 00535 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data , const Stride<Outer, Inner>& stride) 00536 { return typename StridedMapType<Stride<Outer, Inner> >::type(data , stride); } 00537 template<int Outer, int Inner> 00538 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data , Index size, const Stride<Outer, Inner>& stride) 00539 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data , size, stride); } 00540 template<int Outer, int Inner> 00541 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data , Index size, const Stride<Outer, Inner>& stride) 00542 { return typename StridedMapType<Stride<Outer, Inner> >::type(data , size, stride); } 00543 template<int Outer, int Inner> 00544 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data , Index rows, Index cols, const Stride<Outer, Inner>& stride) 00545 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data , rows, cols, stride); } 00546 template<int Outer, int Inner> 00547 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data , Index rows, Index cols, const Stride<Outer, Inner>& stride) 00548 { return typename StridedMapType<Stride<Outer, Inner> >::type(data , rows, cols, stride); } 00549 00550 template<int Outer, int Inner> 00551 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data , const Stride<Outer, Inner>& stride) 00552 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data , stride); } 00553 template<int Outer, int Inner> 00554 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data , const Stride<Outer, Inner>& stride) 00555 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data , stride); } 00556 template<int Outer, int Inner> 00557 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data , Index size, const Stride<Outer, Inner>& stride) 00558 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data , size, stride); } 00559 template<int Outer, int Inner> 00560 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data , Index size, const Stride<Outer, Inner>& stride) 00561 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data , size, stride); } 00562 template<int Outer, int Inner> 00563 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data , Index rows, Index cols, const Stride<Outer, Inner>& stride) 00564 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data , rows, cols, stride); } 00565 template<int Outer, int Inner> 00566 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data , Index rows, Index cols, const Stride<Outer, Inner>& stride) 00567 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data , rows, cols, stride); } 00568 //@} 00569 00570 using Base::setConstant; 00571 Derived& setConstant(Index size, const Scalar& value); 00572 Derived& setConstant(Index rows, Index cols, const Scalar& value); 00573 00574 using Base::setZero; 00575 Derived& setZero(Index size); 00576 Derived& setZero(Index rows, Index cols); 00577 00578 using Base::setOnes; 00579 Derived& setOnes(Index size); 00580 Derived& setOnes(Index rows, Index cols); 00581 00582 using Base::setRandom; 00583 Derived& setRandom(Index size); 00584 Derived& setRandom(Index rows, Index cols); 00585 00586 #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN 00587 #include EIGEN_PLAINOBJECTBASE_PLUGIN 00588 #endif 00589 00590 protected: 00591 /** \internal Resizes *this in preparation for assigning \a other to it. 00592 * Takes care of doing all the checking that's needed. 00593 * 00594 * Note that copying a row-vector into a vector (and conversely) is allowed. 00595 * The resizing, if any, is then done in the appropriate way so that row-vectors 00596 * remain row-vectors and vectors remain vectors. 00597 */ 00598 template<typename OtherDerived> 00599 EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other) 00600 { 00601 #ifdef EIGEN_NO_AUTOMATIC_RESIZING 00602 eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size()) 00603 : (rows() == other.rows() && cols() == other.cols()))) 00604 && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); 00605 EIGEN_ONLY_USED_FOR_DEBUG(other); 00606 if(this->size()==0) 00607 resizeLike(other); 00608 #else 00609 resizeLike(other); 00610 #endif 00611 } 00612 00613 /** 00614 * \brief Copies the value of the expression \a other into \c *this with automatic resizing. 00615 * 00616 * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), 00617 * it will be initialized. 00618 * 00619 * Note that copying a row-vector into a vector (and conversely) is allowed. 00620 * The resizing, if any, is then done in the appropriate way so that row-vectors 00621 * remain row-vectors and vectors remain vectors. 00622 * 00623 * \sa operator=(const MatrixBase<OtherDerived>&), _set_noalias() 00624 * 00625 * \internal 00626 */ 00627 template<typename OtherDerived> 00628 EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other) 00629 { 00630 _set_selector(other.derived(), typename internal::conditional<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type()); 00631 return this->derived(); 00632 } 00633 00634 template<typename OtherDerived> 00635 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); } 00636 00637 template<typename OtherDerived> 00638 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); } 00639 00640 /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which 00641 * is the case when creating a new matrix) so one can enforce lazy evaluation. 00642 * 00643 * \sa operator=(const MatrixBase<OtherDerived>&), _set() 00644 */ 00645 template<typename OtherDerived> 00646 EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other) 00647 { 00648 // I don't think we need this resize call since the lazyAssign will anyways resize 00649 // and lazyAssign will be called by the assign selector. 00650 //_resize_to_match(other); 00651 // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because 00652 // it wouldn't allow to copy a row-vector into a column-vector. 00653 return internal::assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived()); 00654 } 00655 00656 template<typename T0, typename T1> 00657 EIGEN_STRONG_INLINE void _init2(Index nbRows, Index nbCols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0) 00658 { 00659 EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) && 00660 bool(NumTraits<T1>::IsInteger), 00661 FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) 00662 resize(nbRows,nbCols); 00663 } 00664 template<typename T0, typename T1> 00665 EIGEN_STRONG_INLINE void _init2(const Scalar& val0, const Scalar& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0) 00666 { 00667 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2) 00668 m_storage.data ()[0] = val0; 00669 m_storage.data ()[1] = val1; 00670 } 00671 00672 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> 00673 friend struct internal::matrix_swap_impl; 00674 00675 /** \internal generic implementation of swap for dense storage since for dynamic-sized matrices of same type it is enough to swap the 00676 * data pointers. 00677 */ 00678 template<typename OtherDerived> 00679 void _swap(DenseBase<OtherDerived> const & other) 00680 { 00681 enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic }; 00682 internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived()); 00683 } 00684 00685 public: 00686 #ifndef EIGEN_PARSED_BY_DOXYGEN 00687 static EIGEN_STRONG_INLINE void _check_template_params() 00688 { 00689 EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor) 00690 && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0) 00691 && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0)) 00692 && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0)) 00693 && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0)) 00694 && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0)) 00695 && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic) 00696 && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic) 00697 && (Options & (DontAlign|RowMajor)) == Options), 00698 INVALID_MATRIX_TEMPLATE_PARAMETERS) 00699 } 00700 #endif 00701 00702 private: 00703 enum { ThisConstantIsPrivateInPlainObjectBase }; 00704 }; 00705 00706 namespace internal { 00707 00708 template <typename Derived, typename OtherDerived, bool IsVector> 00709 struct conservative_resize_like_impl 00710 { 00711 typedef typename Derived::Index Index; 00712 static void run(DenseBase<Derived> & _this, Index rows, Index cols) 00713 { 00714 if (_this.rows() == rows && _this.cols() == cols) return; 00715 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) 00716 00717 if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows 00718 (!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns 00719 { 00720 internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols); 00721 _this.derived().m_storage.conservativeResize(rows*cols,rows,cols); 00722 } 00723 else 00724 { 00725 // The storage order does not allow us to use reallocation. 00726 typename Derived::PlainObject tmp(rows,cols); 00727 const Index common_rows = (std::min)(rows, _this.rows()); 00728 const Index common_cols = (std::min)(cols, _this.cols()); 00729 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); 00730 _this.derived().swap(tmp); 00731 } 00732 } 00733 00734 static void run(DenseBase<Derived> & _this, const DenseBase<OtherDerived>& other) 00735 { 00736 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; 00737 00738 // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index), 00739 // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the 00740 // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or 00741 // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like 00742 // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good. 00743 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) 00744 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived) 00745 00746 if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows 00747 (!Derived::IsRowMajor && _this.rows() == other.rows()) ) // column-major and we change only the number of columns 00748 { 00749 const Index new_rows = other.rows() - _this.rows(); 00750 const Index new_cols = other.cols() - _this.cols(); 00751 _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols()); 00752 if (new_rows>0) 00753 _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows); 00754 else if (new_cols>0) 00755 _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols); 00756 } 00757 else 00758 { 00759 // The storage order does not allow us to use reallocation. 00760 typename Derived::PlainObject tmp(other); 00761 const Index common_rows = (std::min)(tmp.rows(), _this.rows()); 00762 const Index common_cols = (std::min)(tmp.cols(), _this.cols()); 00763 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); 00764 _this.derived().swap(tmp); 00765 } 00766 } 00767 }; 00768 00769 // Here, the specialization for vectors inherits from the general matrix case 00770 // to allow calling .conservativeResize(rows,cols) on vectors. 00771 template <typename Derived, typename OtherDerived> 00772 struct conservative_resize_like_impl<Derived,OtherDerived,true> 00773 : conservative_resize_like_impl<Derived,OtherDerived,false> 00774 { 00775 using conservative_resize_like_impl<Derived,OtherDerived,false>::run; 00776 00777 typedef typename Derived::Index Index; 00778 static void run(DenseBase<Derived> & _this, Index size) 00779 { 00780 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size; 00781 const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1; 00782 _this.derived().m_storage.conservativeResize(size,new_rows,new_cols); 00783 } 00784 00785 static void run(DenseBase<Derived> & _this, const DenseBase<OtherDerived>& other) 00786 { 00787 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; 00788 00789 const Index num_new_elements = other.size() - _this.size(); 00790 00791 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows(); 00792 const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1; 00793 _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols); 00794 00795 if (num_new_elements > 0) 00796 _this.tail(num_new_elements) = other.tail(num_new_elements); 00797 } 00798 }; 00799 00800 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> 00801 struct matrix_swap_impl 00802 { 00803 static inline void run(MatrixTypeA& a, MatrixTypeB& b) 00804 { 00805 a.base().swap(b); 00806 } 00807 }; 00808 00809 template<typename MatrixTypeA, typename MatrixTypeB> 00810 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true> 00811 { 00812 static inline void run(MatrixTypeA& a, MatrixTypeB& b) 00813 { 00814 static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage); 00815 } 00816 }; 00817 00818 } // end namespace internal 00819 00820 } // end namespace Eigen 00821 00822 #endif // EIGEN_DENSESTORAGEBASE_H
Generated on Thu Nov 17 2022 22:01:30 by
1.7.2