00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef EIGEN_DENSESTORAGEBASE_H
00027 #define EIGEN_DENSESTORAGEBASE_H
00028
00029 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00030 # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
00031 #else
00032 # define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00033 #endif
00034
00035 template <typename Derived, typename OtherDerived = Derived, bool IsVector = static_cast<bool>(Derived::IsVectorAtCompileTime)> struct ei_conservative_resize_like_impl;
00036 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct ei_matrix_swap_impl;
00037
00042 template<typename Derived>
00043 class DenseStorageBase : public ei_dense_xpr_base<Derived>::type
00044 {
00045 public:
00046 enum { Options = ei_traits<Derived>::Options };
00047 typedef typename ei_dense_xpr_base<Derived>::type Base;
00048
00049 typedef typename ei_traits<Derived>::StorageKind StorageKind;
00050 typedef typename ei_traits<Derived>::Index Index;
00051 typedef typename ei_traits<Derived>::Scalar Scalar;
00052 typedef typename ei_packet_traits<Scalar>::type PacketScalar;
00053 typedef typename NumTraits<Scalar>::Real RealScalar;
00054
00055 using Base::RowsAtCompileTime;
00056 using Base::ColsAtCompileTime;
00057 using Base::SizeAtCompileTime;
00058 using Base::MaxRowsAtCompileTime;
00059 using Base::MaxColsAtCompileTime;
00060 using Base::MaxSizeAtCompileTime;
00061 using Base::IsVectorAtCompileTime;
00062 using Base::Flags;
00063
00064 friend class Eigen::Map<Derived, Unaligned>;
00065 typedef class Eigen::Map<Derived, Unaligned> UnalignedMapType;
00066 friend class Eigen::Map<Derived, Aligned>;
00067 typedef class Eigen::Map<Derived, Aligned> AlignedMapType;
00068
00069 protected:
00070 ei_matrix_storage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
00071
00072 public:
00073 enum { NeedsToAlign = (!(Options&DontAlign))
00074 && SizeAtCompileTime!=Dynamic && ((static_cast<int>(sizeof(Scalar))*SizeAtCompileTime)%16)==0 };
00075 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
00076
00077 Base& base() { return *static_cast<Base*>(this); }
00078 const Base& base() const { return *static_cast<const Base*>(this); }
00079
00080 EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
00081 EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
00082
00083 EIGEN_STRONG_INLINE const Scalar& coeff(Index row, Index col) const
00084 {
00085 if(Flags & RowMajorBit)
00086 return m_storage.data()[col + row * m_storage.cols()];
00087 else
00088 return m_storage.data()[row + col * m_storage.rows()];
00089 }
00090
00091 EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
00092 {
00093 return m_storage.data()[index];
00094 }
00095
00096 EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
00097 {
00098 if(Flags & RowMajorBit)
00099 return m_storage.data()[col + row * m_storage.cols()];
00100 else
00101 return m_storage.data()[row + col * m_storage.rows()];
00102 }
00103
00104 EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
00105 {
00106 return m_storage.data()[index];
00107 }
00108
00109 template<int LoadMode>
00110 EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
00111 {
00112 return ei_ploadt<PacketScalar, LoadMode>
00113 (m_storage.data() + (Flags & RowMajorBit
00114 ? col + row * m_storage.cols()
00115 : row + col * m_storage.rows()));
00116 }
00117
00118 template<int LoadMode>
00119 EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
00120 {
00121 return ei_ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
00122 }
00123
00124 template<int StoreMode>
00125 EIGEN_STRONG_INLINE void writePacket(Index row, Index col, const PacketScalar& x)
00126 {
00127 ei_pstoret<Scalar, PacketScalar, StoreMode>
00128 (m_storage.data() + (Flags & RowMajorBit
00129 ? col + row * m_storage.cols()
00130 : row + col * m_storage.rows()), x);
00131 }
00132
00133 template<int StoreMode>
00134 EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& x)
00135 {
00136 ei_pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x);
00137 }
00138
00140 EIGEN_STRONG_INLINE const Scalar *data() const
00141 { return m_storage.data(); }
00142
00144 EIGEN_STRONG_INLINE Scalar *data()
00145 { return m_storage.data(); }
00146
00163 EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
00164 {
00165 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00166 Index size = rows*cols;
00167 bool size_changed = size != this->size();
00168 m_storage.resize(size, rows, cols);
00169 if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00170 #else
00171 m_storage.resize(rows*cols, rows, cols);
00172 #endif
00173 }
00174
00186 inline void resize(Index size)
00187 {
00188 EIGEN_STATIC_ASSERT_VECTOR_ONLY(DenseStorageBase)
00189 ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
00190 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00191 bool size_changed = size != this->size();
00192 #endif
00193 if(RowsAtCompileTime == 1)
00194 m_storage.resize(size, 1, size);
00195 else
00196 m_storage.resize(size, size, 1);
00197 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00198 if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00199 #endif
00200 }
00201
00210 inline void resize(NoChange_t, Index cols)
00211 {
00212 resize(rows(), cols);
00213 }
00214
00223 inline void resize(Index rows, NoChange_t)
00224 {
00225 resize(rows, cols());
00226 }
00227
00235 template<typename OtherDerived>
00236 EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
00237 {
00238 const OtherDerived& other = _other.derived();
00239 const Index othersize = other.rows()*other.cols();
00240 if(RowsAtCompileTime == 1)
00241 {
00242 ei_assert(other.rows() == 1 || other.cols() == 1);
00243 resize(1, othersize);
00244 }
00245 else if(ColsAtCompileTime == 1)
00246 {
00247 ei_assert(other.rows() == 1 || other.cols() == 1);
00248 resize(othersize, 1);
00249 }
00250 else resize(other.rows(), other.cols());
00251 }
00252
00262 EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
00263 {
00264 ei_conservative_resize_like_impl<Derived>::run(*this, rows, cols);
00265 }
00266
00267 EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
00268 {
00269
00270 conservativeResize(rows, cols());
00271 }
00272
00273 EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
00274 {
00275
00276 conservativeResize(rows(), cols);
00277 }
00278
00287 EIGEN_STRONG_INLINE void conservativeResize(Index size)
00288 {
00289 ei_conservative_resize_like_impl<Derived>::run(*this, size);
00290 }
00291
00292 template<typename OtherDerived>
00293 EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
00294 {
00295 ei_conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
00296 }
00297
00301 EIGEN_STRONG_INLINE Derived& operator=(const DenseStorageBase& other)
00302 {
00303 return _set(other);
00304 }
00305
00307 template<typename OtherDerived>
00308 EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
00309 {
00310 _resize_to_match(other);
00311 return Base::lazyAssign(other.derived());
00312 }
00313
00314 template<typename OtherDerived>
00315 EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
00316 {
00317 resize(func.rows(), func.cols());
00318 return Base::operator=(func);
00319 }
00320
00321 EIGEN_STRONG_INLINE explicit DenseStorageBase() : m_storage()
00322 {
00323
00324
00325 }
00326
00327 #ifndef EIGEN_PARSED_BY_DOXYGEN
00328
00330 DenseStorageBase(ei_constructor_without_unaligned_array_assert)
00331 : m_storage(ei_constructor_without_unaligned_array_assert())
00332 {
00333
00334 }
00335 #endif
00336
00337 EIGEN_STRONG_INLINE DenseStorageBase(Index size, Index rows, Index cols)
00338 : m_storage(size, rows, cols)
00339 {
00340
00341
00342 }
00343
00346 template<typename OtherDerived>
00347 EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
00348 {
00349 _resize_to_match(other);
00350 Base::operator=(other.derived());
00351 return this->derived();
00352 }
00353
00355 template<typename OtherDerived>
00356 EIGEN_STRONG_INLINE DenseStorageBase(const EigenBase<OtherDerived> &other)
00357 : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
00358 {
00359 _check_template_params();
00360 Base::operator=(other.derived());
00361 }
00362
00374 inline static const UnalignedMapType Map(const Scalar* data)
00375 { return UnalignedMapType(data); }
00376 inline static UnalignedMapType Map(Scalar* data)
00377 { return UnalignedMapType(data); }
00378 inline static const UnalignedMapType Map(const Scalar* data, Index size)
00379 { return UnalignedMapType(data, size); }
00380 inline static UnalignedMapType Map(Scalar* data, Index size)
00381 { return UnalignedMapType(data, size); }
00382 inline static const UnalignedMapType Map(const Scalar* data, Index rows, Index cols)
00383 { return UnalignedMapType(data, rows, cols); }
00384 inline static UnalignedMapType Map(Scalar* data, Index rows, Index cols)
00385 { return UnalignedMapType(data, rows, cols); }
00386
00387 inline static const AlignedMapType MapAligned(const Scalar* data)
00388 { return AlignedMapType(data); }
00389 inline static AlignedMapType MapAligned(Scalar* data)
00390 { return AlignedMapType(data); }
00391 inline static const AlignedMapType MapAligned(const Scalar* data, Index size)
00392 { return AlignedMapType(data, size); }
00393 inline static AlignedMapType MapAligned(Scalar* data, Index size)
00394 { return AlignedMapType(data, size); }
00395 inline static const AlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
00396 { return AlignedMapType(data, rows, cols); }
00397 inline static AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
00398 { return AlignedMapType(data, rows, cols); }
00400
00401 using Base::setConstant;
00402 Derived& setConstant(Index size, const Scalar& value);
00403 Derived& setConstant(Index rows, Index cols, const Scalar& value);
00404
00405 using Base::setZero;
00406 Derived& setZero(Index size);
00407 Derived& setZero(Index rows, Index cols);
00408
00409 using Base::setOnes;
00410 Derived& setOnes(Index size);
00411 Derived& setOnes(Index rows, Index cols);
00412
00413 using Base::setRandom;
00414 Derived& setRandom(Index size);
00415 Derived& setRandom(Index rows, Index cols);
00416
00417 #ifdef EIGEN_DENSESTORAGEBASE_PLUGIN
00418 #include EIGEN_DENSESTORAGEBASE_PLUGIN
00419 #endif
00420
00421 protected:
00429 template<typename OtherDerived>
00430 EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
00431 {
00432 #ifdef EIGEN_NO_AUTOMATIC_RESIZING
00433 ei_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
00434 : (rows() == other.rows() && cols() == other.cols())))
00435 && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
00436 #else
00437 resizeLike(other);
00438 #endif
00439 }
00440
00455 template<typename OtherDerived>
00456 EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
00457 {
00458 _set_selector(other.derived(), typename ei_meta_if<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), ei_meta_true, ei_meta_false>::ret());
00459 return this->derived();
00460 }
00461
00462 template<typename OtherDerived>
00463 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const ei_meta_true&) { _set_noalias(other.eval()); }
00464
00465 template<typename OtherDerived>
00466 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const ei_meta_false&) { _set_noalias(other); }
00467
00473 template<typename OtherDerived>
00474 EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
00475 {
00476
00477
00478
00479
00480
00481 return ei_assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived());
00482 }
00483
00484 template<typename T0, typename T1>
00485 EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename ei_enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
00486 {
00487 ei_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
00488 && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
00489 m_storage.resize(rows*cols,rows,cols);
00490 EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00491 }
00492 template<typename T0, typename T1>
00493 EIGEN_STRONG_INLINE void _init2(const Scalar& x, const Scalar& y, typename ei_enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
00494 {
00495 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(DenseStorageBase, 2)
00496 m_storage.data()[0] = x;
00497 m_storage.data()[1] = y;
00498 }
00499
00500 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00501 friend struct ei_matrix_swap_impl;
00502
00506 template<typename OtherDerived>
00507 void _swap(DenseBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other)
00508 {
00509 enum { SwapPointers = ei_is_same_type<Derived, OtherDerived>::ret && Base::SizeAtCompileTime==Dynamic };
00510 ei_matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived());
00511 }
00512
00513 public:
00514 #ifndef EIGEN_PARSED_BY_DOXYGEN
00515 EIGEN_STRONG_INLINE static void _check_template_params()
00516 {
00517 EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
00518 && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
00519 && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
00520 && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
00521 && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
00522 && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
00523 && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
00524 && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
00525 && (Options & (DontAlign|RowMajor)) == Options),
00526 INVALID_MATRIX_TEMPLATE_PARAMETERS)
00527 }
00528 #endif
00529 };
00530
00531 template <typename Derived, typename OtherDerived, bool IsVector>
00532 struct ei_conservative_resize_like_impl
00533 {
00534 typedef typename Derived::Index Index;
00535 static void run(DenseBase<Derived>& _this, Index rows, Index cols)
00536 {
00537 if (_this.rows() == rows && _this.cols() == cols) return;
00538 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00539
00540 if ( ( Derived::IsRowMajor && _this.cols() == cols) ||
00541 (!Derived::IsRowMajor && _this.rows() == rows) )
00542 {
00543 _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
00544 }
00545 else
00546 {
00547
00548 typename Derived::PlainObject tmp(rows,cols);
00549 const Index common_rows = std::min(rows, _this.rows());
00550 const Index common_cols = std::min(cols, _this.cols());
00551 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00552 _this.derived().swap(tmp);
00553 }
00554 }
00555
00556 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00557 {
00558 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00559
00560
00561
00562
00563
00564
00565 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00566 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
00567
00568 if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) ||
00569 (!Derived::IsRowMajor && _this.rows() == other.rows()) )
00570 {
00571 const Index new_rows = other.rows() - _this.rows();
00572 const Index new_cols = other.cols() - _this.cols();
00573 _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
00574 if (new_rows>0)
00575 _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
00576 else if (new_cols>0)
00577 _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
00578 }
00579 else
00580 {
00581
00582 typename Derived::PlainObject tmp(other);
00583 const Index common_rows = std::min(tmp.rows(), _this.rows());
00584 const Index common_cols = std::min(tmp.cols(), _this.cols());
00585 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00586 _this.derived().swap(tmp);
00587 }
00588 }
00589 };
00590
00591 template <typename Derived, typename OtherDerived>
00592 struct ei_conservative_resize_like_impl<Derived,OtherDerived,true>
00593 {
00594 typedef typename Derived::Index Index;
00595 static void run(DenseBase<Derived>& _this, Index size)
00596 {
00597 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
00598 const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
00599 _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
00600 }
00601
00602 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00603 {
00604 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00605
00606 const Index num_new_elements = other.size() - _this.size();
00607
00608 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
00609 const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
00610 _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
00611
00612 if (num_new_elements > 0)
00613 _this.tail(num_new_elements) = other.tail(num_new_elements);
00614 }
00615 };
00616
00617 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00618 struct ei_matrix_swap_impl
00619 {
00620 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00621 {
00622 a.base().swap(b);
00623 }
00624 };
00625
00626 template<typename MatrixTypeA, typename MatrixTypeB>
00627 struct ei_matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
00628 {
00629 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00630 {
00631 static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
00632 }
00633 };
00634
00635 #endif // EIGEN_DENSESTORAGEBASE_H