Eigen  3.2.92
PlainObjectBase.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #ifndef EIGEN_DENSESTORAGEBASE_H
12 #define EIGEN_DENSESTORAGEBASE_H
13 
14 #if defined(EIGEN_INITIALIZE_MATRICES_BY_ZERO)
15 # define EIGEN_INITIALIZE_COEFFS
16 # define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0);
17 #elif defined(EIGEN_INITIALIZE_MATRICES_BY_NAN)
18 # define EIGEN_INITIALIZE_COEFFS
19 # 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();
20 #else
21 # undef EIGEN_INITIALIZE_COEFFS
22 # define EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
23 #endif
24 
25 namespace Eigen {
26 
27 namespace internal {
28 
29 template<int MaxSizeAtCompileTime> struct check_rows_cols_for_overflow {
30  template<typename Index>
31  EIGEN_DEVICE_FUNC
32  static EIGEN_ALWAYS_INLINE void run(Index, Index)
33  {
34  }
35 };
36 
37 template<> struct check_rows_cols_for_overflow<Dynamic> {
38  template<typename Index>
39  EIGEN_DEVICE_FUNC
40  static EIGEN_ALWAYS_INLINE void run(Index rows, Index cols)
41  {
42  // http://hg.mozilla.org/mozilla-central/file/6c8a909977d3/xpcom/ds/CheckedInt.h#l242
43  // we assume Index is signed
44  Index max_index = (size_t(1) << (8 * sizeof(Index) - 1)) - 1; // assume Index is signed
45  bool error = (rows == 0 || cols == 0) ? false
46  : (rows > max_index / cols);
47  if (error)
48  throw_std_bad_alloc();
49  }
50 };
51 
52 template <typename Derived,
53  typename OtherDerived = Derived,
54  bool IsVector = bool(Derived::IsVectorAtCompileTime) && bool(OtherDerived::IsVectorAtCompileTime)>
55 struct conservative_resize_like_impl;
56 
57 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct matrix_swap_impl;
58 
59 } // end namespace internal
60 
69 #ifdef EIGEN_PARSED_BY_DOXYGEN
70 namespace internal {
71 
72 // this is a workaround to doxygen not being able to understand the inheritance logic
73 // when it is hidden by the dense_xpr_base helper struct.
75 template<typename Derived> struct dense_xpr_base_dispatcher_for_doxygen;// : public MatrixBase<Derived> {};
77 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
78 struct dense_xpr_base_dispatcher_for_doxygen<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
79  : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
81 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
82 struct dense_xpr_base_dispatcher_for_doxygen<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
83  : public ArrayBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > {};
84 
85 } // namespace internal
86 
87 template<typename Derived>
88 class PlainObjectBase : public internal::dense_xpr_base_dispatcher_for_doxygen<Derived>
89 #else
90 template<typename Derived>
91 class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
92 #endif
93 {
94  public:
95  enum { Options = internal::traits<Derived>::Options };
96  typedef typename internal::dense_xpr_base<Derived>::type Base;
97 
98  typedef typename internal::traits<Derived>::StorageKind StorageKind;
99  typedef typename internal::traits<Derived>::Scalar Scalar;
100 
101  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
102  typedef typename NumTraits<Scalar>::Real RealScalar;
103  typedef Derived DenseType;
104 
105  using Base::RowsAtCompileTime;
106  using Base::ColsAtCompileTime;
107  using Base::SizeAtCompileTime;
108  using Base::MaxRowsAtCompileTime;
109  using Base::MaxColsAtCompileTime;
110  using Base::MaxSizeAtCompileTime;
111  using Base::IsVectorAtCompileTime;
112  using Base::Flags;
113 
114  template<typename PlainObjectType, int MapOptions, typename StrideType> friend class Eigen::Map;
115  friend class Eigen::Map<Derived, Unaligned>;
117  friend class Eigen::Map<const Derived, Unaligned>;
119 #if EIGEN_MAX_ALIGN_BYTES>0
120  // for EIGEN_MAX_ALIGN_BYTES==0, AlignedMax==Unaligned, and many compilers generate warnings for friend-ing a class twice.
121  friend class Eigen::Map<Derived, AlignedMax>;
122  friend class Eigen::Map<const Derived, AlignedMax>;
123 #endif
126  template<typename StrideType> struct StridedMapType { typedef Eigen::Map<Derived, Unaligned, StrideType> type; };
127  template<typename StrideType> struct StridedConstMapType { typedef Eigen::Map<const Derived, Unaligned, StrideType> type; };
128  template<typename StrideType> struct StridedAlignedMapType { typedef Eigen::Map<Derived, AlignedMax, StrideType> type; };
129  template<typename StrideType> struct StridedConstAlignedMapType { typedef Eigen::Map<const Derived, AlignedMax, StrideType> type; };
130 
131  protected:
132  DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
133 
134  public:
135  enum { NeedsToAlign = (SizeAtCompileTime != Dynamic) && (internal::traits<Derived>::Alignment>0) };
136  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
137 
138  EIGEN_DEVICE_FUNC
139  Base& base() { return *static_cast<Base*>(this); }
140  EIGEN_DEVICE_FUNC
141  const Base& base() const { return *static_cast<const Base*>(this); }
142 
143  EIGEN_DEVICE_FUNC
144  EIGEN_STRONG_INLINE Index rows() const { return m_storage.rows(); }
145  EIGEN_DEVICE_FUNC
146  EIGEN_STRONG_INLINE Index cols() const { return m_storage.cols(); }
147 
148  EIGEN_DEVICE_FUNC
149  EIGEN_STRONG_INLINE const Scalar& coeff(Index rowId, Index colId) const
150  {
151  if(Flags & RowMajorBit)
152  return m_storage.data()[colId + rowId * m_storage.cols()];
153  else // column-major
154  return m_storage.data()[rowId + colId * m_storage.rows()];
155  }
156 
157  EIGEN_DEVICE_FUNC
158  EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const
159  {
160  return m_storage.data()[index];
161  }
162 
163  EIGEN_DEVICE_FUNC
164  EIGEN_STRONG_INLINE Scalar& coeffRef(Index rowId, Index colId)
165  {
166  if(Flags & RowMajorBit)
167  return m_storage.data()[colId + rowId * m_storage.cols()];
168  else // column-major
169  return m_storage.data()[rowId + colId * m_storage.rows()];
170  }
171 
172  EIGEN_DEVICE_FUNC
173  EIGEN_STRONG_INLINE Scalar& coeffRef(Index index)
174  {
175  return m_storage.data()[index];
176  }
177 
178  EIGEN_DEVICE_FUNC
179  EIGEN_STRONG_INLINE const Scalar& coeffRef(Index rowId, Index colId) const
180  {
181  if(Flags & RowMajorBit)
182  return m_storage.data()[colId + rowId * m_storage.cols()];
183  else // column-major
184  return m_storage.data()[rowId + colId * m_storage.rows()];
185  }
186 
187  EIGEN_DEVICE_FUNC
188  EIGEN_STRONG_INLINE const Scalar& coeffRef(Index index) const
189  {
190  return m_storage.data()[index];
191  }
192 
194  template<int LoadMode>
195  EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
196  {
197  return internal::ploadt<PacketScalar, LoadMode>
198  (m_storage.data() + (Flags & RowMajorBit
199  ? colId + rowId * m_storage.cols()
200  : rowId + colId * m_storage.rows()));
201  }
202 
204  template<int LoadMode>
205  EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
206  {
207  return internal::ploadt<PacketScalar, LoadMode>(m_storage.data() + index);
208  }
209 
211  template<int StoreMode>
212  EIGEN_STRONG_INLINE void writePacket(Index rowId, Index colId, const PacketScalar& val)
213  {
214  internal::pstoret<Scalar, PacketScalar, StoreMode>
215  (m_storage.data() + (Flags & RowMajorBit
216  ? colId + rowId * m_storage.cols()
217  : rowId + colId * m_storage.rows()), val);
218  }
219 
221  template<int StoreMode>
222  EIGEN_STRONG_INLINE void writePacket(Index index, const PacketScalar& val)
223  {
224  internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, val);
225  }
226 
228  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar *data() const
229  { return m_storage.data(); }
230 
232  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar *data()
233  { return m_storage.data(); }
234 
251  EIGEN_DEVICE_FUNC
252  EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
253  {
254  eigen_assert( EIGEN_IMPLIES(RowsAtCompileTime!=Dynamic,rows==RowsAtCompileTime)
255  && EIGEN_IMPLIES(ColsAtCompileTime!=Dynamic,cols==ColsAtCompileTime)
256  && EIGEN_IMPLIES(RowsAtCompileTime==Dynamic && MaxRowsAtCompileTime!=Dynamic,rows<=MaxRowsAtCompileTime)
257  && EIGEN_IMPLIES(ColsAtCompileTime==Dynamic && MaxColsAtCompileTime!=Dynamic,cols<=MaxColsAtCompileTime)
258  && rows>=0 && cols>=0 && "Invalid sizes when resizing a matrix or array.");
259  internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(rows, cols);
260  #ifdef EIGEN_INITIALIZE_COEFFS
261  Index size = rows*cols;
262  bool size_changed = size != this->size();
263  m_storage.resize(size, rows, cols);
264  if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
265  #else
266  m_storage.resize(rows*cols, rows, cols);
267  #endif
268  }
269 
281  EIGEN_DEVICE_FUNC
282  inline void resize(Index size)
283  {
284  EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
285  eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0);
286  #ifdef EIGEN_INITIALIZE_COEFFS
287  bool size_changed = size != this->size();
288  #endif
289  if(RowsAtCompileTime == 1)
290  m_storage.resize(size, 1, size);
291  else
292  m_storage.resize(size, size, 1);
293  #ifdef EIGEN_INITIALIZE_COEFFS
294  if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
295  #endif
296  }
297 
306  EIGEN_DEVICE_FUNC
307  inline void resize(NoChange_t, Index cols)
308  {
309  resize(rows(), cols);
310  }
311 
320  EIGEN_DEVICE_FUNC
321  inline void resize(Index rows, NoChange_t)
322  {
323  resize(rows, cols());
324  }
325 
333  template<typename OtherDerived>
334  EIGEN_DEVICE_FUNC
335  EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
336  {
337  const OtherDerived& other = _other.derived();
338  internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols());
339  const Index othersize = other.rows()*other.cols();
340  if(RowsAtCompileTime == 1)
341  {
342  eigen_assert(other.rows() == 1 || other.cols() == 1);
343  resize(1, othersize);
344  }
345  else if(ColsAtCompileTime == 1)
346  {
347  eigen_assert(other.rows() == 1 || other.cols() == 1);
348  resize(othersize, 1);
349  }
350  else resize(other.rows(), other.cols());
351  }
352 
362  EIGEN_DEVICE_FUNC
363  EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
364  {
365  internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
366  }
367 
375  EIGEN_DEVICE_FUNC
376  EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
377  {
378  // Note: see the comment in conservativeResize(Index,Index)
379  conservativeResize(rows, cols());
380  }
381 
389  EIGEN_DEVICE_FUNC
390  EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
391  {
392  // Note: see the comment in conservativeResize(Index,Index)
393  conservativeResize(rows(), cols);
394  }
395 
404  EIGEN_DEVICE_FUNC
405  EIGEN_STRONG_INLINE void conservativeResize(Index size)
406  {
407  internal::conservative_resize_like_impl<Derived>::run(*this, size);
408  }
409 
419  template<typename OtherDerived>
420  EIGEN_DEVICE_FUNC
421  EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
422  {
423  internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
424  }
425 
429  EIGEN_DEVICE_FUNC
430  EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
431  {
432  return _set(other);
433  }
434 
436  template<typename OtherDerived>
437  EIGEN_DEVICE_FUNC
438  EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
439  {
440  _resize_to_match(other);
441  return Base::lazyAssign(other.derived());
442  }
443 
444  template<typename OtherDerived>
445  EIGEN_DEVICE_FUNC
446  EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
447  {
448  resize(func.rows(), func.cols());
449  return Base::operator=(func);
450  }
451 
452  // Prevent user from trying to instantiate PlainObjectBase objects
453  // by making all its constructor protected. See bug 1074.
454  protected:
455 
456  EIGEN_DEVICE_FUNC
457  EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
458  {
459 // _check_template_params();
460 // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
461  }
462 
463 #ifndef EIGEN_PARSED_BY_DOXYGEN
464  // FIXME is it still needed ?
466  EIGEN_DEVICE_FUNC
467  explicit PlainObjectBase(internal::constructor_without_unaligned_array_assert)
468  : m_storage(internal::constructor_without_unaligned_array_assert())
469  {
470 // _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
471  }
472 #endif
473 
474 #ifdef EIGEN_HAVE_RVALUE_REFERENCES
475  EIGEN_DEVICE_FUNC
476  PlainObjectBase(PlainObjectBase&& other)
477  : m_storage( std::move(other.m_storage) )
478  {
479  }
480 
481  EIGEN_DEVICE_FUNC
482  PlainObjectBase& operator=(PlainObjectBase&& other)
483  {
484  using std::swap;
485  swap(m_storage, other.m_storage);
486  return *this;
487  }
488 #endif
489 
491  EIGEN_DEVICE_FUNC
492  EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other)
493  : Base(), m_storage(other.m_storage) { }
494  EIGEN_DEVICE_FUNC
495  EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
496  : m_storage(size, rows, cols)
497  {
498 // _check_template_params();
499 // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
500  }
501 
503  template<typename OtherDerived>
504  EIGEN_DEVICE_FUNC
505  EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other)
506  : m_storage()
507  {
508  _check_template_params();
509  resizeLike(other);
510  _set_noalias(other);
511  }
512 
514  template<typename OtherDerived>
515  EIGEN_DEVICE_FUNC
516  EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
517  : m_storage()
518  {
519  _check_template_params();
520  resizeLike(other);
521  *this = other.derived();
522  }
524  template<typename OtherDerived>
525  EIGEN_DEVICE_FUNC
526  EIGEN_STRONG_INLINE PlainObjectBase(const ReturnByValue<OtherDerived>& other)
527  {
528  _check_template_params();
529  // FIXME this does not automatically transpose vectors if necessary
530  resize(other.rows(), other.cols());
531  other.evalTo(this->derived());
532  }
533 
534  public:
535 
538  template<typename OtherDerived>
539  EIGEN_DEVICE_FUNC
540  EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
541  {
542  _resize_to_match(other);
543  Base::operator=(other.derived());
544  return this->derived();
545  }
546 
555  static inline ConstMapType Map(const Scalar* data)
556  { return ConstMapType(data); }
557  static inline MapType Map(Scalar* data)
558  { return MapType(data); }
559  static inline ConstMapType Map(const Scalar* data, Index size)
560  { return ConstMapType(data, size); }
561  static inline MapType Map(Scalar* data, Index size)
562  { return MapType(data, size); }
563  static inline ConstMapType Map(const Scalar* data, Index rows, Index cols)
564  { return ConstMapType(data, rows, cols); }
565  static inline MapType Map(Scalar* data, Index rows, Index cols)
566  { return MapType(data, rows, cols); }
567 
568  static inline ConstAlignedMapType MapAligned(const Scalar* data)
569  { return ConstAlignedMapType(data); }
570  static inline AlignedMapType MapAligned(Scalar* data)
571  { return AlignedMapType(data); }
572  static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size)
573  { return ConstAlignedMapType(data, size); }
574  static inline AlignedMapType MapAligned(Scalar* data, Index size)
575  { return AlignedMapType(data, size); }
576  static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
577  { return ConstAlignedMapType(data, rows, cols); }
578  static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
579  { return AlignedMapType(data, rows, cols); }
580 
581  template<int Outer, int Inner>
582  static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
583  { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
584  template<int Outer, int Inner>
585  static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
586  { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
587  template<int Outer, int Inner>
588  static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
589  { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
590  template<int Outer, int Inner>
591  static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
592  { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
593  template<int Outer, int Inner>
594  static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
595  { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
596  template<int Outer, int Inner>
597  static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
598  { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
599 
600  template<int Outer, int Inner>
601  static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
602  { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
603  template<int Outer, int Inner>
604  static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
605  { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
606  template<int Outer, int Inner>
607  static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
608  { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
609  template<int Outer, int Inner>
610  static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
611  { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
612  template<int Outer, int Inner>
613  static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
614  { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
615  template<int Outer, int Inner>
616  static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
617  { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
619 
620  using Base::setConstant;
621  EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& value);
622  EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& value);
623 
624  using Base::setZero;
625  EIGEN_DEVICE_FUNC Derived& setZero(Index size);
626  EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols);
627 
628  using Base::setOnes;
629  EIGEN_DEVICE_FUNC Derived& setOnes(Index size);
630  EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols);
631 
632  using Base::setRandom;
633  Derived& setRandom(Index size);
634  Derived& setRandom(Index rows, Index cols);
635 
636  #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
637  #include EIGEN_PLAINOBJECTBASE_PLUGIN
638  #endif
639 
640  protected:
648  template<typename OtherDerived>
649  EIGEN_DEVICE_FUNC
650  EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
651  {
652  #ifdef EIGEN_NO_AUTOMATIC_RESIZING
653  eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
654  : (rows() == other.rows() && cols() == other.cols())))
655  && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
656  EIGEN_ONLY_USED_FOR_DEBUG(other);
657  #else
658  resizeLike(other);
659  #endif
660  }
661 
676  // aliasing is dealt once in internall::call_assignment
677  // so at this stage we have to assume aliasing... and resising has to be done later.
678  template<typename OtherDerived>
679  EIGEN_DEVICE_FUNC
680  EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
681  {
682  internal::call_assignment(this->derived(), other.derived());
683  return this->derived();
684  }
685 
691  template<typename OtherDerived>
692  EIGEN_DEVICE_FUNC
693  EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
694  {
695  // I don't think we need this resize call since the lazyAssign will anyways resize
696  // and lazyAssign will be called by the assign selector.
697  //_resize_to_match(other);
698  // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
699  // it wouldn't allow to copy a row-vector into a column-vector.
700  internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op<Scalar>());
701  return this->derived();
702  }
703 
704  template<typename T0, typename T1>
705  EIGEN_DEVICE_FUNC
706  EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
707  {
708  EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
709  bool(NumTraits<T1>::IsInteger),
710  FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
711  resize(rows,cols);
712  }
713 
714  template<typename T0, typename T1>
715  EIGEN_DEVICE_FUNC
716  EIGEN_STRONG_INLINE void _init2(const Scalar& val0, const Scalar& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
717  {
718  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
719  m_storage.data()[0] = val0;
720  m_storage.data()[1] = val1;
721  }
722 
723  template<typename T0, typename T1>
724  EIGEN_DEVICE_FUNC
725  EIGEN_STRONG_INLINE void _init2(const Index& val0, const Index& val1,
726  typename internal::enable_if< (!internal::is_same<Index,Scalar>::value)
727  && (internal::is_same<T0,Index>::value)
728  && (internal::is_same<T1,Index>::value)
729  && Base::SizeAtCompileTime==2,T1>::type* = 0)
730  {
731  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
732  m_storage.data()[0] = Scalar(val0);
733  m_storage.data()[1] = Scalar(val1);
734  }
735 
736  // The argument is convertible to the Index type and we either have a non 1x1 Matrix, or a dynamic-sized Array,
737  // then the argument is meant to be the size of the object.
738  template<typename T>
739  EIGEN_DEVICE_FUNC
740  EIGEN_STRONG_INLINE void _init1(Index size, typename internal::enable_if< (Base::SizeAtCompileTime!=1 || !internal::is_convertible<T, Scalar>::value)
741  && ((!internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0)
742  {
743  // NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument.
744  const bool is_integer = NumTraits<T>::IsInteger;
745  EIGEN_STATIC_ASSERT(is_integer,
746  FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
747  resize(size);
748  }
749 
750  // 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)
751  template<typename T>
752  EIGEN_DEVICE_FUNC
753  EIGEN_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0)
754  {
755  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
756  m_storage.data()[0] = val0;
757  }
758 
759  // 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)
760  template<typename T>
761  EIGEN_DEVICE_FUNC
762  EIGEN_STRONG_INLINE void _init1(const Index& val0,
763  typename internal::enable_if< (!internal::is_same<Index,Scalar>::value)
764  && (internal::is_same<Index,T>::value)
765  && Base::SizeAtCompileTime==1
766  && internal::is_convertible<T, Scalar>::value,T*>::type* = 0)
767  {
768  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
769  m_storage.data()[0] = Scalar(val0);
770  }
771 
772  // Initialize a fixed size matrix from a pointer to raw data
773  template<typename T>
774  EIGEN_DEVICE_FUNC
775  EIGEN_STRONG_INLINE void _init1(const Scalar* data){
776  this->_set_noalias(ConstMapType(data));
777  }
778 
779  // Initialize an arbitrary matrix from a dense expression
780  template<typename T, typename OtherDerived>
781  EIGEN_DEVICE_FUNC
782  EIGEN_STRONG_INLINE void _init1(const DenseBase<OtherDerived>& other){
783  this->_set_noalias(other);
784  }
785 
786  // Initialize an arbitrary matrix from a generic Eigen expression
787  template<typename T, typename OtherDerived>
788  EIGEN_DEVICE_FUNC
789  EIGEN_STRONG_INLINE void _init1(const EigenBase<OtherDerived>& other){
790  this->derived() = other;
791  }
792 
793  template<typename T, typename OtherDerived>
794  EIGEN_DEVICE_FUNC
795  EIGEN_STRONG_INLINE void _init1(const ReturnByValue<OtherDerived>& other)
796  {
797  resize(other.rows(), other.cols());
798  other.evalTo(this->derived());
799  }
800 
801  template<typename T, typename OtherDerived, int ColsAtCompileTime>
802  EIGEN_DEVICE_FUNC
803  EIGEN_STRONG_INLINE void _init1(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
804  {
805  this->derived() = r;
806  }
807 
808  // For fixed -size arrays:
809  template<typename T>
810  EIGEN_DEVICE_FUNC
811  EIGEN_STRONG_INLINE void _init1(const Scalar& val0,
812  typename internal::enable_if< Base::SizeAtCompileTime!=Dynamic
813  && Base::SizeAtCompileTime!=1
814  && internal::is_convertible<T, Scalar>::value
815  && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T>::type* = 0)
816  {
817  Base::setConstant(val0);
818  }
819 
820  template<typename T>
821  EIGEN_DEVICE_FUNC
822  EIGEN_STRONG_INLINE void _init1(const Index& val0,
823  typename internal::enable_if< (!internal::is_same<Index,Scalar>::value)
824  && (internal::is_same<Index,T>::value)
825  && Base::SizeAtCompileTime!=Dynamic
826  && Base::SizeAtCompileTime!=1
827  && internal::is_convertible<T, Scalar>::value
828  && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T*>::type* = 0)
829  {
830  Base::setConstant(val0);
831  }
832 
833  template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
834  friend struct internal::matrix_swap_impl;
835 
836  public:
837 
838 #ifndef EIGEN_PARSED_BY_DOXYGEN
839 
843  template<typename OtherDerived>
844  EIGEN_DEVICE_FUNC
845  void swap(DenseBase<OtherDerived> & other)
846  {
847  enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
848  internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.derived());
849  }
850 
854  template<typename OtherDerived>
855  EIGEN_DEVICE_FUNC
856  void swap(DenseBase<OtherDerived> const & other)
857  { Base::swap(other.derived()); }
858 
859  EIGEN_DEVICE_FUNC
860  static EIGEN_STRONG_INLINE void _check_template_params()
861  {
862  EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
863  && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
864  && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
865  && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
866  && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
867  && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
868  && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
869  && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
870  && (Options & (DontAlign|RowMajor)) == Options),
871  INVALID_MATRIX_TEMPLATE_PARAMETERS)
872  }
873 
874  enum { IsPlainObjectBase = 1 };
875 #endif
876 };
877 
878 namespace internal {
879 
880 template <typename Derived, typename OtherDerived, bool IsVector>
881 struct conservative_resize_like_impl
882 {
883  static void run(DenseBase<Derived>& _this, Index rows, Index cols)
884  {
885  if (_this.rows() == rows && _this.cols() == cols) return;
886  EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
887 
888  if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
889  (!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns
890  {
891  internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
892  _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
893  }
894  else
895  {
896  // The storage order does not allow us to use reallocation.
897  typename Derived::PlainObject tmp(rows,cols);
898  const Index common_rows = (std::min)(rows, _this.rows());
899  const Index common_cols = (std::min)(cols, _this.cols());
900  tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
901  _this.derived().swap(tmp);
902  }
903  }
904 
905  static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
906  {
907  if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
908 
909  // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index),
910  // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
911  // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or
912  // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like
913  // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
914  EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
915  EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
916 
917  if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
918  (!Derived::IsRowMajor && _this.rows() == other.rows()) ) // column-major and we change only the number of columns
919  {
920  const Index new_rows = other.rows() - _this.rows();
921  const Index new_cols = other.cols() - _this.cols();
922  _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
923  if (new_rows>0)
924  _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
925  else if (new_cols>0)
926  _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
927  }
928  else
929  {
930  // The storage order does not allow us to use reallocation.
931  typename Derived::PlainObject tmp(other);
932  const Index common_rows = (std::min)(tmp.rows(), _this.rows());
933  const Index common_cols = (std::min)(tmp.cols(), _this.cols());
934  tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
935  _this.derived().swap(tmp);
936  }
937  }
938 };
939 
940 // Here, the specialization for vectors inherits from the general matrix case
941 // to allow calling .conservativeResize(rows,cols) on vectors.
942 template <typename Derived, typename OtherDerived>
943 struct conservative_resize_like_impl<Derived,OtherDerived,true>
944  : conservative_resize_like_impl<Derived,OtherDerived,false>
945 {
946  using conservative_resize_like_impl<Derived,OtherDerived,false>::run;
947 
948  static void run(DenseBase<Derived>& _this, Index size)
949  {
950  const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
951  const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
952  _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
953  }
954 
955  static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
956  {
957  if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
958 
959  const Index num_new_elements = other.size() - _this.size();
960 
961  const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
962  const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
963  _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
964 
965  if (num_new_elements > 0)
966  _this.tail(num_new_elements) = other.tail(num_new_elements);
967  }
968 };
969 
970 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
971 struct matrix_swap_impl
972 {
973  EIGEN_DEVICE_FUNC
974  static inline void run(MatrixTypeA& a, MatrixTypeB& b)
975  {
976  a.base().swap(b);
977  }
978 };
979 
980 template<typename MatrixTypeA, typename MatrixTypeB>
981 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
982 {
983  EIGEN_DEVICE_FUNC
984  static inline void run(MatrixTypeA& a, MatrixTypeB& b)
985  {
986  static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
987  }
988 };
989 
990 } // end namespace internal
991 
992 } // end namespace Eigen
993 
994 #endif // EIGEN_DENSESTORAGEBASE_H
void resize(NoChange_t, Index cols)
Definition: PlainObjectBase.h:307
PlainObjectBase(const ReturnByValue< OtherDerived > &other)
Copy constructor with in-place evaluation.
Definition: PlainObjectBase.h:526
Derived & lazyAssign(const DenseBase< OtherDerived > &other)
Definition: PlainObjectBase.h:438
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:89
void conservativeResize(Index rows, Index cols)
Definition: PlainObjectBase.h:363
Derived & setRandom(Index size)
Definition: Random.h:152
Definition: LDLT.h:16
Definition: StdDeque.h:58
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:107
Derived & derived()
Definition: EigenBase.h:44
const unsigned int RowMajorBit
Definition: Constants.h:61
Base class for all dense matrices, vectors, and arrays.
Definition: DenseBase.h:41
void resize(Index rows, Index cols)
Definition: PlainObjectBase.h:252
PlainObjectBase(const DenseBase< OtherDerived > &other)
Definition: PlainObjectBase.h:505
PlainObjectBase(const EigenBase< OtherDerived > &other)
Definition: PlainObjectBase.h:516
PlainObjectBase(const PlainObjectBase &other)
Definition: PlainObjectBase.h:492
Definition: EigenBase.h:28
Scalar * data()
Definition: PlainObjectBase.h:232
Derived & setOnes(Index size)
Definition: CwiseNullaryOp.h:646
Definition: Constants.h:326
void conservativeResize(NoChange_t, Index cols)
Definition: PlainObjectBase.h:390
Derived & setZero(Index size)
Definition: CwiseNullaryOp.h:520
void resizeLike(const EigenBase< OtherDerived > &_other)
Definition: PlainObjectBase.h:335
Definition: Constants.h:322
void resize(Index rows, NoChange_t)
Definition: PlainObjectBase.h:321
Dense storage base class for matrices and arrays.
Definition: PlainObjectBase.h:88
Derived & operator=(const PlainObjectBase &other)
Definition: PlainObjectBase.h:430
void conservativeResize(Index size)
Definition: PlainObjectBase.h:405
Definition: Eigen_Colamd.h:54
void resize(Index size)
Definition: PlainObjectBase.h:282
void conservativeResizeLike(const DenseBase< OtherDerived > &other)
Definition: PlainObjectBase.h:421
const Scalar * data() const
Definition: PlainObjectBase.h:228
void conservativeResize(Index rows, NoChange_t)
Definition: PlainObjectBase.h:376
Derived & _set(const DenseBase< OtherDerived > &other)
Copies the value of the expression other into *this with automatic resizing.
Definition: PlainObjectBase.h:680
Derived & operator=(const EigenBase< OtherDerived > &other)
Definition: PlainObjectBase.h:540
Derived & setConstant(Index size, const Scalar &value)
Definition: CwiseNullaryOp.h:352