Eigen  3.2.91
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  internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(rows, cols);
267  m_storage.resize(rows*cols, rows, cols);
268  #endif
269  }
270 
282  EIGEN_DEVICE_FUNC
283  inline void resize(Index size)
284  {
285  EIGEN_STATIC_ASSERT_VECTOR_ONLY(PlainObjectBase)
286  eigen_assert(((SizeAtCompileTime == Dynamic && (MaxSizeAtCompileTime==Dynamic || size<=MaxSizeAtCompileTime)) || SizeAtCompileTime == size) && size>=0);
287  #ifdef EIGEN_INITIALIZE_COEFFS
288  bool size_changed = size != this->size();
289  #endif
290  if(RowsAtCompileTime == 1)
291  m_storage.resize(size, 1, size);
292  else
293  m_storage.resize(size, size, 1);
294  #ifdef EIGEN_INITIALIZE_COEFFS
295  if(size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
296  #endif
297  }
298 
307  EIGEN_DEVICE_FUNC
308  inline void resize(NoChange_t, Index cols)
309  {
310  resize(rows(), cols);
311  }
312 
321  EIGEN_DEVICE_FUNC
322  inline void resize(Index rows, NoChange_t)
323  {
324  resize(rows, cols());
325  }
326 
334  template<typename OtherDerived>
335  EIGEN_DEVICE_FUNC
336  EIGEN_STRONG_INLINE void resizeLike(const EigenBase<OtherDerived>& _other)
337  {
338  const OtherDerived& other = _other.derived();
339  internal::check_rows_cols_for_overflow<MaxSizeAtCompileTime>::run(other.rows(), other.cols());
340  const Index othersize = other.rows()*other.cols();
341  if(RowsAtCompileTime == 1)
342  {
343  eigen_assert(other.rows() == 1 || other.cols() == 1);
344  resize(1, othersize);
345  }
346  else if(ColsAtCompileTime == 1)
347  {
348  eigen_assert(other.rows() == 1 || other.cols() == 1);
349  resize(othersize, 1);
350  }
351  else resize(other.rows(), other.cols());
352  }
353 
363  EIGEN_DEVICE_FUNC
364  EIGEN_STRONG_INLINE void conservativeResize(Index rows, Index cols)
365  {
366  internal::conservative_resize_like_impl<Derived>::run(*this, rows, cols);
367  }
368 
376  EIGEN_DEVICE_FUNC
377  EIGEN_STRONG_INLINE void conservativeResize(Index rows, NoChange_t)
378  {
379  // Note: see the comment in conservativeResize(Index,Index)
380  conservativeResize(rows, cols());
381  }
382 
390  EIGEN_DEVICE_FUNC
391  EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, Index cols)
392  {
393  // Note: see the comment in conservativeResize(Index,Index)
394  conservativeResize(rows(), cols);
395  }
396 
405  EIGEN_DEVICE_FUNC
406  EIGEN_STRONG_INLINE void conservativeResize(Index size)
407  {
408  internal::conservative_resize_like_impl<Derived>::run(*this, size);
409  }
410 
420  template<typename OtherDerived>
421  EIGEN_DEVICE_FUNC
422  EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other)
423  {
424  internal::conservative_resize_like_impl<Derived,OtherDerived>::run(*this, other);
425  }
426 
430  EIGEN_DEVICE_FUNC
431  EIGEN_STRONG_INLINE Derived& operator=(const PlainObjectBase& other)
432  {
433  return _set(other);
434  }
435 
437  template<typename OtherDerived>
438  EIGEN_DEVICE_FUNC
439  EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
440  {
441  _resize_to_match(other);
442  return Base::lazyAssign(other.derived());
443  }
444 
445  template<typename OtherDerived>
446  EIGEN_DEVICE_FUNC
447  EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func)
448  {
449  resize(func.rows(), func.cols());
450  return Base::operator=(func);
451  }
452 
453  EIGEN_DEVICE_FUNC
454  EIGEN_STRONG_INLINE PlainObjectBase() : m_storage()
455  {
456 // _check_template_params();
457 // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
458  }
459 
460 #ifndef EIGEN_PARSED_BY_DOXYGEN
461  // FIXME is it still needed ?
463  EIGEN_DEVICE_FUNC
464  explicit PlainObjectBase(internal::constructor_without_unaligned_array_assert)
465  : m_storage(internal::constructor_without_unaligned_array_assert())
466  {
467 // _check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
468  }
469 #endif
470 
471 #ifdef EIGEN_HAVE_RVALUE_REFERENCES
472  EIGEN_DEVICE_FUNC
473  PlainObjectBase(PlainObjectBase&& other)
474  : m_storage( std::move(other.m_storage) )
475  {
476  }
477 
478  EIGEN_DEVICE_FUNC
479  PlainObjectBase& operator=(PlainObjectBase&& other)
480  {
481  using std::swap;
482  swap(m_storage, other.m_storage);
483  return *this;
484  }
485 #endif
486 
488  EIGEN_DEVICE_FUNC
489  EIGEN_STRONG_INLINE PlainObjectBase(const PlainObjectBase& other)
490  : Base(), m_storage(other.m_storage) { }
491  EIGEN_DEVICE_FUNC
492  EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
493  : m_storage(size, rows, cols)
494  {
495 // _check_template_params();
496 // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
497  }
498 
501  template<typename OtherDerived>
502  EIGEN_DEVICE_FUNC
503  EIGEN_STRONG_INLINE Derived& operator=(const EigenBase<OtherDerived> &other)
504  {
505  _resize_to_match(other);
506  Base::operator=(other.derived());
507  return this->derived();
508  }
509 
511  template<typename OtherDerived>
512  EIGEN_DEVICE_FUNC
513  EIGEN_STRONG_INLINE PlainObjectBase(const DenseBase<OtherDerived> &other)
514  : m_storage()
515  {
516  _check_template_params();
517  resizeLike(other);
518  _set_noalias(other);
519  }
520 
522  template<typename OtherDerived>
523  EIGEN_DEVICE_FUNC
524  EIGEN_STRONG_INLINE PlainObjectBase(const EigenBase<OtherDerived> &other)
525  : m_storage()
526  {
527  _check_template_params();
528  resizeLike(other);
529  *this = other.derived();
530  }
532  template<typename OtherDerived>
533  EIGEN_DEVICE_FUNC
534  EIGEN_STRONG_INLINE PlainObjectBase(const ReturnByValue<OtherDerived>& other)
535  {
536  _check_template_params();
537  // FIXME this does not automatically transpose vectors if necessary
538  resize(other.rows(), other.cols());
539  other.evalTo(this->derived());
540  }
541 
550  static inline ConstMapType Map(const Scalar* data)
551  { return ConstMapType(data); }
552  static inline MapType Map(Scalar* data)
553  { return MapType(data); }
554  static inline ConstMapType Map(const Scalar* data, Index size)
555  { return ConstMapType(data, size); }
556  static inline MapType Map(Scalar* data, Index size)
557  { return MapType(data, size); }
558  static inline ConstMapType Map(const Scalar* data, Index rows, Index cols)
559  { return ConstMapType(data, rows, cols); }
560  static inline MapType Map(Scalar* data, Index rows, Index cols)
561  { return MapType(data, rows, cols); }
562 
563  static inline ConstAlignedMapType MapAligned(const Scalar* data)
564  { return ConstAlignedMapType(data); }
565  static inline AlignedMapType MapAligned(Scalar* data)
566  { return AlignedMapType(data); }
567  static inline ConstAlignedMapType MapAligned(const Scalar* data, Index size)
568  { return ConstAlignedMapType(data, size); }
569  static inline AlignedMapType MapAligned(Scalar* data, Index size)
570  { return AlignedMapType(data, size); }
571  static inline ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
572  { return ConstAlignedMapType(data, rows, cols); }
573  static inline AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
574  { return AlignedMapType(data, rows, cols); }
575 
576  template<int Outer, int Inner>
577  static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, const Stride<Outer, Inner>& stride)
578  { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, stride); }
579  template<int Outer, int Inner>
580  static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, const Stride<Outer, Inner>& stride)
581  { return typename StridedMapType<Stride<Outer, Inner> >::type(data, stride); }
582  template<int Outer, int Inner>
583  static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
584  { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, size, stride); }
585  template<int Outer, int Inner>
586  static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
587  { return typename StridedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
588  template<int Outer, int Inner>
589  static inline typename StridedConstMapType<Stride<Outer, Inner> >::type Map(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
590  { return typename StridedConstMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
591  template<int Outer, int Inner>
592  static inline typename StridedMapType<Stride<Outer, Inner> >::type Map(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
593  { return typename StridedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
594 
595  template<int Outer, int Inner>
596  static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, const Stride<Outer, Inner>& stride)
597  { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
598  template<int Outer, int Inner>
599  static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, const Stride<Outer, Inner>& stride)
600  { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, stride); }
601  template<int Outer, int Inner>
602  static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index size, const Stride<Outer, Inner>& stride)
603  { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
604  template<int Outer, int Inner>
605  static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index size, const Stride<Outer, Inner>& stride)
606  { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, size, stride); }
607  template<int Outer, int Inner>
608  static inline typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type MapAligned(const Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
609  { return typename StridedConstAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
610  template<int Outer, int Inner>
611  static inline typename StridedAlignedMapType<Stride<Outer, Inner> >::type MapAligned(Scalar* data, Index rows, Index cols, const Stride<Outer, Inner>& stride)
612  { return typename StridedAlignedMapType<Stride<Outer, Inner> >::type(data, rows, cols, stride); }
614 
615  using Base::setConstant;
616  EIGEN_DEVICE_FUNC Derived& setConstant(Index size, const Scalar& value);
617  EIGEN_DEVICE_FUNC Derived& setConstant(Index rows, Index cols, const Scalar& value);
618 
619  using Base::setZero;
620  EIGEN_DEVICE_FUNC Derived& setZero(Index size);
621  EIGEN_DEVICE_FUNC Derived& setZero(Index rows, Index cols);
622 
623  using Base::setOnes;
624  EIGEN_DEVICE_FUNC Derived& setOnes(Index size);
625  EIGEN_DEVICE_FUNC Derived& setOnes(Index rows, Index cols);
626 
627  using Base::setRandom;
628  Derived& setRandom(Index size);
629  Derived& setRandom(Index rows, Index cols);
630 
631  #ifdef EIGEN_PLAINOBJECTBASE_PLUGIN
632  #include EIGEN_PLAINOBJECTBASE_PLUGIN
633  #endif
634 
635  protected:
643  template<typename OtherDerived>
644  EIGEN_DEVICE_FUNC
645  EIGEN_STRONG_INLINE void _resize_to_match(const EigenBase<OtherDerived>& other)
646  {
647  #ifdef EIGEN_NO_AUTOMATIC_RESIZING
648  eigen_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size())
649  : (rows() == other.rows() && cols() == other.cols())))
650  && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined");
651  EIGEN_ONLY_USED_FOR_DEBUG(other);
652  #else
653  resizeLike(other);
654  #endif
655  }
656 
671  // aliasing is dealt once in internall::call_assignment
672  // so at this stage we have to assume aliasing... and resising has to be done later.
673  template<typename OtherDerived>
674  EIGEN_DEVICE_FUNC
675  EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other)
676  {
677  internal::call_assignment(this->derived(), other.derived());
678  return this->derived();
679  }
680 
686  template<typename OtherDerived>
687  EIGEN_DEVICE_FUNC
688  EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other)
689  {
690  // I don't think we need this resize call since the lazyAssign will anyways resize
691  // and lazyAssign will be called by the assign selector.
692  //_resize_to_match(other);
693  // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
694  // it wouldn't allow to copy a row-vector into a column-vector.
695  internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op<Scalar>());
696  return this->derived();
697  }
698 
699  template<typename T0, typename T1>
700  EIGEN_DEVICE_FUNC
701  EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename internal::enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
702  {
703  EIGEN_STATIC_ASSERT(bool(NumTraits<T0>::IsInteger) &&
704  bool(NumTraits<T1>::IsInteger),
705  FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
706  resize(rows,cols);
707  }
708 
709  template<typename T0, typename T1>
710  EIGEN_DEVICE_FUNC
711  EIGEN_STRONG_INLINE void _init2(const Scalar& val0, const Scalar& val1, typename internal::enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0)
712  {
713  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
714  m_storage.data()[0] = val0;
715  m_storage.data()[1] = val1;
716  }
717 
718  template<typename T0, typename T1>
719  EIGEN_DEVICE_FUNC
720  EIGEN_STRONG_INLINE void _init2(const Index& val0, const Index& val1,
721  typename internal::enable_if< (!internal::is_same<Index,Scalar>::value)
722  && (internal::is_same<T0,Index>::value)
723  && (internal::is_same<T1,Index>::value)
724  && Base::SizeAtCompileTime==2,T1>::type* = 0)
725  {
726  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2)
727  m_storage.data()[0] = Scalar(val0);
728  m_storage.data()[1] = Scalar(val1);
729  }
730 
731  // The argument is convertible to the Index type and we either have a non 1x1 Matrix, or a dynamic-sized Array,
732  // then the argument is meant to be the size of the object.
733  template<typename T>
734  EIGEN_DEVICE_FUNC
735  EIGEN_STRONG_INLINE void _init1(Index size, typename internal::enable_if< (Base::SizeAtCompileTime!=1 || !internal::is_convertible<T, Scalar>::value)
736  && ((!internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0)
737  {
738  // NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument.
739  const bool is_integer = NumTraits<T>::IsInteger;
740  EIGEN_STATIC_ASSERT(is_integer,
741  FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED)
742  resize(size);
743  }
744 
745  // 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)
746  template<typename T>
747  EIGEN_DEVICE_FUNC
748  EIGEN_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0)
749  {
750  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
751  m_storage.data()[0] = val0;
752  }
753 
754  // 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)
755  template<typename T>
756  EIGEN_DEVICE_FUNC
757  EIGEN_STRONG_INLINE void _init1(const Index& val0,
758  typename internal::enable_if< (!internal::is_same<Index,Scalar>::value)
759  && (internal::is_same<Index,T>::value)
760  && Base::SizeAtCompileTime==1
761  && internal::is_convertible<T, Scalar>::value,T*>::type* = 0)
762  {
763  EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1)
764  m_storage.data()[0] = Scalar(val0);
765  }
766 
767  // Initialize a fixed size matrix from a pointer to raw data
768  template<typename T>
769  EIGEN_DEVICE_FUNC
770  EIGEN_STRONG_INLINE void _init1(const Scalar* data){
771  this->_set_noalias(ConstMapType(data));
772  }
773 
774  // Initialize an arbitrary matrix from a dense expression
775  template<typename T, typename OtherDerived>
776  EIGEN_DEVICE_FUNC
777  EIGEN_STRONG_INLINE void _init1(const DenseBase<OtherDerived>& other){
778  this->_set_noalias(other);
779  }
780 
781  // Initialize an arbitrary matrix from a generic Eigen expression
782  template<typename T, typename OtherDerived>
783  EIGEN_DEVICE_FUNC
784  EIGEN_STRONG_INLINE void _init1(const EigenBase<OtherDerived>& other){
785  this->derived() = other;
786  }
787 
788  template<typename T, typename OtherDerived>
789  EIGEN_DEVICE_FUNC
790  EIGEN_STRONG_INLINE void _init1(const ReturnByValue<OtherDerived>& other)
791  {
792  resize(other.rows(), other.cols());
793  other.evalTo(this->derived());
794  }
795 
796  template<typename T, typename OtherDerived, int ColsAtCompileTime>
797  EIGEN_DEVICE_FUNC
798  EIGEN_STRONG_INLINE void _init1(const RotationBase<OtherDerived,ColsAtCompileTime>& r)
799  {
800  this->derived() = r;
801  }
802 
803  // For fixed -size arrays:
804  template<typename T>
805  EIGEN_DEVICE_FUNC
806  EIGEN_STRONG_INLINE void _init1(const Scalar& val0,
807  typename internal::enable_if< Base::SizeAtCompileTime!=Dynamic
808  && Base::SizeAtCompileTime!=1
809  && internal::is_convertible<T, Scalar>::value
810  && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T>::type* = 0)
811  {
812  Base::setConstant(val0);
813  }
814 
815  template<typename T>
816  EIGEN_DEVICE_FUNC
817  EIGEN_STRONG_INLINE void _init1(const Index& val0,
818  typename internal::enable_if< (!internal::is_same<Index,Scalar>::value)
819  && (internal::is_same<Index,T>::value)
820  && Base::SizeAtCompileTime!=Dynamic
821  && Base::SizeAtCompileTime!=1
822  && internal::is_convertible<T, Scalar>::value
823  && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T*>::type* = 0)
824  {
825  Base::setConstant(val0);
826  }
827 
828  template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
829  friend struct internal::matrix_swap_impl;
830 
831  public:
832 
833 #ifndef EIGEN_PARSED_BY_DOXYGEN
834 
838  template<typename OtherDerived>
839  EIGEN_DEVICE_FUNC
840  void swap(DenseBase<OtherDerived> & other)
841  {
842  enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
843  internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.derived());
844  }
845 
849  template<typename OtherDerived>
850  EIGEN_DEVICE_FUNC
851  void swap(DenseBase<OtherDerived> const & other)
852  { Base::swap(other.derived()); }
853 
854  EIGEN_DEVICE_FUNC
855  static EIGEN_STRONG_INLINE void _check_template_params()
856  {
857  EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, (Options&RowMajor)==RowMajor)
858  && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, (Options&RowMajor)==0)
859  && ((RowsAtCompileTime == Dynamic) || (RowsAtCompileTime >= 0))
860  && ((ColsAtCompileTime == Dynamic) || (ColsAtCompileTime >= 0))
861  && ((MaxRowsAtCompileTime == Dynamic) || (MaxRowsAtCompileTime >= 0))
862  && ((MaxColsAtCompileTime == Dynamic) || (MaxColsAtCompileTime >= 0))
863  && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic)
864  && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic)
865  && (Options & (DontAlign|RowMajor)) == Options),
866  INVALID_MATRIX_TEMPLATE_PARAMETERS)
867  }
868 
869  enum { IsPlainObjectBase = 1 };
870 #endif
871 };
872 
873 namespace internal {
874 
875 template <typename Derived, typename OtherDerived, bool IsVector>
876 struct conservative_resize_like_impl
877 {
878  static void run(DenseBase<Derived>& _this, Index rows, Index cols)
879  {
880  if (_this.rows() == rows && _this.cols() == cols) return;
881  EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
882 
883  if ( ( Derived::IsRowMajor && _this.cols() == cols) || // row-major and we change only the number of rows
884  (!Derived::IsRowMajor && _this.rows() == rows) ) // column-major and we change only the number of columns
885  {
886  internal::check_rows_cols_for_overflow<Derived::MaxSizeAtCompileTime>::run(rows, cols);
887  _this.derived().m_storage.conservativeResize(rows*cols,rows,cols);
888  }
889  else
890  {
891  // The storage order does not allow us to use reallocation.
892  typename Derived::PlainObject tmp(rows,cols);
893  const Index common_rows = (std::min)(rows, _this.rows());
894  const Index common_cols = (std::min)(cols, _this.cols());
895  tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
896  _this.derived().swap(tmp);
897  }
898  }
899 
900  static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
901  {
902  if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
903 
904  // Note: Here is space for improvement. Basically, for conservativeResize(Index,Index),
905  // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
906  // dimensions is dynamic, one could use either conservativeResize(Index rows, NoChange_t) or
907  // conservativeResize(NoChange_t, Index cols). For these methods new static asserts like
908  // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
909  EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
910  EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
911 
912  if ( ( Derived::IsRowMajor && _this.cols() == other.cols()) || // row-major and we change only the number of rows
913  (!Derived::IsRowMajor && _this.rows() == other.rows()) ) // column-major and we change only the number of columns
914  {
915  const Index new_rows = other.rows() - _this.rows();
916  const Index new_cols = other.cols() - _this.cols();
917  _this.derived().m_storage.conservativeResize(other.size(),other.rows(),other.cols());
918  if (new_rows>0)
919  _this.bottomRightCorner(new_rows, other.cols()) = other.bottomRows(new_rows);
920  else if (new_cols>0)
921  _this.bottomRightCorner(other.rows(), new_cols) = other.rightCols(new_cols);
922  }
923  else
924  {
925  // The storage order does not allow us to use reallocation.
926  typename Derived::PlainObject tmp(other);
927  const Index common_rows = (std::min)(tmp.rows(), _this.rows());
928  const Index common_cols = (std::min)(tmp.cols(), _this.cols());
929  tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
930  _this.derived().swap(tmp);
931  }
932  }
933 };
934 
935 // Here, the specialization for vectors inherits from the general matrix case
936 // to allow calling .conservativeResize(rows,cols) on vectors.
937 template <typename Derived, typename OtherDerived>
938 struct conservative_resize_like_impl<Derived,OtherDerived,true>
939  : conservative_resize_like_impl<Derived,OtherDerived,false>
940 {
941  using conservative_resize_like_impl<Derived,OtherDerived,false>::run;
942 
943  static void run(DenseBase<Derived>& _this, Index size)
944  {
945  const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : size;
946  const Index new_cols = Derived::RowsAtCompileTime==1 ? size : 1;
947  _this.derived().m_storage.conservativeResize(size,new_rows,new_cols);
948  }
949 
950  static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other)
951  {
952  if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
953 
954  const Index num_new_elements = other.size() - _this.size();
955 
956  const Index new_rows = Derived::RowsAtCompileTime==1 ? 1 : other.rows();
957  const Index new_cols = Derived::RowsAtCompileTime==1 ? other.cols() : 1;
958  _this.derived().m_storage.conservativeResize(other.size(),new_rows,new_cols);
959 
960  if (num_new_elements > 0)
961  _this.tail(num_new_elements) = other.tail(num_new_elements);
962  }
963 };
964 
965 template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
966 struct matrix_swap_impl
967 {
968  EIGEN_DEVICE_FUNC
969  static inline void run(MatrixTypeA& a, MatrixTypeB& b)
970  {
971  a.base().swap(b);
972  }
973 };
974 
975 template<typename MatrixTypeA, typename MatrixTypeB>
976 struct matrix_swap_impl<MatrixTypeA, MatrixTypeB, true>
977 {
978  EIGEN_DEVICE_FUNC
979  static inline void run(MatrixTypeA& a, MatrixTypeB& b)
980  {
981  static_cast<typename MatrixTypeA::Base&>(a).m_storage.swap(static_cast<typename MatrixTypeB::Base&>(b).m_storage);
982  }
983 };
984 
985 } // end namespace internal
986 
987 } // end namespace Eigen
988 
989 #endif // EIGEN_DENSESTORAGEBASE_H
void resize(NoChange_t, Index cols)
Definition: PlainObjectBase.h:308
Definition: Constants.h:314
PlainObjectBase(const ReturnByValue< OtherDerived > &other)
Copy constructor with in-place evaluation.
Definition: PlainObjectBase.h:534
Derived & lazyAssign(const DenseBase< OtherDerived > &other)
Definition: PlainObjectBase.h:439
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:89
void conservativeResize(Index rows, Index cols)
Definition: PlainObjectBase.h:364
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:53
Base class for all dense matrices, vectors, and arrays.
Definition: DenseBase.h:41
void resize(Index rows, Index cols)
Definition: PlainObjectBase.h:252
Definition: Constants.h:318
PlainObjectBase(const DenseBase< OtherDerived > &other)
Definition: PlainObjectBase.h:513
PlainObjectBase(const EigenBase< OtherDerived > &other)
Definition: PlainObjectBase.h:524
PlainObjectBase(const PlainObjectBase &other)
Definition: PlainObjectBase.h:489
Definition: EigenBase.h:28
Scalar * data()
Definition: PlainObjectBase.h:232
Derived & setOnes(Index size)
Definition: CwiseNullaryOp.h:646
void conservativeResize(NoChange_t, Index cols)
Definition: PlainObjectBase.h:391
Derived & setZero(Index size)
Definition: CwiseNullaryOp.h:520
void resizeLike(const EigenBase< OtherDerived > &_other)
Definition: PlainObjectBase.h:336
void resize(Index rows, NoChange_t)
Definition: PlainObjectBase.h:322
Dense storage base class for matrices and arrays.
Definition: PlainObjectBase.h:88
Derived & operator=(const PlainObjectBase &other)
Definition: PlainObjectBase.h:431
void conservativeResize(Index size)
Definition: PlainObjectBase.h:406
Definition: Eigen_Colamd.h:54
void resize(Index size)
Definition: PlainObjectBase.h:283
void conservativeResizeLike(const DenseBase< OtherDerived > &other)
Definition: PlainObjectBase.h:422
const Scalar * data() const
Definition: PlainObjectBase.h:228
void conservativeResize(Index rows, NoChange_t)
Definition: PlainObjectBase.h:377
Derived & _set(const DenseBase< OtherDerived > &other)
Copies the value of the expression other into *this with automatic resizing.
Definition: PlainObjectBase.h:675
Derived & operator=(const EigenBase< OtherDerived > &other)
Definition: PlainObjectBase.h:503
Derived & setConstant(Index size, const Scalar &value)
Definition: CwiseNullaryOp.h:352