![]() |
Eigen
3.3.3
|
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 EIGEN_DEVICE_FUNC 00032 static EIGEN_ALWAYS_INLINE void run(Index, Index) 00033 { 00034 } 00035 }; 00036 00037 template<> struct check_rows_cols_for_overflow<Dynamic> { 00038 template<typename Index> 00039 EIGEN_DEVICE_FUNC 00040 static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols) 00041 { 00042 // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242 00043 // we assume Index is signed 00044 Index max_index = (std::size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed 00045 bool error = (rows == 0 || cols == 0) ? false 00046 : (rows > max_index / cols); 00047 if (error) 00048 throw_std_bad_alloc(); 00049 } 00050 }; 00051 00052 template <typename Derived, 00053 typename OtherDerived = Derived, 00054 bool IsVector = bool(Derived::IsVectorAtCompileTime) && bool(OtherDerived::IsVectorAtCompileTime)> 00055 struct conservative_resize_like_impl; 00056 00057 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl; 00058 00059 } // end namespace internal 00060 00061 #ifdef EIGEN_PARSED_BY_DOXYGEN 00062 namespace doxygen { 00063 00064 // This is a workaround to doxygen not being able to understand the inheritance logic 00065 // when it is hidden by the dense_xpr_base helper struct. 00066 // Moreover, doxygen fails to include members that are not documented in the declaration body of 00067 // MatrixBase if we inherits MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >, 00068 // this is why we simply inherits MatrixBase, though this does not make sense. 00069 00071 template<typename Derived> struct dense_xpr_base_dispatcher; 00073 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> 00074 struct dense_xpr_base_dispatcher<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > 00075 : public MatrixBase {}; 00077 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> 00078 struct dense_xpr_base_dispatcher<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > 00079 : public ArrayBase {}; 00080 00081 } // namespace doxygen 00082 00094 template<typename Derived> 00095 class PlainObjectBase : public doxygen::dense_xpr_base_dispatcher<Derived> 00096 #else 00097 template<typename Derived> 00098 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type 00099 #endif 00100 { 00101 public: 00102 enum { Options = internal::traits<Derived>::Options }; 00103 typedef typename internal::dense_xpr_base<Derived>::type Base; 00104 00105 typedef typename internal::traits<Derived>::StorageKind StorageKind; 00106 typedef typename internal::traits<Derived>::Scalar Scalar; 00107 00108 typedef typename internal::packet_traits<Scalar>::type PacketScalar; 00109 typedef typename NumTraits<Scalar>::Real RealScalar; 00110 typedef Derived DenseType; 00111 00112 using Base::RowsAtCompileTime; 00113 using Base::ColsAtCompileTime; 00114 using Base::SizeAtCompileTime; 00115 using Base::MaxRowsAtCompileTime; 00116 using Base::MaxColsAtCompileTime; 00117 using Base::MaxSizeAtCompileTime; 00118 using Base::IsVectorAtCompileTime; 00119 using Base::Flags; 00120 00121 template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map; 00122 friend class Eigen::Map<Derived, Unaligned>; 00123 typedef Eigen::Map<Derived, Unaligned> MapType; 00124 friend class Eigen::Map<const Derived, Unaligned>; 00125 typedef const Eigen::Map<const Derived, Unaligned> ConstMapType; 00126 #if EIGEN_MAX_ALIGN_BYTES>0 00127 // for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice. 00128 friend class Eigen::Map<Derived, AlignedMax>; 00129 friend class Eigen::Map<const Derived, AlignedMax>; 00130 #endif 00131 typedef Eigen::Map<Derived, AlignedMax> AlignedMapType; 00132 typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType; 00133 template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; }; 00134 template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; }; 00135 template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, AlignedMax, StrideType> type; }; 00136 template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, AlignedMax, StrideType> type; }; 00137 00138 protected: 00139 DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage; 00140 00141 public: 00142 enum { NeedsToAlign = (SizeAtCompileTime != Dynamic) && (internal::traits<Derived>::Alignment>0) }; 00143 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) 00144 00145 EIGEN_DEVICE_FUNC 00146 Base& base() { return *static_cast<Base*>(this); } 00147 EIGEN_DEVICE_FUNC 00148 const Base& base() const { return *static_cast<const Base*>(this); } 00149 00150 EIGEN_DEVICE_FUNC 00151 EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); } 00152 EIGEN_DEVICE_FUNC 00153 EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); } 00154 00159 EIGEN_DEVICE_FUNC 00160 EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const 00161 { 00162 if(Flags & RowMajorBit) 00163 return m_storage.data()[colId + rowId * m_storage.cols()]; 00164 else // column-major 00165 return m_storage.data()[rowId + colId * m_storage.rows()]; 00166 } 00167 00172 EIGEN_DEVICE_FUNC 00173 EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const 00174 { 00175 return m_storage.data()[index]; 00176 } 00177 00182 EIGEN_DEVICE_FUNC 00183 EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId) 00184 { 00185 if(Flags & RowMajorBit) 00186 return m_storage.data()[colId + rowId * m_storage.cols()]; 00187 else // column-major 00188 return m_storage.data()[rowId + colId * m_storage.rows()]; 00189 } 00190 00195 EIGEN_DEVICE_FUNC 00196 EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) 00197 { 00198 return m_storage.data()[index]; 00199 } 00200 00203 EIGEN_DEVICE_FUNC 00204 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const 00205 { 00206 if(Flags & RowMajorBit) 00207 return m_storage.data()[colId + rowId * m_storage.cols()]; 00208 else // column-major 00209 return m_storage.data()[rowId + colId * m_storage.rows()]; 00210 } 00211 00214 EIGEN_DEVICE_FUNC 00215 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const 00216 { 00217 return m_storage.data()[index]; 00218 } 00219 00221 template<int LoadMode> 00222 EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const 00223 { 00224 return internal::ploadt<PacketScalar, LoadMode> 00225 (m_storage.data() + (Flags & RowMajorBit 00226 ? colId + rowId * m_storage.cols() 00227 : rowId + colId * m_storage.rows())); 00228 } 00229 00231 template<int LoadMode> 00232 EIGEN_STRONG_INLINE PacketScalar packet(Index index) const 00233 { 00234 return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index); 00235 } 00236 00238 template<int StoreMode> 00239 EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val) 00240 { 00241 internal::pstoret<Scalar, PacketScalar, StoreMode> 00242 (m_storage.data() + (Flags & RowMajorBit 00243 ? colId + rowId * m_storage.cols() 00244 : rowId + colId * m_storage.rows()), val); 00245 } 00246 00248 template<int StoreMode> 00249 EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val) 00250 { 00251 internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val); 00252 } 00253 00255 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar *data() const 00256 { return m_storage.data(); } 00257 00259 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar *data() 00260 { return m_storage.data(); } 00261 00278 EIGEN_DEVICE_FUNC 00279 EIGEN_STRONG_INLINE void resize(Index rows, Index cols) 00280 { 00281 eigen_assert( EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,rows==RowsAtCompileTime) 00282 && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,cols==ColsAtCompileTime) 00283 && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,rows<=MaxRowsAtCompileTime) 00284 && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,cols<=MaxColsAtCompileTime) 00285 && rows>=0 && cols>=0 && "Invalid sizes when resizing a matrix or array."); 00286 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(rows, cols); 00287 #ifdef EIGEN_INITIALIZE_COEFFS 00288 Index size = rows*cols; 00289 bool size_changed = size != this->size(); 00290 m_storage.resize(size, rows, cols); 00291 if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00292 #else 00293 m_storage.resize(rows*cols, rows, cols); 00294 #endif 00295 } 00296 00308 EIGEN_DEVICE_FUNC 00309 inline void resize(Index size) 00310 { 00311 EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase) 00312 eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0); 00313 #ifdef EIGEN_INITIALIZE_COEFFS 00314 bool size_changed = size != this->size(); 00315 #endif 00316 if(RowsAtCompileTime == 1) 00317 m_storage.resize(size, 1, size); 00318 else 00319 m_storage.resize(size, size, 1); 00320 #ifdef EIGEN_INITIALIZE_COEFFS 00321 if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00322 #endif 00323 } 00324 00333 EIGEN_DEVICE_FUNC 00334 inline void resize(NoChange_t, Index cols) 00335 { 00336 resize(rows(), cols); 00337 } 00338 00347 EIGEN_DEVICE_FUNC 00348 inline void resize(Index rows, NoChange_t) 00349 { 00350 resize(rows, cols()); 00351 } 00352 00360 template<typename OtherDerived> 00361 EIGEN_DEVICE_FUNC 00362 EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other) 00363 { 00364 const OtherDerived& other = _other.derived(); 00365 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols()); 00366 const Index othersize = other.rows()*other.cols(); 00367 if(RowsAtCompileTime == 1) 00368 { 00369 eigen_assert(other.rows() == 1 || other.cols() == 1); 00370 resize(1, othersize); 00371 } 00372 else if(ColsAtCompileTime == 1) 00373 { 00374 eigen_assert(other.rows() == 1 || other.cols() == 1); 00375 resize(othersize, 1); 00376 } 00377 else resize(other.rows(), other.cols()); 00378 } 00379 00389 EIGEN_DEVICE_FUNC 00390 EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols) 00391 { 00392 internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols); 00393 } 00394 00402 EIGEN_DEVICE_FUNC 00403 EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t) 00404 { 00405 // Note: see the comment in conservativeResize(Index,Index) 00406 conservativeResize(rows, cols()); 00407 } 00408 00416 EIGEN_DEVICE_FUNC 00417 EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols) 00418 { 00419 // Note: see the comment in conservativeResize(Index,Index) 00420 conservativeResize(rows(), cols); 00421 } 00422 00431 EIGEN_DEVICE_FUNC 00432 EIGEN_STRONG_INLINE void conservativeResize(Index size) 00433 { 00434 internal::conservative_resize_like_impl<Derived>::run(*this, size); 00435 } 00436 00446 template<typename OtherDerived> 00447 EIGEN_DEVICE_FUNC 00448 EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other) 00449 { 00450 internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other); 00451 } 00452 00456 EIGEN_DEVICE_FUNC 00457 EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other) 00458 { 00459 return _set(other); 00460 } 00461 00463 template<typename OtherDerived> 00464 EIGEN_DEVICE_FUNC 00465 EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other) 00466 { 00467 _resize_to_match(other); 00468 return Base::lazyAssign(other.derived()); 00469 } 00470 00471 template<typename OtherDerived> 00472 EIGEN_DEVICE_FUNC 00473 EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func) 00474 { 00475 resize(func.rows(), func.cols()); 00476 return Base::operator=(func); 00477 } 00478 00479 // Prevent user from trying to instantiate PlainObjectBase objects 00480 // by making all its constructor protected. See bug 1074. 00481 protected: 00482 00483 EIGEN_DEVICE_FUNC 00484 EIGEN_STRONG_INLINE PlainObjectBase() : m_storage() 00485 { 00486 // _check_template_params(); 00487 // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00488 } 00489 00490 #ifndef EIGEN_PARSED_BY_DOXYGEN 00491 // FIXME is it still needed ? 00493 EIGEN_DEVICE_FUNC 00494 explicit PlainObjectBase(internal::constructor_without_unaligned_array_assert) 00495 : m_storage(internal::constructor_without_unaligned_array_assert()) 00496 { 00497 // _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00498 } 00499 #endif 00500 00501 #if EIGEN_HAS_RVALUE_REFERENCES 00502 EIGEN_DEVICE_FUNC 00503 PlainObjectBase(PlainObjectBase&& other) EIGEN_NOEXCEPT 00504 : m_storage( std::move(other.m_storage) ) 00505 { 00506 } 00507 00508 EIGEN_DEVICE_FUNC 00509 PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT 00510 { 00511 using std::swap; 00512 swap(m_storage, other.m_storage); 00513 return *this; 00514 } 00515 #endif 00516 00518 EIGEN_DEVICE_FUNC 00519 EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other) 00520 : Base(), m_storage(other.m_storage) { } 00521 EIGEN_DEVICE_FUNC 00522 EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols) 00523 : m_storage(size, rows, cols) 00524 { 00525 // _check_template_params(); 00526 // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00527 } 00528 00530 template<typename OtherDerived> 00531 EIGEN_DEVICE_FUNC 00532 EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other) 00533 : m_storage() 00534 { 00535 _check_template_params(); 00536 resizeLike(other); 00537 _set_noalias(other); 00538 } 00539 00541 template<typename OtherDerived> 00542 EIGEN_DEVICE_FUNC 00543 EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other) 00544 : m_storage() 00545 { 00546 _check_template_params(); 00547 resizeLike(other); 00548 *this = other.derived(); 00549 } 00551 template<typename OtherDerived> 00552 EIGEN_DEVICE_FUNC 00553 EIGEN_STRONG_INLINE PlainObjectBase(const ReturnByValue<OtherDerived>& other) 00554 { 00555 _check_template_params(); 00556 // FIXME this does not automatically transpose vectors if necessary 00557 resize(other.rows(), other.cols()); 00558 other.evalTo(this->derived()); 00559 } 00560 00561 public: 00562 00566 template<typename OtherDerived> 00567 EIGEN_DEVICE_FUNC 00568 EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other) 00569 { 00570 _resize_to_match(other); 00571 Base::operator=(other.derived()); 00572 return this->derived(); 00573 } 00574 00583 static inline ConstMapType Map(const Scalar* data) 00584 { return ConstMapType(data); } 00585 static inline MapType Map(Scalar* data) 00586 { return MapType(data); } 00587 static inline ConstMapType Map(const Scalar* data, Index size) 00588 { return ConstMapType(data, size); } 00589 static inline MapType Map(Scalar* data, Index size) 00590 { return MapType(data, size); } 00591 static inline ConstMapType Map(const Scalar* data, Index rows, Index cols) 00592 { return ConstMapType(data, rows, cols); } 00593 static inline MapType Map(Scalar* data, Index rows, Index cols) 00594 { return MapType(data, rows, cols); } 00595 00596 static inline ConstAlignedMapType MapAligned(const Scalar* data) 00597 { return ConstAlignedMapType(data); } 00598 static inline AlignedMapType MapAligned(Scalar* data) 00599 { return AlignedMapType(data); } 00600 static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size) 00601 { return ConstAlignedMapType(data, size); } 00602 static inline AlignedMapType MapAligned(Scalar* data, Index size) 00603 { return AlignedMapType(data, size); } 00604 static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols) 00605 { return ConstAlignedMapType(data, rows, cols); } 00606 static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols) 00607 { return AlignedMapType(data, rows, cols); } 00608 00609 template<int Outer, int Inner> 00610 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride) 00611 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); } 00612 template<int Outer, int Inner> 00613 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride) 00614 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); } 00615 template<int Outer, int Inner> 00616 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride) 00617 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); } 00618 template<int Outer, int Inner> 00619 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride) 00620 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); } 00621 template<int Outer, int Inner> 00622 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) 00623 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } 00624 template<int Outer, int Inner> 00625 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) 00626 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } 00627 00628 template<int Outer, int Inner> 00629 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride) 00630 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); } 00631 template<int Outer, int Inner> 00632 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride) 00633 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); } 00634 template<int Outer, int Inner> 00635 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride) 00636 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); } 00637 template<int Outer, int Inner> 00638 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride) 00639 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); } 00640 template<int Outer, int Inner> 00641 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) 00642 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } 00643 template<int Outer, int Inner> 00644 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) 00645 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } 00647 00648 using Base::setConstant; 00649 EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& val); 00650 EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& val); 00651 00652 using Base::setZero; 00653 EIGEN_DEVICE_FUNC Derived& setZero(Index size); 00654 EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols); 00655 00656 using Base::setOnes; 00657 EIGEN_DEVICE_FUNC Derived& setOnes(Index size); 00658 EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols); 00659 00660 using Base::setRandom; 00661 Derived& setRandom(Index size); 00662 Derived& setRandom(Index rows, Index cols); 00663 00664 #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN 00665 #include EIGEN_PLAINOBJECTBASE_PLUGIN 00666 #endif 00667 00668 protected: 00676 template<typename OtherDerived> 00677 EIGEN_DEVICE_FUNC 00678 EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other) 00679 { 00680 #ifdef EIGEN_NO_AUTOMATIC_RESIZING 00681 eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size()) 00682 : (rows() == other.rows() && cols() == other.cols()))) 00683 && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); 00684 EIGEN_ONLY_USED_FOR_DEBUG(other); 00685 #else 00686 resizeLike(other); 00687 #endif 00688 } 00689 00704 // aliasing is dealt once in internall::call_assignment 00705 // so at this stage we have to assume aliasing... and resising has to be done later. 00706 template<typename OtherDerived> 00707 EIGEN_DEVICE_FUNC 00708 EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other) 00709 { 00710 internal::call_assignment(this->derived(), other.derived()); 00711 return this->derived(); 00712 } 00713 00719 template<typename OtherDerived> 00720 EIGEN_DEVICE_FUNC 00721 EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other) 00722 { 00723 // I don't think we need this resize call since the lazyAssign will anyways resize 00724 // and lazyAssign will be called by the assign selector. 00725 //_resize_to_match(other); 00726 // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because 00727 // it wouldn't allow to copy a row-vector into a column-vector. 00728 internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>()); 00729 return this->derived(); 00730 } 00731 00732 template<typename T0, typename T1> 00733 EIGEN_DEVICE_FUNC 00734 EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0) 00735 { 00736 EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) && 00737 bool(NumTraits<T1>::IsInteger), 00738 FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) 00739 resize(rows,cols); 00740 } 00741 00742 template<typename T0, typename T1> 00743 EIGEN_DEVICE_FUNC 00744 EIGEN_STRONG_INLINE void _init2(const T0& val0, const T1& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0) 00745 { 00746 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2) 00747 m_storage.data()[0] = Scalar(val0); 00748 m_storage.data()[1] = Scalar(val1); 00749 } 00750 00751 template<typename T0, typename T1> 00752 EIGEN_DEVICE_FUNC 00753 EIGEN_STRONG_INLINE void _init2(const Index& val0, const Index& val1, 00754 typename internal::enable_if< (!internal::is_same<Index,Scalar>::value) 00755 && (internal::is_same<T0,Index>::value) 00756 && (internal::is_same<T1,Index>::value) 00757 && Base::SizeAtCompileTime==2,T1>::type* = 0) 00758 { 00759 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2) 00760 m_storage.data()[0] = Scalar(val0); 00761 m_storage.data()[1] = Scalar(val1); 00762 } 00763 00764 // The argument is convertible to the Index type and we either have a non 1x1 Matrix, or a dynamic-sized Array, 00765 // then the argument is meant to be the size of the object. 00766 template<typename T> 00767 EIGEN_DEVICE_FUNC 00768 EIGEN_STRONG_INLINE void _init1(Index size, typename internal::enable_if< (Base::SizeAtCompileTime!=1 || !internal::is_convertible<T, Scalar>::value) 00769 && ((!internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0) 00770 { 00771 // NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument. 00772 const bool is_integer = NumTraits<T>::IsInteger; 00773 EIGEN_UNUSED_VARIABLE(is_integer); 00774 EIGEN_STATIC_ASSERT(is_integer, 00775 FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) 00776 resize(size); 00777 } 00778 00779 // We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type can be implicitely converted) 00780 template<typename T> 00781 EIGEN_DEVICE_FUNC 00782 EIGEN_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0) 00783 { 00784 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1) 00785 m_storage.data()[0] = val0; 00786 } 00787 00788 // We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type match the index type) 00789 template<typename T> 00790 EIGEN_DEVICE_FUNC 00791 EIGEN_STRONG_INLINE void _init1(const Index& val0, 00792 typename internal::enable_if< (!internal::is_same<Index,Scalar>::value) 00793 && (internal::is_same<Index,T>::value) 00794 && Base::SizeAtCompileTime==1 00795 && internal::is_convertible<T, Scalar>::value,T*>::type* = 0) 00796 { 00797 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1) 00798 m_storage.data()[0] = Scalar(val0); 00799 } 00800 00801 // Initialize a fixed size matrix from a pointer to raw data 00802 template<typename T> 00803 EIGEN_DEVICE_FUNC 00804 EIGEN_STRONG_INLINE void _init1(const Scalar* data){ 00805 this->_set_noalias(ConstMapType(data)); 00806 } 00807 00808 // Initialize an arbitrary matrix from a dense expression 00809 template<typename T, typename OtherDerived> 00810 EIGEN_DEVICE_FUNC 00811 EIGEN_STRONG_INLINE void _init1(const DenseBase<OtherDerived>& other){ 00812 this->_set_noalias(other); 00813 } 00814 00815 // Initialize an arbitrary matrix from an object convertible to the Derived type. 00816 template<typename T> 00817 EIGEN_DEVICE_FUNC 00818 EIGEN_STRONG_INLINE void _init1(const Derived& other){ 00819 this->_set_noalias(other); 00820 } 00821 00822 // Initialize an arbitrary matrix from a generic Eigen expression 00823 template<typename T, typename OtherDerived> 00824 EIGEN_DEVICE_FUNC 00825 EIGEN_STRONG_INLINE void _init1(const EigenBase<OtherDerived>& other){ 00826 this->derived() = other; 00827 } 00828 00829 template<typename T, typename OtherDerived> 00830 EIGEN_DEVICE_FUNC 00831 EIGEN_STRONG_INLINE void _init1(const ReturnByValue<OtherDerived>& other) 00832 { 00833 resize(other.rows(), other.cols()); 00834 other.evalTo(this->derived()); 00835 } 00836 00837 template<typename T, typename OtherDerived, int ColsAtCompileTime> 00838 EIGEN_DEVICE_FUNC 00839 EIGEN_STRONG_INLINE void _init1(const RotationBase<OtherDerived,ColsAtCompileTime>& r) 00840 { 00841 this->derived() = r; 00842 } 00843 00844 // For fixed-size Array<Scalar,...> 00845 template<typename T> 00846 EIGEN_DEVICE_FUNC 00847 EIGEN_STRONG_INLINE void _init1(const Scalar& val0, 00848 typename internal::enable_if< Base::SizeAtCompileTime!=Dynamic 00849 && Base::SizeAtCompileTime!=1 00850 && internal::is_convertible<T, Scalar>::value 00851 && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T>::type* = 0) 00852 { 00853 Base::setConstant(val0); 00854 } 00855 00856 // For fixed-size Array<Index,...> 00857 template<typename T> 00858 EIGEN_DEVICE_FUNC 00859 EIGEN_STRONG_INLINE void _init1(const Index& val0, 00860 typename internal::enable_if< (!internal::is_same<Index,Scalar>::value) 00861 && (internal::is_same<Index,T>::value) 00862 && Base::SizeAtCompileTime!=Dynamic 00863 && Base::SizeAtCompileTime!=1 00864 && internal::is_convertible<T, Scalar>::value 00865 && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T*>::type* = 0) 00866 { 00867 Base::setConstant(val0); 00868 } 00869 00870 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> 00871 friend struct internal::matrix_swap_impl; 00872 00873 public: 00874 00875 #ifndef EIGEN_PARSED_BY_DOXYGEN 00876 00880 template<typename OtherDerived> 00881 EIGEN_DEVICE_FUNC 00882 void swap(DenseBase<OtherDerived> & other) 00883 { 00884 enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic }; 00885 internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.derived()); 00886 } 00887 00891 template<typename OtherDerived> 00892 EIGEN_DEVICE_FUNC 00893 void swap(DenseBase<OtherDerived> const & other) 00894 { Base::swap(other.derived()); } 00895 00896 EIGEN_DEVICE_FUNC 00897 static EIGEN_STRONG_INLINE void _check_template_params() 00898 { 00899 EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor) 00900 && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0) 00901 && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0)) 00902 && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0)) 00903 && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0)) 00904 && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0)) 00905 && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic) 00906 && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic) 00907 && (Options & (DontAlign|RowMajor)) == Options), 00908 INVALID_MATRIX_TEMPLATE_PARAMETERS) 00909 } 00910 00911 enum { IsPlainObjectBase = 1 }; 00912 #endif 00913 }; 00914 00915 namespace internal { 00916 00917 template <typename Derived, typename OtherDerived, bool IsVector> 00918 struct conservative_resize_like_impl 00919 { 00920 static void run(DenseBase<Derived>& _this, Index rows, Index cols) 00921 { 00922 if (_this.rows() == rows && _this.cols() == cols) return; 00923 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) 00924 00925 if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows 00926 (!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns 00927 { 00928 internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols); 00929 _this.derived().m_storage.conservativeResize(rows*cols,rows,cols); 00930 } 00931 else 00932 { 00933 // The storage order does not allow us to use reallocation. 00934 typename Derived::PlainObject tmp(rows,cols); 00935 const Index common_rows = numext::mini(rows, _this.rows()); 00936 const Index common_cols = numext::mini(cols, _this.cols()); 00937 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); 00938 _this.derived().swap(tmp); 00939 } 00940 } 00941 00942 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other) 00943 { 00944 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; 00945 00946 // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index), 00947 // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the 00948 // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or 00949 // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like 00950 // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good. 00951 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) 00952 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived) 00953 00954 if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows 00955 (!Derived::IsRowMajor && _this.rows() == other.rows()) ) // column-major and we change only the number of columns 00956 { 00957 const Index new_rows = other.rows() - _this.rows(); 00958 const Index new_cols = other.cols() - _this.cols(); 00959 _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols()); 00960 if (new_rows>0) 00961 _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows); 00962 else if (new_cols>0) 00963 _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols); 00964 } 00965 else 00966 { 00967 // The storage order does not allow us to use reallocation. 00968 typename Derived::PlainObject tmp(other); 00969 const Index common_rows = numext::mini(tmp.rows(), _this.rows()); 00970 const Index common_cols = numext::mini(tmp.cols(), _this.cols()); 00971 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); 00972 _this.derived().swap(tmp); 00973 } 00974 } 00975 }; 00976 00977 // Here, the specialization for vectors inherits from the general matrix case 00978 // to allow calling .conservativeResize(rows,cols) on vectors. 00979 template <typename Derived, typename OtherDerived> 00980 struct conservative_resize_like_impl<Derived,OtherDerived,true> 00981 : conservative_resize_like_impl<Derived,OtherDerived,false> 00982 { 00983 using conservative_resize_like_impl<Derived,OtherDerived,false>::run; 00984 00985 static void run(DenseBase<Derived>& _this, Index size) 00986 { 00987 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size; 00988 const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1; 00989 _this.derived().m_storage.conservativeResize(size,new_rows,new_cols); 00990 } 00991 00992 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other) 00993 { 00994 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; 00995 00996 const Index num_new_elements = other.size() - _this.size(); 00997 00998 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows(); 00999 const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1; 01000 _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols); 01001 01002 if (num_new_elements > 0) 01003 _this.tail(num_new_elements) = other.tail(num_new_elements); 01004 } 01005 }; 01006 01007 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> 01008 struct matrix_swap_impl 01009 { 01010 EIGEN_DEVICE_FUNC 01011 static inline void run(MatrixTypeA& a, MatrixTypeB& b) 01012 { 01013 a.base().swap(b); 01014 } 01015 }; 01016 01017 template<typename MatrixTypeA, typename MatrixTypeB> 01018 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true> 01019 { 01020 EIGEN_DEVICE_FUNC 01021 static inline void run(MatrixTypeA& a, MatrixTypeB& b) 01022 { 01023 static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage); 01024 } 01025 }; 01026 01027 } // end namespace internal 01028 01029 } // end namespace Eigen 01030 01031 #endif // EIGEN_DENSESTORAGEBASE_H