DenseCoeffsBase.h
Go to the documentation of this file.
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 #include "./InternalHeaderCheck.h"
14 
15 namespace Eigen {
16 
17 namespace internal {
18 template<typename T> struct add_const_on_value_type_if_arithmetic
19 {
20  typedef std::conditional_t<is_arithmetic<T>::value, T, add_const_on_value_type_t<T>> type;
21 };
22 }
23 
36 template<typename Derived>
37 class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
38 {
39  public:
40  typedef typename internal::traits<Derived>::StorageKind StorageKind;
41  typedef typename internal::traits<Derived>::Scalar Scalar;
42  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
43 
44  // Explanation for this CoeffReturnType typedef.
45  // - This is the return type of the coeff() method.
46  // - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references
47  // to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value).
48  // - The is_arithmetic check is required since "const int", "const double", etc. will cause warnings on some systems
49  // while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is
50  // not possible, since the underlying expressions might not offer a valid address the reference could be referring to.
51  typedef std::conditional_t<bool(internal::traits<Derived>::Flags&LvalueBit),
52  const Scalar&,
53  std::conditional_t<internal::is_arithmetic<Scalar>::value, Scalar, const Scalar>
55 
56  typedef typename internal::add_const_on_value_type_if_arithmetic<
57  typename internal::packet_traits<Scalar>::type
59 
61  using Base::rows;
62  using Base::cols;
63  using Base::size;
64  using Base::derived;
65 
67  EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const
68  {
69  return int(Derived::RowsAtCompileTime) == 1 ? 0
70  : int(Derived::ColsAtCompileTime) == 1 ? inner
71  : int(Derived::Flags)&RowMajorBit ? outer
72  : inner;
73  }
74 
76  EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const
77  {
78  return int(Derived::ColsAtCompileTime) == 1 ? 0
79  : int(Derived::RowsAtCompileTime) == 1 ? inner
80  : int(Derived::Flags)&RowMajorBit ? inner
81  : outer;
82  }
83 
99  EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
100  {
101  eigen_internal_assert(row >= 0 && row < rows()
102  && col >= 0 && col < cols());
103  return internal::evaluator<Derived>(derived()).coeff(row,col);
104  }
105 
107  EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
108  {
109  return coeff(rowIndexByOuterInner(outer, inner),
110  colIndexByOuterInner(outer, inner));
111  }
112 
118  EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const
119  {
120  eigen_assert(row >= 0 && row < rows()
121  && col >= 0 && col < cols());
122  return coeff(row, col);
123  }
124 
141  EIGEN_STRONG_INLINE CoeffReturnType
142  coeff(Index index) const
143  {
144  EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
145  THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
146  eigen_internal_assert(index >= 0 && index < size());
147  return internal::evaluator<Derived>(derived()).coeff(index);
148  }
149 
150 
160  EIGEN_STRONG_INLINE CoeffReturnType
161  operator[](Index index) const
162  {
163  EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
164  THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
165  eigen_assert(index >= 0 && index < size());
166  return coeff(index);
167  }
168 
180  EIGEN_STRONG_INLINE CoeffReturnType
181  operator()(Index index) const
182  {
183  eigen_assert(index >= 0 && index < size());
184  return coeff(index);
185  }
186 
190  EIGEN_STRONG_INLINE CoeffReturnType
191  x() const { return (*this)[0]; }
192 
196  EIGEN_STRONG_INLINE CoeffReturnType
197  y() const
198  {
199  EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=2, OUT_OF_RANGE_ACCESS);
200  return (*this)[1];
201  }
202 
206  EIGEN_STRONG_INLINE CoeffReturnType
207  z() const
208  {
209  EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=3, OUT_OF_RANGE_ACCESS);
210  return (*this)[2];
211  }
212 
216  EIGEN_STRONG_INLINE CoeffReturnType
217  w() const
218  {
219  EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=4, OUT_OF_RANGE_ACCESS);
220  return (*this)[3];
221  }
222 
233  template<int LoadMode>
234  EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
235  {
236  typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
237  eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
238  return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(row,col);
239  }
240 
241 
243  template<int LoadMode>
244  EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const
245  {
246  return packet<LoadMode>(rowIndexByOuterInner(outer, inner),
247  colIndexByOuterInner(outer, inner));
248  }
249 
260  template<int LoadMode>
261  EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
262  {
263  EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
264  THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
265  typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
266  eigen_internal_assert(index >= 0 && index < size());
267  return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(index);
268  }
269 
270  protected:
271  // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase.
272  // But some methods are only available in the DirectAccess case.
273  // So we add dummy methods here with these names, so that "using... " doesn't fail.
274  // It's not private so that the child class DenseBase can access them, and it's not public
275  // either since it's an implementation detail, so has to be protected.
276  void coeffRef();
278  void writePacket();
280  void copyCoeff();
282  void copyPacket();
284  void stride();
285  void innerStride();
286  void outerStride();
287  void rowStride();
288  void colStride();
289 };
290 
303 template<typename Derived>
304 class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
305 {
306  public:
307 
309 
310  typedef typename internal::traits<Derived>::StorageKind StorageKind;
311  typedef typename internal::traits<Derived>::Scalar Scalar;
312  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
314 
315  using Base::coeff;
316  using Base::rows;
317  using Base::cols;
318  using Base::size;
319  using Base::derived;
320  using Base::rowIndexByOuterInner;
321  using Base::colIndexByOuterInner;
322  using Base::operator[];
323  using Base::operator();
324  using Base::x;
325  using Base::y;
326  using Base::z;
327  using Base::w;
328 
344  EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
345  {
346  eigen_internal_assert(row >= 0 && row < rows()
347  && col >= 0 && col < cols());
348  return internal::evaluator<Derived>(derived()).coeffRef(row,col);
349  }
350 
352  EIGEN_STRONG_INLINE Scalar&
354  {
355  return coeffRef(rowIndexByOuterInner(outer, inner),
356  colIndexByOuterInner(outer, inner));
357  }
358 
365  EIGEN_STRONG_INLINE Scalar&
367  {
368  eigen_assert(row >= 0 && row < rows()
369  && col >= 0 && col < cols());
370  return coeffRef(row, col);
371  }
372 
373 
390  EIGEN_STRONG_INLINE Scalar&
392  {
393  EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
394  THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
395  eigen_internal_assert(index >= 0 && index < size());
396  return internal::evaluator<Derived>(derived()).coeffRef(index);
397  }
398 
407  EIGEN_STRONG_INLINE Scalar&
409  {
410  EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
411  THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
412  eigen_assert(index >= 0 && index < size());
413  return coeffRef(index);
414  }
415 
426  EIGEN_STRONG_INLINE Scalar&
428  {
429  eigen_assert(index >= 0 && index < size());
430  return coeffRef(index);
431  }
432 
436  EIGEN_STRONG_INLINE Scalar&
437  x() { return (*this)[0]; }
438 
442  EIGEN_STRONG_INLINE Scalar&
443  y()
444  {
445  EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=2, OUT_OF_RANGE_ACCESS);
446  return (*this)[1];
447  }
448 
452  EIGEN_STRONG_INLINE Scalar&
453  z()
454  {
455  EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=3, OUT_OF_RANGE_ACCESS);
456  return (*this)[2];
457  }
458 
462  EIGEN_STRONG_INLINE Scalar&
463  w()
464  {
465  EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=4, OUT_OF_RANGE_ACCESS);
466  return (*this)[3];
467  }
468 };
469 
482 template<typename Derived>
483 class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
484 {
485  public:
486 
488  typedef typename internal::traits<Derived>::Scalar Scalar;
490 
491  using Base::rows;
492  using Base::cols;
493  using Base::size;
494  using Base::derived;
495 
501  inline Index innerStride() const
502  {
503  return derived().innerStride();
504  }
505 
512  inline Index outerStride() const
513  {
514  return derived().outerStride();
515  }
516 
517  // FIXME shall we remove it ?
518  EIGEN_CONSTEXPR inline Index stride() const
519  {
520  return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
521  }
522 
528  inline Index rowStride() const
529  {
530  return Derived::IsRowMajor ? outerStride() : innerStride();
531  }
532 
538  inline Index colStride() const
539  {
540  return Derived::IsRowMajor ? innerStride() : outerStride();
541  }
542 };
543 
556 template<typename Derived>
558  : public DenseCoeffsBase<Derived, WriteAccessors>
559 {
560  public:
561 
563  typedef typename internal::traits<Derived>::Scalar Scalar;
565 
566  using Base::rows;
567  using Base::cols;
568  using Base::size;
569  using Base::derived;
570 
577  {
578  return derived().innerStride();
579  }
580 
588  {
589  return derived().outerStride();
590  }
591 
592  // FIXME shall we remove it ?
594  {
595  return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
596  }
597 
604  {
605  return Derived::IsRowMajor ? outerStride() : innerStride();
606  }
607 
614  {
615  return Derived::IsRowMajor ? innerStride() : outerStride();
616  }
617 };
618 
619 namespace internal {
620 
621 template<int Alignment, typename Derived, bool JustReturnZero>
622 struct first_aligned_impl
623 {
624  static EIGEN_CONSTEXPR inline Index run(const Derived&) EIGEN_NOEXCEPT
625  { return 0; }
626 };
627 
628 template<int Alignment, typename Derived>
629 struct first_aligned_impl<Alignment, Derived, false>
630 {
631  static inline Index run(const Derived& m)
632  {
633  return internal::first_aligned<Alignment>(m.data(), m.size());
634  }
635 };
636 
644 template<int Alignment, typename Derived>
646 {
647  enum { ReturnZero = (int(evaluator<Derived>::Alignment) >= Alignment) || !(Derived::Flags & DirectAccessBit) };
648  return first_aligned_impl<Alignment, Derived, ReturnZero>::run(m.derived());
649 }
650 
651 template<typename Derived>
653 {
654  typedef typename Derived::Scalar Scalar;
655  typedef typename packet_traits<Scalar>::type DefaultPacketType;
656  return internal::first_aligned<int(unpacket_traits<DefaultPacketType>::alignment),Derived>(m);
657 }
658 
659 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
660 struct inner_stride_at_compile_time
661 {
662  enum { ret = traits<Derived>::InnerStrideAtCompileTime };
663 };
664 
665 template<typename Derived>
666 struct inner_stride_at_compile_time<Derived, false>
667 {
668  enum { ret = 0 };
669 };
670 
671 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
672 struct outer_stride_at_compile_time
673 {
674  enum { ret = traits<Derived>::OuterStrideAtCompileTime };
675 };
676 
677 template<typename Derived>
678 struct outer_stride_at_compile_time<Derived, false>
679 {
680  enum { ret = 0 };
681 };
682 
683 } // end namespace internal
684 
685 } // end namespace Eigen
686 
687 #endif // EIGEN_DENSECOEFFSBASE_H
Matrix3f m
RowXpr row(Index i)
This is the const version of row(). *‍/.
ColXpr col(Index i)
This is the const version of col().
#define eigen_internal_assert(x)
Definition: Macros.h:908
#define EIGEN_NOEXCEPT
Definition: Macros.h:1260
#define EIGEN_CONSTEXPR
Definition: Macros.h:747
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:883
#define eigen_assert(x)
Definition: Macros.h:902
RowVector3d w
#define EIGEN_STATIC_ASSERT(X, MSG)
Definition: StaticAssert.h:26
Eigen::Triplet< double > T
Base class for all dense matrices, vectors, and arrays.
Definition: DenseBase.h:42
DenseCoeffsBase< Derived, ReadOnlyAccessors > Base
internal::traits< Derived >::Scalar Scalar
EIGEN_CONSTEXPR Index innerStride() const EIGEN_NOEXCEPT
EIGEN_CONSTEXPR Index rowStride() const EIGEN_NOEXCEPT
DenseCoeffsBase< Derived, WriteAccessors > Base
EIGEN_CONSTEXPR Index stride() const EIGEN_NOEXCEPT
EIGEN_CONSTEXPR Index outerStride() const EIGEN_NOEXCEPT
EIGEN_CONSTEXPR Index colStride() const EIGEN_NOEXCEPT
Base class providing read-only coefficient access to matrices and arrays.
internal::packet_traits< Scalar >::type PacketScalar
internal::traits< Derived >::StorageKind StorageKind
Index colIndexByOuterInner(Index outer, Index inner) const
CoeffReturnType operator[](Index index) const
Index rowIndexByOuterInner(Index outer, Index inner) const
internal::add_const_on_value_type_if_arithmetic< typename internal::packet_traits< Scalar >::type >::type PacketReturnType
PacketReturnType packet(Index index) const
std::conditional_t< bool(internal::traits< Derived >::Flags &LvalueBit), const Scalar &, std::conditional_t< internal::is_arithmetic< Scalar >::value, Scalar, const Scalar > > CoeffReturnType
CoeffReturnType operator()(Index row, Index col) const
internal::traits< Derived >::Scalar Scalar
PacketReturnType packetByOuterInner(Index outer, Index inner) const
CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
PacketReturnType packet(Index row, Index col) const
CoeffReturnType coeff(Index row, Index col) const
CoeffReturnType operator()(Index index) const
Base class providing read/write coefficient access to matrices and arrays.
Scalar & coeffRefByOuterInner(Index outer, Index inner)
DenseCoeffsBase< Derived, ReadOnlyAccessors > Base
internal::packet_traits< Scalar >::type PacketScalar
internal::traits< Derived >::Scalar Scalar
internal::traits< Derived >::StorageKind StorageKind
@ DirectAccessors
Definition: Constants.h:382
@ ReadOnlyAccessors
Definition: Constants.h:378
@ WriteAccessors
Definition: Constants.h:380
@ DirectWriteAccessors
Definition: Constants.h:384
const unsigned int LinearAccessBit
Definition: Constants.h:132
const unsigned int DirectAccessBit
Definition: Constants.h:157
const unsigned int LvalueBit
Definition: Constants.h:146
const unsigned int RowMajorBit
Definition: Constants.h:68
const Scalar & y
static Index first_default_aligned(const DenseBase< Derived > &m)
static Index first_aligned(const DenseBase< Derived > &m)
: InteropHeaders
Definition: Core:139
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:41
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:231