Eigen  3.2.92
DenseCoeffsBase.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_DENSECOEFFSBASE_H
11 #define EIGEN_DENSECOEFFSBASE_H
12 
13 namespace Eigen {
14 
15 namespace internal {
16 template<typename T> struct add_const_on_value_type_if_arithmetic
17 {
18  typedef typename conditional<is_arithmetic<T>::value, T, typename add_const_on_value_type<T>::type>::type type;
19 };
20 }
21 
33 template<typename Derived>
34 class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
35 {
36  public:
37  typedef typename internal::traits<Derived>::StorageKind StorageKind;
38  typedef typename internal::traits<Derived>::Scalar Scalar;
39  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
40 
41  // Explanation for this CoeffReturnType typedef.
42  // - This is the return type of the coeff() method.
43  // - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references
44  // to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value).
45  // - The is_artihmetic check is required since "const int", "const double", etc. will cause warnings on some systems
46  // while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is
47  // not possible, since the underlying expressions might not offer a valid address the reference could be referring to.
48  typedef typename internal::conditional<bool(internal::traits<Derived>::Flags&LvalueBit),
49  const Scalar&,
50  typename internal::conditional<internal::is_arithmetic<Scalar>::value, Scalar, const Scalar>::type
51  >::type CoeffReturnType;
52 
53  typedef typename internal::add_const_on_value_type_if_arithmetic<
54  typename internal::packet_traits<Scalar>::type
55  >::type PacketReturnType;
56 
57  typedef EigenBase<Derived> Base;
58  using Base::rows;
59  using Base::cols;
60  using Base::size;
61  using Base::derived;
62 
63  EIGEN_DEVICE_FUNC
64  EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const
65  {
66  return int(Derived::RowsAtCompileTime) == 1 ? 0
67  : int(Derived::ColsAtCompileTime) == 1 ? inner
68  : int(Derived::Flags)&RowMajorBit ? outer
69  : inner;
70  }
71 
72  EIGEN_DEVICE_FUNC
73  EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const
74  {
75  return int(Derived::ColsAtCompileTime) == 1 ? 0
76  : int(Derived::RowsAtCompileTime) == 1 ? inner
77  : int(Derived::Flags)&RowMajorBit ? inner
78  : outer;
79  }
80 
95  EIGEN_DEVICE_FUNC
96  EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
97  {
98  eigen_internal_assert(row >= 0 && row < rows()
99  && col >= 0 && col < cols());
100  return internal::evaluator<Derived>(derived()).coeff(row,col);
101  }
102 
103  EIGEN_DEVICE_FUNC
104  EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
105  {
106  return coeff(rowIndexByOuterInner(outer, inner),
107  colIndexByOuterInner(outer, inner));
108  }
109 
114  EIGEN_DEVICE_FUNC
115  EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const
116  {
117  eigen_assert(row >= 0 && row < rows()
118  && col >= 0 && col < cols());
119  return coeff(row, col);
120  }
121 
137  EIGEN_DEVICE_FUNC
138  EIGEN_STRONG_INLINE CoeffReturnType
139  coeff(Index index) const
140  {
141  EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
142  THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
143  eigen_internal_assert(index >= 0 && index < size());
144  return internal::evaluator<Derived>(derived()).coeff(index);
145  }
146 
147 
156  EIGEN_DEVICE_FUNC
157  EIGEN_STRONG_INLINE CoeffReturnType
158  operator[](Index index) const
159  {
160  EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
161  THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
162  eigen_assert(index >= 0 && index < size());
163  return coeff(index);
164  }
165 
176  EIGEN_DEVICE_FUNC
177  EIGEN_STRONG_INLINE CoeffReturnType
178  operator()(Index index) const
179  {
180  eigen_assert(index >= 0 && index < size());
181  return coeff(index);
182  }
183 
186  EIGEN_DEVICE_FUNC
187  EIGEN_STRONG_INLINE CoeffReturnType
188  x() const { return (*this)[0]; }
189 
192  EIGEN_DEVICE_FUNC
193  EIGEN_STRONG_INLINE CoeffReturnType
194  y() const { return (*this)[1]; }
195 
198  EIGEN_DEVICE_FUNC
199  EIGEN_STRONG_INLINE CoeffReturnType
200  z() const { return (*this)[2]; }
201 
204  EIGEN_DEVICE_FUNC
205  EIGEN_STRONG_INLINE CoeffReturnType
206  w() const { return (*this)[3]; }
207 
218  template<int LoadMode>
219  EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
220  {
221  typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
222  eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
223  return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(row,col);
224  }
225 
226 
228  template<int LoadMode>
229  EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const
230  {
231  return packet<LoadMode>(rowIndexByOuterInner(outer, inner),
232  colIndexByOuterInner(outer, inner));
233  }
234 
245  template<int LoadMode>
246  EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
247  {
248  EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
249  THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
250  typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
251  eigen_internal_assert(index >= 0 && index < size());
252  return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(index);
253  }
254 
255  protected:
256  // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase.
257  // But some methods are only available in the DirectAccess case.
258  // So we add dummy methods here with these names, so that "using... " doesn't fail.
259  // It's not private so that the child class DenseBase can access them, and it's not public
260  // either since it's an implementation detail, so has to be protected.
261  void coeffRef();
262  void coeffRefByOuterInner();
263  void writePacket();
264  void writePacketByOuterInner();
265  void copyCoeff();
266  void copyCoeffByOuterInner();
267  void copyPacket();
268  void copyPacketByOuterInner();
269  void stride();
270  void innerStride();
271  void outerStride();
272  void rowStride();
273  void colStride();
274 };
275 
287 template<typename Derived>
288 class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
289 {
290  public:
291 
293 
294  typedef typename internal::traits<Derived>::StorageKind StorageKind;
295  typedef typename internal::traits<Derived>::Scalar Scalar;
296  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
297  typedef typename NumTraits<Scalar>::Real RealScalar;
298 
299  using Base::coeff;
300  using Base::rows;
301  using Base::cols;
302  using Base::size;
303  using Base::derived;
304  using Base::rowIndexByOuterInner;
305  using Base::colIndexByOuterInner;
306  using Base::operator[];
307  using Base::operator();
308  using Base::x;
309  using Base::y;
310  using Base::z;
311  using Base::w;
312 
327  EIGEN_DEVICE_FUNC
328  EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
329  {
330  eigen_internal_assert(row >= 0 && row < rows()
331  && col >= 0 && col < cols());
332  return internal::evaluator<Derived>(derived()).coeffRef(row,col);
333  }
334 
335  EIGEN_DEVICE_FUNC
336  EIGEN_STRONG_INLINE Scalar&
337  coeffRefByOuterInner(Index outer, Index inner)
338  {
339  return coeffRef(rowIndexByOuterInner(outer, inner),
340  colIndexByOuterInner(outer, inner));
341  }
342 
348  EIGEN_DEVICE_FUNC
349  EIGEN_STRONG_INLINE Scalar&
351  {
352  eigen_assert(row >= 0 && row < rows()
353  && col >= 0 && col < cols());
354  return coeffRef(row, col);
355  }
356 
357 
373  EIGEN_DEVICE_FUNC
374  EIGEN_STRONG_INLINE Scalar&
376  {
377  EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
378  THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
379  eigen_internal_assert(index >= 0 && index < size());
380  return internal::evaluator<Derived>(derived()).coeffRef(index);
381  }
382 
390  EIGEN_DEVICE_FUNC
391  EIGEN_STRONG_INLINE Scalar&
393  {
394  EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
395  THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
396  eigen_assert(index >= 0 && index < size());
397  return coeffRef(index);
398  }
399 
409  EIGEN_DEVICE_FUNC
410  EIGEN_STRONG_INLINE Scalar&
412  {
413  eigen_assert(index >= 0 && index < size());
414  return coeffRef(index);
415  }
416 
419  EIGEN_DEVICE_FUNC
420  EIGEN_STRONG_INLINE Scalar&
421  x() { return (*this)[0]; }
422 
425  EIGEN_DEVICE_FUNC
426  EIGEN_STRONG_INLINE Scalar&
427  y() { return (*this)[1]; }
428 
431  EIGEN_DEVICE_FUNC
432  EIGEN_STRONG_INLINE Scalar&
433  z() { return (*this)[2]; }
434 
437  EIGEN_DEVICE_FUNC
438  EIGEN_STRONG_INLINE Scalar&
439  w() { return (*this)[3]; }
440 };
441 
453 template<typename Derived>
454 class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
455 {
456  public:
457 
459  typedef typename internal::traits<Derived>::Scalar Scalar;
460  typedef typename NumTraits<Scalar>::Real RealScalar;
461 
462  using Base::rows;
463  using Base::cols;
464  using Base::size;
465  using Base::derived;
466 
471  EIGEN_DEVICE_FUNC
472  inline Index innerStride() const
473  {
474  return derived().innerStride();
475  }
476 
482  EIGEN_DEVICE_FUNC
483  inline Index outerStride() const
484  {
485  return derived().outerStride();
486  }
487 
488  // FIXME shall we remove it ?
489  inline Index stride() const
490  {
491  return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
492  }
493 
498  EIGEN_DEVICE_FUNC
499  inline Index rowStride() const
500  {
501  return Derived::IsRowMajor ? outerStride() : innerStride();
502  }
503 
508  EIGEN_DEVICE_FUNC
509  inline Index colStride() const
510  {
511  return Derived::IsRowMajor ? innerStride() : outerStride();
512  }
513 };
514 
526 template<typename Derived>
527 class DenseCoeffsBase<Derived, DirectWriteAccessors>
528  : public DenseCoeffsBase<Derived, WriteAccessors>
529 {
530  public:
531 
533  typedef typename internal::traits<Derived>::Scalar Scalar;
534  typedef typename NumTraits<Scalar>::Real RealScalar;
535 
536  using Base::rows;
537  using Base::cols;
538  using Base::size;
539  using Base::derived;
540 
545  EIGEN_DEVICE_FUNC
546  inline Index innerStride() const
547  {
548  return derived().innerStride();
549  }
550 
556  EIGEN_DEVICE_FUNC
557  inline Index outerStride() const
558  {
559  return derived().outerStride();
560  }
561 
562  // FIXME shall we remove it ?
563  inline Index stride() const
564  {
565  return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
566  }
567 
572  EIGEN_DEVICE_FUNC
573  inline Index rowStride() const
574  {
575  return Derived::IsRowMajor ? outerStride() : innerStride();
576  }
577 
582  EIGEN_DEVICE_FUNC
583  inline Index colStride() const
584  {
585  return Derived::IsRowMajor ? innerStride() : outerStride();
586  }
587 };
588 
589 namespace internal {
590 
591 template<int Alignment, typename Derived, bool JustReturnZero>
592 struct first_aligned_impl
593 {
594  static inline Index run(const Derived&)
595  { return 0; }
596 };
597 
598 template<int Alignment, typename Derived>
599 struct first_aligned_impl<Alignment, Derived, false>
600 {
601  static inline Index run(const Derived& m)
602  {
603  return internal::first_aligned<Alignment>(&m.const_cast_derived().coeffRef(0,0), m.size());
604  }
605 };
606 
614 template<int Alignment, typename Derived>
615 static inline Index first_aligned(const DenseBase<Derived>& m)
616 {
617  enum { ReturnZero = (int(evaluator<Derived>::Alignment) >= Alignment) || !(Derived::Flags & DirectAccessBit) };
618  return first_aligned_impl<Alignment, Derived, ReturnZero>::run(m.derived());
619 }
620 
621 template<typename Derived>
622 static inline Index first_default_aligned(const DenseBase<Derived>& m)
623 {
624  typedef typename Derived::Scalar Scalar;
625  typedef typename packet_traits<Scalar>::type DefaultPacketType;
626  return internal::first_aligned<int(unpacket_traits<DefaultPacketType>::alignment),Derived>(m);
627 }
628 
629 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
630 struct inner_stride_at_compile_time
631 {
632  enum { ret = traits<Derived>::InnerStrideAtCompileTime };
633 };
634 
635 template<typename Derived>
636 struct inner_stride_at_compile_time<Derived, false>
637 {
638  enum { ret = 0 };
639 };
640 
641 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
642 struct outer_stride_at_compile_time
643 {
644  enum { ret = traits<Derived>::OuterStrideAtCompileTime };
645 };
646 
647 template<typename Derived>
648 struct outer_stride_at_compile_time<Derived, false>
649 {
650  enum { ret = 0 };
651 };
652 
653 } // end namespace internal
654 
655 } // end namespace Eigen
656 
657 #endif // EIGEN_DENSECOEFFSBASE_H
Scalar & operator()(Index row, Index col)
Definition: DenseCoeffsBase.h:350
CoeffReturnType coeff(Index row, Index col) const
Definition: DenseCoeffsBase.h:96
Definition: Constants.h:368
CoeffReturnType coeff(Index index) const
Definition: DenseCoeffsBase.h:139
const unsigned int DirectAccessBit
Definition: Constants.h:149
Scalar & coeffRef(Index index)
Definition: DenseCoeffsBase.h:375
const unsigned int LvalueBit
Definition: Constants.h:138
Definition: LDLT.h:16
Scalar & operator()(Index index)
Definition: DenseCoeffsBase.h:411
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:107
Scalar & y()
Definition: DenseCoeffsBase.h:427
CoeffReturnType w() const
Definition: DenseCoeffsBase.h:206
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:37
const unsigned int RowMajorBit
Definition: Constants.h:61
Base class for all dense matrices, vectors, and arrays.
Definition: DenseBase.h:41
Index rowStride() const
Definition: DenseCoeffsBase.h:573
CoeffReturnType z() const
Definition: DenseCoeffsBase.h:200
Scalar & operator[](Index index)
Definition: DenseCoeffsBase.h:392
CoeffReturnType operator()(Index row, Index col) const
Definition: DenseCoeffsBase.h:115
Definition: EigenBase.h:28
Scalar & z()
Definition: DenseCoeffsBase.h:433
Definition: Constants.h:366
Index outerStride() const
Definition: DenseCoeffsBase.h:483
Index outerStride() const
Definition: DenseCoeffsBase.h:557
Index colStride() const
Definition: DenseCoeffsBase.h:509
Definition: Constants.h:370
Scalar & x()
Definition: DenseCoeffsBase.h:421
Index innerStride() const
Definition: DenseCoeffsBase.h:546
Definition: Constants.h:372
Definition: Eigen_Colamd.h:54
CoeffReturnType operator()(Index index) const
Definition: DenseCoeffsBase.h:178
Index rowStride() const
Definition: DenseCoeffsBase.h:499
CoeffReturnType x() const
Definition: DenseCoeffsBase.h:188
Scalar & w()
Definition: DenseCoeffsBase.h:439
Base class providing read-only coefficient access to matrices and arrays.
Definition: DenseCoeffsBase.h:34
Index innerStride() const
Definition: DenseCoeffsBase.h:472
CoeffReturnType y() const
Definition: DenseCoeffsBase.h:194
Base class providing read/write coefficient access to matrices and arrays.
Definition: DenseCoeffsBase.h:288
Scalar & coeffRef(Index row, Index col)
Definition: DenseCoeffsBase.h:328
const unsigned int LinearAccessBit
Definition: Constants.h:124
CoeffReturnType operator[](Index index) const
Definition: DenseCoeffsBase.h:158
Index colStride() const
Definition: DenseCoeffsBase.h:583