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 namespace internal {
00036
00037 template <typename Derived, typename OtherDerived = Derived, bool IsVector = static_cast<bool>(Derived::IsVectorAtCompileTime)> struct conservative_resize_like_impl;
00038
00039 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
00040
00041 }
00042
00043
00044
00045
00046
00047 template<typename Derived>
00048 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
00049 {
00050 public:
00051 enum { Options = internal::traits<Derived>::Options };
00052 typedef typename internal::dense_xpr_base<Derived>::type Base;
00053
00054 typedef typename internal::traits<Derived>::StorageKind StorageKind;
00055 typedef typename internal::traits<Derived>::Index Index;
00056 typedef typename internal::traits<Derived>::Scalar Scalar;
00057 typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00058 typedef typename NumTraits<Scalar>::Real RealScalar;
00059
00060 using Base::RowsAtCompileTime;
00061 using Base::ColsAtCompileTime;
00062 using Base::SizeAtCompileTime;
00063 using Base::MaxRowsAtCompileTime;
00064 using Base::MaxColsAtCompileTime;
00065 using Base::MaxSizeAtCompileTime;
00066 using Base::IsVectorAtCompileTime;
00067 using Base::Flags;
00068
00069 friend class Eigen::Map<Derived, Unaligned>;
00070 typedef Eigen::Map<Derived, Unaligned> MapType;
00071 friend class Eigen::Map<const Derived, Unaligned>;
00072 typedef const Eigen::Map<const Derived, Unaligned> ConstMapType;
00073 friend class Eigen::Map<Derived, Aligned>;
00074 typedef Eigen::Map<Derived, Aligned> AlignedMapType;
00075 friend class Eigen::Map<const Derived, Aligned>;
00076 typedef const Eigen::Map<const Derived, Aligned> ConstAlignedMapType;
00077
00078 protected:
00079 DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
00080
00081 public:
00082 enum { NeedsToAlign = (!(Options&DontAlign))
00083 && SizeAtCompileTime!=Dynamic && ((static_cast<int>(sizeof(Scalar))*SizeAtCompileTime)%16)==0 };
00084 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
00085
00086 Base& base() { return *static_cast<Base*>(this); }
00087 const Base& base() const { return *static_cast<const Base*>(this); }
00088
00089 EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
00090 EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
00091
00092 EIGEN_STRONG_INLINE const Scalar& coeff(Index row, Index col) const
00093 {
00094 if(Flags & RowMajorBit)
00095 return m_storage.data()[col + row * m_storage.cols()];
00096 else
00097 return m_storage.data()[row + col * m_storage.rows()];
00098 }
00099
00100 EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
00101 {
00102 return m_storage.data()[index];
00103 }
00104
00105 EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
00106 {
00107 if(Flags & RowMajorBit)
00108 return m_storage.data()[col + row * m_storage.cols()];
00109 else
00110 return m_storage.data()[row + col * m_storage.rows()];
00111 }
00112
00113 EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
00114 {
00115 return m_storage.data()[index];
00116 }
00117
00118 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index row, Index col) const
00119 {
00120 if(Flags & RowMajorBit)
00121 return m_storage.data()[col + row * m_storage.cols()];
00122 else
00123 return m_storage.data()[row + col * m_storage.rows()];
00124 }
00125
00126 EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
00127 {
00128 return m_storage.data()[index];
00129 }
00130
00131 template<int LoadMode>
00132 EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
00133 {
00134 return internal::ploadt<PacketScalar, LoadMode>
00135 (m_storage.data() + (Flags & RowMajorBit
00136 ? col + row * m_storage.cols()
00137 : row + col * m_storage.rows()));
00138 }
00139
00140 template<int LoadMode>
00141 EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
00142 {
00143 return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
00144 }
00145
00146 template<int StoreMode>
00147 EIGEN_STRONG_INLINE void writePacket(Index row, Index col, const PacketScalar& x)
00148 {
00149 internal::pstoret<Scalar, PacketScalar, StoreMode>
00150 (m_storage.data() + (Flags & RowMajorBit
00151 ? col + row * m_storage.cols()
00152 : row + col * m_storage.rows()), x);
00153 }
00154
00155 template<int StoreMode>
00156 EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& x)
00157 {
00158 internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x);
00159 }
00160
00161
00162 EIGEN_STRONG_INLINE const Scalar *data() const
00163 { return m_storage.data(); }
00164
00165
00166 EIGEN_STRONG_INLINE Scalar *data()
00167 { return m_storage.data(); }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
00186 {
00187 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00188 Index size = rows*cols;
00189 bool size_changed = size != this->size();
00190 m_storage.resize(size, rows, cols);
00191 if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00192 #else
00193 m_storage.resize(rows*cols, rows, cols);
00194 #endif
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 inline void resize(Index size)
00209 {
00210 EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
00211 eigen_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
00212 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00213 bool size_changed = size != this->size();
00214 #endif
00215 if(RowsAtCompileTime == 1)
00216 m_storage.resize(size, 1, size);
00217 else
00218 m_storage.resize(size, size, 1);
00219 #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO
00220 if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00221 #endif
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 inline void resize(NoChange_t, Index cols)
00233 {
00234 resize(rows(), cols);
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 inline void resize(Index rows, NoChange_t)
00246 {
00247 resize(rows, cols());
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257 template<typename OtherDerived>
00258 EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
00259 {
00260 const OtherDerived& other = _other.derived();
00261 const Index othersize = other.rows()*other.cols();
00262 if(RowsAtCompileTime == 1)
00263 {
00264 eigen_assert(other.rows() == 1 || other.cols() == 1);
00265 resize(1, othersize);
00266 }
00267 else if(ColsAtCompileTime == 1)
00268 {
00269 eigen_assert(other.rows() == 1 || other.cols() == 1);
00270 resize(othersize, 1);
00271 }
00272 else resize(other.rows(), other.cols());
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
00285 {
00286 internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
00287 }
00288
00289 EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
00290 {
00291
00292 conservativeResize(rows, cols());
00293 }
00294
00295 EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
00296 {
00297
00298 conservativeResize(rows(), cols);
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 EIGEN_STRONG_INLINE void conservativeResize(Index size)
00310 {
00311 internal::conservative_resize_like_impl<Derived>::run(*this, size);
00312 }
00313
00314 template<typename OtherDerived>
00315 EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
00316 {
00317 internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
00318 }
00319
00320
00321
00322
00323 EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
00324 {
00325 return _set(other);
00326 }
00327
00328
00329 template<typename OtherDerived>
00330 EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
00331 {
00332 _resize_to_match(other);
00333 return Base::lazyAssign(other.derived());
00334 }
00335
00336 template<typename OtherDerived>
00337 EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
00338 {
00339 resize(func.rows(), func.cols());
00340 return Base::operator=(func);
00341 }
00342
00343 EIGEN_STRONG_INLINE explicit PlainObjectBase() : m_storage()
00344 {
00345
00346
00347 }
00348
00349 #ifndef EIGEN_PARSED_BY_DOXYGEN
00350
00351
00352 PlainObjectBase(internal::constructor_without_unaligned_array_assert)
00353 : m_storage(internal::constructor_without_unaligned_array_assert())
00354 {
00355
00356 }
00357 #endif
00358
00359 EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
00360 : m_storage(size, rows, cols)
00361 {
00362
00363
00364 }
00365
00366
00367
00368 template<typename OtherDerived>
00369 EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
00370 {
00371 _resize_to_match(other);
00372 Base::operator=(other.derived());
00373 return this->derived();
00374 }
00375
00376
00377 template<typename OtherDerived>
00378 EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
00379 : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
00380 {
00381 _check_template_params();
00382 Base::operator=(other.derived());
00383 }
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396 inline static ConstMapType Map(const Scalar* data)
00397 { return ConstMapType(data); }
00398 inline static MapType Map(Scalar* data)
00399 { return MapType(data); }
00400 inline static ConstMapType Map(const Scalar* data, Index size)
00401 { return ConstMapType(data, size); }
00402 inline static MapType Map(Scalar* data, Index size)
00403 { return MapType(data, size); }
00404 inline static ConstMapType Map(const Scalar* data, Index rows, Index cols)
00405 { return ConstMapType(data, rows, cols); }
00406 inline static MapType Map(Scalar* data, Index rows, Index cols)
00407 { return MapType(data, rows, cols); }
00408
00409 inline static ConstAlignedMapType MapAligned(const Scalar* data)
00410 { return ConstAlignedMapType(data); }
00411 inline static AlignedMapType MapAligned(Scalar* data)
00412 { return AlignedMapType(data); }
00413 inline static ConstAlignedMapType MapAligned(const Scalar* data, Index size)
00414 { return ConstAlignedMapType(data, size); }
00415 inline static AlignedMapType MapAligned(Scalar* data, Index size)
00416 { return AlignedMapType(data, size); }
00417 inline static ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
00418 { return ConstAlignedMapType(data, rows, cols); }
00419 inline static AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
00420 { return AlignedMapType(data, rows, cols); }
00421
00422
00423 using Base::setConstant;
00424 Derived& setConstant(Index size, const Scalar& value);
00425 Derived& setConstant(Index rows, Index cols, const Scalar& value);
00426
00427 using Base::setZero;
00428 Derived& setZero(Index size);
00429 Derived& setZero(Index rows, Index cols);
00430
00431 using Base::setOnes;
00432 Derived& setOnes(Index size);
00433 Derived& setOnes(Index rows, Index cols);
00434
00435 using Base::setRandom;
00436 Derived& setRandom(Index size);
00437 Derived& setRandom(Index rows, Index cols);
00438
00439 #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
00440 #include EIGEN_PLAINOBJECTBASE_PLUGIN
00441 #endif
00442
00443 protected:
00444
00445
00446
00447
00448
00449
00450
00451 template<typename OtherDerived>
00452 EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
00453 {
00454 #ifdef EIGEN_NO_AUTOMATIC_RESIZING
00455 eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
00456 : (rows() == other.rows() && cols() == other.cols())))
00457 && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
00458 #else
00459 resizeLike(other);
00460 #endif
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 template<typename OtherDerived>
00478 EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
00479 {
00480 _set_selector(other.derived(), typename internal::conditional<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), internal::true_type, internal::false_type>::type());
00481 return this->derived();
00482 }
00483
00484 template<typename OtherDerived>
00485 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::true_type&) { _set_noalias(other.eval()); }
00486
00487 template<typename OtherDerived>
00488 EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const internal::false_type&) { _set_noalias(other); }
00489
00490
00491
00492
00493
00494
00495 template<typename OtherDerived>
00496 EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
00497 {
00498
00499
00500
00501
00502
00503 return internal::assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived());
00504 }
00505
00506 template<typename T0, typename T1>
00507 EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
00508 {
00509 eigen_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
00510 && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
00511 m_storage.resize(rows*cols,rows,cols);
00512 EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
00513 }
00514 template<typename T0, typename T1>
00515 EIGEN_STRONG_INLINE void _init2(const Scalar& x, const Scalar& y, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
00516 {
00517 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
00518 m_storage.data()[0] = x;
00519 m_storage.data()[1] = y;
00520 }
00521
00522 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00523 friend struct internal::matrix_swap_impl;
00524
00525
00526
00527
00528 template<typename OtherDerived>
00529 void _swap(DenseBase<OtherDerived> const & other)
00530 {
00531 enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
00532 internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived());
00533 }
00534
00535 public:
00536 #ifndef EIGEN_PARSED_BY_DOXYGEN
00537 EIGEN_STRONG_INLINE static void _check_template_params()
00538 {
00539 EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
00540 && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
00541 && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
00542 && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
00543 && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
00544 && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
00545 && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
00546 && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
00547 && (Options & (DontAlign|RowMajor)) == Options),
00548 INVALID_MATRIX_TEMPLATE_PARAMETERS)
00549 }
00550 #endif
00551
00552 private:
00553 enum { ThisConstantIsPrivateInPlainObjectBase };
00554 };
00555
00556 template <typename Derived, typename OtherDerived, bool IsVector>
00557 struct internal::conservative_resize_like_impl
00558 {
00559 typedef typename Derived::Index Index;
00560 static void run(DenseBase<Derived>& _this, Index rows, Index cols)
00561 {
00562 if (_this.rows() == rows && _this.cols() == cols) return;
00563 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00564
00565 if ( ( Derived::IsRowMajor && _this.cols() == cols) ||
00566 (!Derived::IsRowMajor && _this.rows() == rows) )
00567 {
00568 _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
00569 }
00570 else
00571 {
00572
00573 typename Derived::PlainObject tmp(rows,cols);
00574 const Index common_rows = std::min(rows, _this.rows());
00575 const Index common_cols = std::min(cols, _this.cols());
00576 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00577 _this.derived().swap(tmp);
00578 }
00579 }
00580
00581 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00582 {
00583 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00584
00585
00586
00587
00588
00589
00590 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
00591 EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
00592
00593 if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) ||
00594 (!Derived::IsRowMajor && _this.rows() == other.rows()) )
00595 {
00596 const Index new_rows = other.rows() - _this.rows();
00597 const Index new_cols = other.cols() - _this.cols();
00598 _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
00599 if (new_rows>0)
00600 _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
00601 else if (new_cols>0)
00602 _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
00603 }
00604 else
00605 {
00606
00607 typename Derived::PlainObject tmp(other);
00608 const Index common_rows = std::min(tmp.rows(), _this.rows());
00609 const Index common_cols = std::min(tmp.cols(), _this.cols());
00610 tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
00611 _this.derived().swap(tmp);
00612 }
00613 }
00614 };
00615
00616 namespace internal {
00617
00618 template <typename Derived, typename OtherDerived>
00619 struct conservative_resize_like_impl<Derived,OtherDerived,true>
00620 {
00621 typedef typename Derived::Index Index;
00622 static void run(DenseBase<Derived>& _this, Index size)
00623 {
00624 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
00625 const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
00626 _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
00627 }
00628
00629 static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
00630 {
00631 if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
00632
00633 const Index num_new_elements = other.size() - _this.size();
00634
00635 const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
00636 const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
00637 _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
00638
00639 if (num_new_elements > 0)
00640 _this.tail(num_new_elements) = other.tail(num_new_elements);
00641 }
00642 };
00643
00644 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
00645 struct matrix_swap_impl
00646 {
00647 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00648 {
00649 a.base().swap(b);
00650 }
00651 };
00652
00653 template<typename MatrixTypeA, typename MatrixTypeB>
00654 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
00655 {
00656 static inline void run(MatrixTypeA& a, MatrixTypeB& b)
00657 {
00658 static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
00659 }
00660 };
00661
00662 }
00663
00664 #endif // EIGEN_DENSESTORAGEBASE_H