MOAB
4.9.3pre
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008-2009 Gael Guennebaud <[email protected]> 00005 // Copyright (C) 2006-2008 Benoit Jacob <[email protected]> 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 = (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 00069 #ifdef EIGEN_PARSED_BY_DOXYGEN 00070 namespace internal { 00071 00072 // this is a workaround to doxygen not being able to understand the inheritance logic 00073 // when it is hidden by the dense_xpr_base helper struct. 00075 template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase<Derived> {}; 00077 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> 00078 struct dense_xpr_base_dispatcher_for_doxygen<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > 00079 : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {}; 00081 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> 00082 struct dense_xpr_base_dispatcher_for_doxygen<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > 00083 : public ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {}; 00084 00085 } // namespace internal 00086 00087 template<typename Derived> 00088 class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen<Derived> 00089 #else 00090 template<typename Derived> 00091 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type 00092 #endif 00093 { 00094 public: 00095 enum { Options = internal::traits<Derived>::Options }; 00096 typedef typename internal::dense_xpr_base<Derived>::type Base; 00097 00098 typedef typename internal::traits<Derived>::StorageKind StorageKind; 00099 typedef typename internal::traits<Derived>::Scalar Scalar; 00100 00101 typedef typename internal::packet_traits<Scalar>::type PacketScalar; 00102 typedef typename NumTraits<Scalar>::Real RealScalar; 00103 typedef Derived DenseType; 00104 00105 using Base::RowsAtCompileTime; 00106 using Base::ColsAtCompileTime; 00107 using Base::SizeAtCompileTime; 00108 using Base::MaxRowsAtCompileTime; 00109 using Base::MaxColsAtCompileTime; 00110 using Base::MaxSizeAtCompileTime; 00111 using Base::IsVectorAtCompileTime; 00112 using Base::Flags; 00113 00114 template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map; 00115 friend class Eigen::Map<Derived, Unaligned>; 00116 typedef Eigen::Map<Derived, Unaligned> MapType; 00117 friend class Eigen::Map<const Derived, Unaligned>; 00118 typedef const Eigen::Map<const Derived, Unaligned> ConstMapType; 00119 #if EIGEN_MAX_ALIGN_BYTES>0 00120 // for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice. 00121 friend class Eigen::Map<Derived, AlignedMax>; 00122 friend class Eigen::Map<const Derived, AlignedMax>; 00123 #endif 00124 typedef Eigen::Map<Derived, AlignedMax> AlignedMapType; 00125 typedef const Eigen::Map<const Derived, AlignedMax> ConstAlignedMapType; 00126 template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; }; 00127 template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; }; 00128 template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, AlignedMax, StrideType> type; }; 00129 template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, AlignedMax, StrideType> type; }; 00130 00131 protected: 00132 DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage; 00133 00134 public: 00135 enum { NeedsToAlign = (SizeAtCompileTime != Dynamic) && (internal::traits<Derived>::Alignment>0) }; 00136 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) 00137 00138 EIGEN_DEVICE_FUNC 00139 Base& base() { return *static_cast<Base*>(this); } 00140 EIGEN_DEVICE_FUNC 00141 const Base& base() const { return *static_cast<const Base*>(this); } 00142 00143 EIGEN_DEVICE_FUNC 00144 EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); } 00145 EIGEN_DEVICE_FUNC 00146 EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); } 00147 00148 EIGEN_DEVICE_FUNC 00149 EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const 00150 { 00151 if(Flags & RowMajorBit) 00152 return m_storage.data()[colId + rowId * m_storage.cols()]; 00153 else // column-major 00154 return m_storage.data()[rowId + colId * m_storage.rows()]; 00155 } 00156 00157 EIGEN_DEVICE_FUNC 00158 EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const 00159 { 00160 return m_storage.data()[index]; 00161 } 00162 00163 EIGEN_DEVICE_FUNC 00164 EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId) 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_DEVICE_FUNC 00173 EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) 00174 { 00175 return m_storage.data()[index]; 00176 } 00177 00178 EIGEN_DEVICE_FUNC 00179 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const 00180 { 00181 if(Flags & RowMajorBit) 00182 return m_storage.data()[colId + rowId * m_storage.cols()]; 00183 else // column-major 00184 return m_storage.data()[rowId + colId * m_storage.rows()]; 00185 } 00186 00187 EIGEN_DEVICE_FUNC 00188 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const 00189 { 00190 return m_storage.data()[index]; 00191 } 00192 00194 template<int LoadMode> 00195 EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const 00196 { 00197 return internal::ploadt<PacketScalar, LoadMode> 00198 (m_storage.data() + (Flags & RowMajorBit 00199 ? colId + rowId * m_storage.cols() 00200 : rowId + colId * m_storage.rows())); 00201 } 00202 00204 template<int LoadMode> 00205 EIGEN_STRONG_INLINE PacketScalar packet(Index index) const 00206 { 00207 return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index); 00208 } 00209 00211 template<int StoreMode> 00212 EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val) 00213 { 00214 internal::pstoret<Scalar, PacketScalar, StoreMode> 00215 (m_storage.data() + (Flags & RowMajorBit 00216 ? colId + rowId * m_storage.cols() 00217 : rowId + colId * m_storage.rows()), val); 00218 } 00219 00221 template<int StoreMode> 00222 EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val) 00223 { 00224 internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val); 00225 } 00226 00228 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar *data() const 00229 { return m_storage.data(); } 00230 00232 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar *data() 00233 { return m_storage.data(); } 00234 00251 EIGEN_DEVICE_FUNC 00252 EIGEN_STRONG_INLINE void resize(Index rows, Index cols) 00253 { 00254 eigen_assert( EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,rows==RowsAtCompileTime) 00255 && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,cols==ColsAtCompileTime) 00256 && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,rows<=MaxRowsAtCompileTime) 00257 && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,cols<=MaxColsAtCompileTime) 00258 && rows>=0 && cols>=0 && "Invalid sizes when resizing a matrix or array."); 00259 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(rows, cols); 00260 #ifdef EIGEN_INITIALIZE_COEFFS 00261 Index size = rows*cols; 00262 bool size_changed = size != this->size(); 00263 m_storage.resize(size, rows, cols); 00264 if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00265 #else 00266 m_storage.resize(rows*cols, rows, cols); 00267 #endif 00268 } 00269 00281 EIGEN_DEVICE_FUNC 00282 inline void resize(Index size) 00283 { 00284 EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase) 00285 eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0); 00286 #ifdef EIGEN_INITIALIZE_COEFFS 00287 bool size_changed = size != this->size(); 00288 #endif 00289 if(RowsAtCompileTime == 1) 00290 m_storage.resize(size, 1, size); 00291 else 00292 m_storage.resize(size, size, 1); 00293 #ifdef EIGEN_INITIALIZE_COEFFS 00294 if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00295 #endif 00296 } 00297 00306 EIGEN_DEVICE_FUNC 00307 inline void resize(NoChange_t, Index cols) 00308 { 00309 resize(rows(), cols); 00310 } 00311 00320 EIGEN_DEVICE_FUNC 00321 inline void resize(Index rows, NoChange_t) 00322 { 00323 resize(rows, cols()); 00324 } 00325 00333 template<typename OtherDerived> 00334 EIGEN_DEVICE_FUNC 00335 EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other) 00336 { 00337 const OtherDerived& other = _other.derived(); 00338 internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols()); 00339 const Index othersize = other.rows()*other.cols(); 00340 if(RowsAtCompileTime == 1) 00341 { 00342 eigen_assert(other.rows() == 1 || other.cols() == 1); 00343 resize(1, othersize); 00344 } 00345 else if(ColsAtCompileTime == 1) 00346 { 00347 eigen_assert(other.rows() == 1 || other.cols() == 1); 00348 resize(othersize, 1); 00349 } 00350 else resize(other.rows(), other.cols()); 00351 } 00352 00362 EIGEN_DEVICE_FUNC 00363 EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols) 00364 { 00365 internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols); 00366 } 00367 00375 EIGEN_DEVICE_FUNC 00376 EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t) 00377 { 00378 // Note: see the comment in conservativeResize(Index,Index) 00379 conservativeResize(rows, cols()); 00380 } 00381 00389 EIGEN_DEVICE_FUNC 00390 EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols) 00391 { 00392 // Note: see the comment in conservativeResize(Index,Index) 00393 conservativeResize(rows(), cols); 00394 } 00395 00404 EIGEN_DEVICE_FUNC 00405 EIGEN_STRONG_INLINE void conservativeResize(Index size) 00406 { 00407 internal::conservative_resize_like_impl<Derived>::run(*this, size); 00408 } 00409 00419 template<typename OtherDerived> 00420 EIGEN_DEVICE_FUNC 00421 EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other) 00422 { 00423 internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other); 00424 } 00425 00429 EIGEN_DEVICE_FUNC 00430 EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other) 00431 { 00432 return _set(other); 00433 } 00434 00436 template<typename OtherDerived> 00437 EIGEN_DEVICE_FUNC 00438 EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other) 00439 { 00440 _resize_to_match(other); 00441 return Base::lazyAssign(other.derived()); 00442 } 00443 00444 template<typename OtherDerived> 00445 EIGEN_DEVICE_FUNC 00446 EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func) 00447 { 00448 resize(func.rows(), func.cols()); 00449 return Base::operator=(func); 00450 } 00451 00452 // Prevent user from trying to instantiate PlainObjectBase objects 00453 // by making all its constructor protected. See bug 1074. 00454 protected: 00455 00456 EIGEN_DEVICE_FUNC 00457 EIGEN_STRONG_INLINE PlainObjectBase() : m_storage() 00458 { 00459 // _check_template_params(); 00460 // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00461 } 00462 00463 #ifndef EIGEN_PARSED_BY_DOXYGEN 00464 // FIXME is it still needed ? 00466 EIGEN_DEVICE_FUNC 00467 explicit PlainObjectBase(internal::constructor_without_unaligned_array_assert) 00468 : m_storage(internal::constructor_without_unaligned_array_assert()) 00469 { 00470 // _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00471 } 00472 #endif 00473 00474 #ifdef EIGEN_HAVE_RVALUE_REFERENCES 00475 EIGEN_DEVICE_FUNC 00476 PlainObjectBase(PlainObjectBase&& other) 00477 : m_storage( std::move(other.m_storage) ) 00478 { 00479 } 00480 00481 EIGEN_DEVICE_FUNC 00482 PlainObjectBase& operator=(PlainObjectBase&& other) 00483 { 00484 using std::swap; 00485 swap(m_storage, other.m_storage); 00486 return *this; 00487 } 00488 #endif 00489 00491 EIGEN_DEVICE_FUNC 00492 EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other) 00493 : Base(), m_storage(other.m_storage) { } 00494 EIGEN_DEVICE_FUNC 00495 EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols) 00496 : m_storage(size, rows, cols) 00497 { 00498 // _check_template_params(); 00499 // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED 00500 } 00501 00503 template<typename OtherDerived> 00504 EIGEN_DEVICE_FUNC 00505 EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other) 00506 : m_storage() 00507 { 00508 _check_template_params(); 00509 resizeLike(other); 00510 _set_noalias(other); 00511 } 00512 00514 template<typename OtherDerived> 00515 EIGEN_DEVICE_FUNC 00516 EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other) 00517 : m_storage() 00518 { 00519 _check_template_params(); 00520 resizeLike(other); 00521 *this = other.derived(); 00522 } 00524 template<typename OtherDerived> 00525 EIGEN_DEVICE_FUNC 00526 EIGEN_STRONG_INLINE PlainObjectBase(const ReturnByValue<OtherDerived>& other) 00527 { 00528 _check_template_params(); 00529 // FIXME this does not automatically transpose vectors if necessary 00530 resize(other.rows(), other.cols()); 00531 other.evalTo(this->derived()); 00532 } 00533 00534 public: 00535 00538 template<typename OtherDerived> 00539 EIGEN_DEVICE_FUNC 00540 EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other) 00541 { 00542 _resize_to_match(other); 00543 Base::operator=(other.derived()); 00544 return this->derived(); 00545 } 00546 00555 static inline ConstMapType Map(const Scalar* data) 00556 { return ConstMapType(data); } 00557 static inline MapType Map(Scalar* data) 00558 { return MapType(data); } 00559 static inline ConstMapType Map(const Scalar* data, Index size) 00560 { return ConstMapType(data, size); } 00561 static inline MapType Map(Scalar* data, Index size) 00562 { return MapType(data, size); } 00563 static inline ConstMapType Map(const Scalar* data, Index rows, Index cols) 00564 { return ConstMapType(data, rows, cols); } 00565 static inline MapType Map(Scalar* data, Index rows, Index cols) 00566 { return MapType(data, rows, cols); } 00567 00568 static inline ConstAlignedMapType MapAligned(const Scalar* data) 00569 { return ConstAlignedMapType(data); } 00570 static inline AlignedMapType MapAligned(Scalar* data) 00571 { return AlignedMapType(data); } 00572 static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size) 00573 { return ConstAlignedMapType(data, size); } 00574 static inline AlignedMapType MapAligned(Scalar* data, Index size) 00575 { return AlignedMapType(data, size); } 00576 static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols) 00577 { return ConstAlignedMapType(data, rows, cols); } 00578 static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols) 00579 { return AlignedMapType(data, rows, cols); } 00580 00581 template<int Outer, int Inner> 00582 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride) 00583 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); } 00584 template<int Outer, int Inner> 00585 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride) 00586 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); } 00587 template<int Outer, int Inner> 00588 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride) 00589 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); } 00590 template<int Outer, int Inner> 00591 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride) 00592 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); } 00593 template<int Outer, int Inner> 00594 static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) 00595 { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } 00596 template<int Outer, int Inner> 00597 static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) 00598 { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } 00599 00600 template<int Outer, int Inner> 00601 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride) 00602 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); } 00603 template<int Outer, int Inner> 00604 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride) 00605 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); } 00606 template<int Outer, int Inner> 00607 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride) 00608 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); } 00609 template<int Outer, int Inner> 00610 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride) 00611 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); } 00612 template<int Outer, int Inner> 00613 static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) 00614 { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } 00615 template<int Outer, int Inner> 00616 static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride) 00617 { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); } 00619 00620 using Base::setConstant; 00621 EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& val); 00622 EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& val); 00623 00624 using Base::setZero; 00625 EIGEN_DEVICE_FUNC Derived& setZero(Index size); 00626 EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols); 00627 00628 using Base::setOnes; 00629 EIGEN_DEVICE_FUNC Derived& setOnes(Index size); 00630 EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols); 00631 00632 using Base::setRandom; 00633 Derived& setRandom(Index size); 00634 Derived& setRandom(Index rows, Index cols); 00635 00636 #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN 00637 #include EIGEN_PLAINOBJECTBASE_PLUGIN 00638 #endif 00639 00640 protected: 00648 template<typename OtherDerived> 00649 EIGEN_DEVICE_FUNC 00650 EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other) 00651 { 00652 #ifdef EIGEN_NO_AUTOMATIC_RESIZING 00653 eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size()) 00654 : (rows() == other.rows() && cols() == other.cols()))) 00655 && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); 00656 EIGEN_ONLY_USED_FOR_DEBUG(other); 00657 #else 00658 resizeLike(other); 00659 #endif 00660 } 00661 00676 // aliasing is dealt once in internall::call_assignment 00677 // so at this stage we have to assume aliasing... and resising has to be done later. 00678 template<typename OtherDerived> 00679 EIGEN_DEVICE_FUNC 00680 EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other) 00681 { 00682 internal::call_assignment(this->derived(), other.derived()); 00683 return this->derived(); 00684 } 00685 00691 template<typename OtherDerived> 00692 EIGEN_DEVICE_FUNC 00693 EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other) 00694 { 00695 // I don't think we need this resize call since the lazyAssign will anyways resize 00696 // and lazyAssign will be called by the assign selector. 00697 //_resize_to_match(other); 00698 // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because 00699 // it wouldn't allow to copy a row-vector into a column-vector. 00700 internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op<Scalar>()); 00701 return this->derived(); 00702 } 00703 00704 template<typename T0, typename T1> 00705 EIGEN_DEVICE_FUNC 00706 EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0) 00707 { 00708 EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) && 00709 bool(NumTraits<T1>::IsInteger), 00710 FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) 00711 resize(rows,cols); 00712 } 00713 00714 template<typename T0, typename T1> 00715 EIGEN_DEVICE_FUNC 00716 EIGEN_STRONG_INLINE void _init2(const Scalar& val0, const Scalar& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0) 00717 { 00718 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2) 00719 m_storage.data()[0] = val0; 00720 m_storage.data()[1] = val1; 00721 } 00722 00723 template<typename T0, typename T1> 00724 EIGEN_DEVICE_FUNC 00725 EIGEN_STRONG_INLINE void _init2(const Index& val0, const Index& val1, 00726 typename internal::enable_if< (!internal::is_same<Index,Scalar>::value) 00727 && (internal::is_same<T0,Index>::value) 00728 && (internal::is_same<T1,Index>::value) 00729 && Base::SizeAtCompileTime==2,T1>::type* = 0) 00730 { 00731 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2) 00732 m_storage.data()[0] = Scalar(val0); 00733 m_storage.data()[1] = Scalar(val1); 00734 } 00735 00736 // The argument is convertible to the Index type and we either have a non 1x1 Matrix, or a dynamic-sized Array, 00737 // then the argument is meant to be the size of the object. 00738 template<typename T> 00739 EIGEN_DEVICE_FUNC 00740 EIGEN_STRONG_INLINE void _init1(Index size, typename internal::enable_if< (Base::SizeAtCompileTime!=1 || !internal::is_convertible<T, Scalar>::value) 00741 && ((!internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0) 00742 { 00743 // NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument. 00744 const bool is_integer = NumTraits<T>::IsInteger; 00745 EIGEN_STATIC_ASSERT(is_integer, 00746 FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) 00747 resize(size); 00748 } 00749 00750 // 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) 00751 template<typename T> 00752 EIGEN_DEVICE_FUNC 00753 EIGEN_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0) 00754 { 00755 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1) 00756 m_storage.data()[0] = val0; 00757 } 00758 00759 // 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) 00760 template<typename T> 00761 EIGEN_DEVICE_FUNC 00762 EIGEN_STRONG_INLINE void _init1(const Index& val0, 00763 typename internal::enable_if< (!internal::is_same<Index,Scalar>::value) 00764 && (internal::is_same<Index,T>::value) 00765 && Base::SizeAtCompileTime==1 00766 && internal::is_convertible<T, Scalar>::value,T*>::type* = 0) 00767 { 00768 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1) 00769 m_storage.data()[0] = Scalar(val0); 00770 } 00771 00772 // Initialize a fixed size matrix from a pointer to raw data 00773 template<typename T> 00774 EIGEN_DEVICE_FUNC 00775 EIGEN_STRONG_INLINE void _init1(const Scalar* data){ 00776 this->_set_noalias(ConstMapType(data)); 00777 } 00778 00779 // Initialize an arbitrary matrix from a dense expression 00780 template<typename T, typename OtherDerived> 00781 EIGEN_DEVICE_FUNC 00782 EIGEN_STRONG_INLINE void _init1(const DenseBase<OtherDerived>& other){ 00783 this->_set_noalias(other); 00784 } 00785 00786 // Initialize an arbitrary matrix from a generic Eigen expression 00787 template<typename T, typename OtherDerived> 00788 EIGEN_DEVICE_FUNC 00789 EIGEN_STRONG_INLINE void _init1(const EigenBase<OtherDerived>& other){ 00790 this->derived() = other; 00791 } 00792 00793 template<typename T, typename OtherDerived> 00794 EIGEN_DEVICE_FUNC 00795 EIGEN_STRONG_INLINE void _init1(const ReturnByValue<OtherDerived>& other) 00796 { 00797 resize(other.rows(), other.cols()); 00798 other.evalTo(this->derived()); 00799 } 00800 00801 template<typename T, typename OtherDerived, int ColsAtCompileTime> 00802 EIGEN_DEVICE_FUNC 00803 EIGEN_STRONG_INLINE void _init1(const RotationBase<OtherDerived,ColsAtCompileTime>& r) 00804 { 00805 this->derived() = r; 00806 } 00807 00808 // For fixed -size arrays: 00809 template<typename T> 00810 EIGEN_DEVICE_FUNC 00811 EIGEN_STRONG_INLINE void _init1(const Scalar& val0, 00812 typename internal::enable_if< Base::SizeAtCompileTime!=Dynamic 00813 && Base::SizeAtCompileTime!=1 00814 && internal::is_convertible<T, Scalar>::value 00815 && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T>::type* = 0) 00816 { 00817 Base::setConstant(val0); 00818 } 00819 00820 template<typename T> 00821 EIGEN_DEVICE_FUNC 00822 EIGEN_STRONG_INLINE void _init1(const Index& val0, 00823 typename internal::enable_if< (!internal::is_same<Index,Scalar>::value) 00824 && (internal::is_same<Index,T>::value) 00825 && Base::SizeAtCompileTime!=Dynamic 00826 && Base::SizeAtCompileTime!=1 00827 && internal::is_convertible<T, Scalar>::value 00828 && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T*>::type* = 0) 00829 { 00830 Base::setConstant(val0); 00831 } 00832 00833 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> 00834 friend struct internal::matrix_swap_impl; 00835 00836 public: 00837 00838 #ifndef EIGEN_PARSED_BY_DOXYGEN 00839 00843 template<typename OtherDerived> 00844 EIGEN_DEVICE_FUNC 00845 void swap(DenseBase<OtherDerived> & other) 00846 { 00847 enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic }; 00848 internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.derived()); 00849 } 00850 00854 template<typename OtherDerived> 00855 EIGEN_DEVICE_FUNC 00856 void swap(DenseBase<OtherDerived> const & other) 00857 { Base::swap(other.derived()); } 00858 00859 EIGEN_DEVICE_FUNC 00860 static EIGEN_STRONG_INLINE void _check_template_params() 00861 { 00862 EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor) 00863 && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0) 00864 && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0)) 00865 && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0)) 00866 && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0)) 00867 && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0)) 00868 && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic) 00869 && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic) 00870 && (Options & (DontAlign|RowMajor)) == Options), 00871 INVALID_MATRIX_TEMPLATE_PARAMETERS) 00872 } 00873 00874 enum { IsPlainObjectBase = 1 }; 00875 #endif 00876 }; 00877 00878 namespace internal { 00879 00880 template <typename Derived, typename OtherDerived, bool IsVector> 00881 struct conservative_resize_like_impl 00882 { 00883 static void run(DenseBase<Derived>& _this, Index rows, Index cols) 00884 { 00885 if (_this.rows() == rows && _this.cols() == cols) return; 00886 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) 00887 00888 if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows 00889 (!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns 00890 { 00891 internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols); 00892 _this.derived().m_storage.conservativeResize(rows*cols,rows,cols); 00893 } 00894 else 00895 { 00896 // The storage order does not allow us to use reallocation. 00897 typename Derived::PlainObject tmp(rows,cols); 00898 const Index common_rows = (std::min)(rows, _this.rows()); 00899 const Index common_cols = (std::min)(cols, _this.cols()); 00900 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); 00901 _this.derived().swap(tmp); 00902 } 00903 } 00904 00905 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other) 00906 { 00907 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; 00908 00909 // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index), 00910 // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the 00911 // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or 00912 // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like 00913 // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good. 00914 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) 00915 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived) 00916 00917 if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows 00918 (!Derived::IsRowMajor && _this.rows() == other.rows()) ) // column-major and we change only the number of columns 00919 { 00920 const Index new_rows = other.rows() - _this.rows(); 00921 const Index new_cols = other.cols() - _this.cols(); 00922 _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols()); 00923 if (new_rows>0) 00924 _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows); 00925 else if (new_cols>0) 00926 _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols); 00927 } 00928 else 00929 { 00930 // The storage order does not allow us to use reallocation. 00931 typename Derived::PlainObject tmp(other); 00932 const Index common_rows = (std::min)(tmp.rows(), _this.rows()); 00933 const Index common_cols = (std::min)(tmp.cols(), _this.cols()); 00934 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); 00935 _this.derived().swap(tmp); 00936 } 00937 } 00938 }; 00939 00940 // Here, the specialization for vectors inherits from the general matrix case 00941 // to allow calling .conservativeResize(rows,cols) on vectors. 00942 template <typename Derived, typename OtherDerived> 00943 struct conservative_resize_like_impl<Derived,OtherDerived,true> 00944 : conservative_resize_like_impl<Derived,OtherDerived,false> 00945 { 00946 using conservative_resize_like_impl<Derived,OtherDerived,false>::run; 00947 00948 static void run(DenseBase<Derived>& _this, Index size) 00949 { 00950 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size; 00951 const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1; 00952 _this.derived().m_storage.conservativeResize(size,new_rows,new_cols); 00953 } 00954 00955 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other) 00956 { 00957 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; 00958 00959 const Index num_new_elements = other.size() - _this.size(); 00960 00961 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows(); 00962 const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1; 00963 _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols); 00964 00965 if (num_new_elements > 0) 00966 _this.tail(num_new_elements) = other.tail(num_new_elements); 00967 } 00968 }; 00969 00970 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> 00971 struct matrix_swap_impl 00972 { 00973 EIGEN_DEVICE_FUNC 00974 static inline void run(MatrixTypeA& a, MatrixTypeB& b) 00975 { 00976 a.base().swap(b); 00977 } 00978 }; 00979 00980 template<typename MatrixTypeA, typename MatrixTypeB> 00981 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true> 00982 { 00983 EIGEN_DEVICE_FUNC 00984 static inline void run(MatrixTypeA& a, MatrixTypeB& b) 00985 { 00986 static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage); 00987 } 00988 }; 00989 00990 } // end namespace internal 00991 00992 } // end namespace Eigen 00993 00994 #endif // EIGEN_DENSESTORAGEBASE_H