$darkmode
Eigen  5.0.1-dev
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 // IWYU pragma: private
14 #include "./InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
18 namespace internal {
19 template <typename T>
20 struct add_const_on_value_type_if_arithmetic {
21  typedef std::conditional_t<is_arithmetic<T>::value, T, add_const_on_value_type_t<T>> type;
22 };
23 } // namespace internal
24 
37 template <typename Derived>
38 class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
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 DirectAccessBit means exactly that the underlying data of coefficients can be directly accessed as a plain
49  // strided array, which means exactly that the underlying data of coefficients does exist in memory, which means
50  // exactly that the coefficients is const-referencable, which means exactly that we can have coeff() return a const
51  // reference. For example, Map<const Matrix> have DirectAccessBit but not LvalueBit, so that Map<const Matrix>.coeff()
52  // does points to a const Scalar& which exists in memory, while does not allow coeffRef() as it would not provide a
53  // lvalue. Notice that DirectAccessBit and LvalueBit are mutually orthogonal.
54  // - The is_arithmetic check is required since "const int", "const double", etc. will cause warnings on some systems
55  // while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is
56  // not possible, since the underlying expressions might not offer a valid address the reference could be referring to.
57  typedef std::conditional_t<bool(internal::traits<Derived>::Flags&(LvalueBit | DirectAccessBit)), const Scalar&,
58  std::conditional_t<internal::is_arithmetic<Scalar>::value, Scalar, const Scalar>>
59  CoeffReturnType;
60 
61  typedef typename internal::add_const_on_value_type_if_arithmetic<typename internal::packet_traits<Scalar>::type>::type
62  PacketReturnType;
63 
64  typedef EigenBase<Derived> Base;
65  using Base::cols;
66  using Base::derived;
67  using Base::rows;
68  using Base::size;
69 
70  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const {
71  return int(Derived::RowsAtCompileTime) == 1 ? 0
72  : int(Derived::ColsAtCompileTime) == 1 ? inner
73  : int(Derived::Flags) & RowMajorBit ? outer
74  : inner;
75  }
76 
77  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const {
78  return int(Derived::ColsAtCompileTime) == 1 ? 0
79  : int(Derived::RowsAtCompileTime) == 1 ? inner
80  : int(Derived::Flags) & RowMajorBit ? inner
81  : outer;
82  }
83 
98  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType coeff(Index row, Index col) const {
99  eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
100  return internal::evaluator<Derived>(derived()).coeff(row, col);
101  }
102 
103  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType coeffByOuterInner(Index outer, Index inner) const {
104  return coeff(rowIndexByOuterInner(outer, inner), colIndexByOuterInner(outer, inner));
105  }
106 
111  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType operator()(Index row, Index col) const {
112  eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
113  return coeff(row, col);
114  }
115 
131  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType coeff(Index index) const {
132  EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
133  THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
134  eigen_internal_assert(index >= 0 && index < size());
135  return internal::evaluator<Derived>(derived()).coeff(index);
136  }
137 
146  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType operator[](Index index) const {
147  EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
148  THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
149  eigen_assert(index >= 0 && index < size());
150  return coeff(index);
151  }
152 
163  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType operator()(Index index) const {
164  eigen_assert(index >= 0 && index < size());
165  return coeff(index);
166  }
167 
170  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType x() const { return (*this)[0]; }
171 
174  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType y() const {
175  EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 2, OUT_OF_RANGE_ACCESS);
176  return (*this)[1];
177  }
178 
181  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType z() const {
182  EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 3, OUT_OF_RANGE_ACCESS);
183  return (*this)[2];
184  }
185 
188  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType w() const {
189  EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 4, OUT_OF_RANGE_ACCESS);
190  return (*this)[3];
191  }
192 
203  template <int LoadMode>
204  EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const {
205  typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
206  eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
207  return internal::evaluator<Derived>(derived()).template packet<LoadMode, DefaultPacketType>(row, col);
208  }
209 
211  template <int LoadMode>
212  EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const {
213  return packet<LoadMode>(rowIndexByOuterInner(outer, inner), colIndexByOuterInner(outer, inner));
214  }
215 
226  template <int LoadMode>
227  EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const {
228  EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
229  THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
230  typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
231  eigen_internal_assert(index >= 0 && index < size());
232  return internal::evaluator<Derived>(derived()).template packet<LoadMode, DefaultPacketType>(index);
233  }
234 
235  protected:
236  // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase.
237  // But some methods are only available in the DirectAccess case.
238  // So we add dummy methods here with these names, so that "using... " doesn't fail.
239  // It's not private so that the child class DenseBase can access them, and it's not public
240  // either since it's an implementation detail, so has to be protected.
241  void coeffRef();
242  void coeffRefByOuterInner();
243  void writePacket();
244  void writePacketByOuterInner();
245  void copyCoeff();
246  void copyCoeffByOuterInner();
247  void copyPacket();
248  void copyPacketByOuterInner();
249  void stride();
250  void innerStride();
251  void outerStride();
252  void rowStride();
253  void colStride();
254 };
255 
268 template <typename Derived>
269 class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors> {
270  public:
272 
273  typedef typename internal::traits<Derived>::StorageKind StorageKind;
274  typedef typename internal::traits<Derived>::Scalar Scalar;
275  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
276  typedef typename NumTraits<Scalar>::Real RealScalar;
277 
278  using Base::coeff;
279  using Base::colIndexByOuterInner;
280  using Base::cols;
281  using Base::derived;
282  using Base::rowIndexByOuterInner;
283  using Base::rows;
284  using Base::size;
285  using Base::operator[];
286  using Base::operator();
287  using Base::w;
288  using Base::x;
289  using Base::y;
290  using Base::z;
291 
306  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& coeffRef(Index row, Index col) {
307  eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
308  return internal::evaluator<Derived>(derived()).coeffRef(row, col);
309  }
310 
311  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRefByOuterInner(Index outer, Index inner) {
312  return coeffRef(rowIndexByOuterInner(outer, inner), colIndexByOuterInner(outer, inner));
313  }
314 
320  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& operator()(Index row, Index col) {
321  eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
322  return coeffRef(row, col);
323  }
324 
340  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& coeffRef(Index index) {
341  EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
342  THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
343  eigen_internal_assert(index >= 0 && index < size());
344  return internal::evaluator<Derived>(derived()).coeffRef(index);
345  }
346 
354  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& operator[](Index index) {
355  EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
356  THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
357  eigen_assert(index >= 0 && index < size());
358  return coeffRef(index);
359  }
360 
370  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& operator()(Index index) {
371  eigen_assert(index >= 0 && index < size());
372  return coeffRef(index);
373  }
374 
377  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& x() { return (*this)[0]; }
378 
381  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& y() {
382  EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 2, OUT_OF_RANGE_ACCESS);
383  return (*this)[1];
384  }
385 
388  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& z() {
389  EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 3, OUT_OF_RANGE_ACCESS);
390  return (*this)[2];
391  }
392 
395  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& w() {
396  EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 4, OUT_OF_RANGE_ACCESS);
397  return (*this)[3];
398  }
399 };
400 
413 template <typename Derived>
414 class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors> {
415  public:
417  typedef typename internal::traits<Derived>::Scalar Scalar;
418  typedef typename NumTraits<Scalar>::Real RealScalar;
419 
420  using Base::cols;
421  using Base::derived;
422  using Base::rows;
423  using Base::size;
424 
429  EIGEN_DEVICE_FUNC constexpr Index innerStride() const { return derived().innerStride(); }
430 
436  EIGEN_DEVICE_FUNC constexpr Index outerStride() const { return derived().outerStride(); }
437 
438  // FIXME shall we remove it ?
439  constexpr Index stride() const { return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); }
440 
445  EIGEN_DEVICE_FUNC constexpr Index rowStride() const { return Derived::IsRowMajor ? outerStride() : innerStride(); }
446 
451  EIGEN_DEVICE_FUNC constexpr Index colStride() const { return Derived::IsRowMajor ? innerStride() : outerStride(); }
452 };
453 
466 template <typename Derived>
467 class DenseCoeffsBase<Derived, DirectWriteAccessors> : public DenseCoeffsBase<Derived, WriteAccessors> {
468  public:
470  typedef typename internal::traits<Derived>::Scalar Scalar;
471  typedef typename NumTraits<Scalar>::Real RealScalar;
472 
473  using Base::cols;
474  using Base::derived;
475  using Base::rows;
476  using Base::size;
477 
482  EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept { return derived().innerStride(); }
483 
489  EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept { return derived().outerStride(); }
490 
491  // FIXME shall we remove it ?
492  constexpr Index stride() const noexcept { return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); }
493 
498  EIGEN_DEVICE_FUNC constexpr Index rowStride() const noexcept {
499  return Derived::IsRowMajor ? outerStride() : innerStride();
500  }
501 
506  EIGEN_DEVICE_FUNC constexpr Index colStride() const noexcept {
507  return Derived::IsRowMajor ? innerStride() : outerStride();
508  }
509 };
510 
511 namespace internal {
512 
513 template <int Alignment, typename Derived, bool JustReturnZero>
514 struct first_aligned_impl {
515  static constexpr Index run(const Derived&) noexcept { return 0; }
516 };
517 
518 template <int Alignment, typename Derived>
519 struct first_aligned_impl<Alignment, Derived, false> {
520  static inline Index run(const Derived& m) { return internal::first_aligned<Alignment>(m.data(), m.size()); }
521 };
522 
531 template <int Alignment, typename Derived>
532 static inline Index first_aligned(const DenseBase<Derived>& m) {
533  enum { ReturnZero = (int(evaluator<Derived>::Alignment) >= Alignment) || !(Derived::Flags & DirectAccessBit) };
534  return first_aligned_impl<Alignment, Derived, ReturnZero>::run(m.derived());
535 }
536 
537 template <typename Derived>
538 static inline Index first_default_aligned(const DenseBase<Derived>& m) {
539  typedef typename Derived::Scalar Scalar;
540  typedef typename packet_traits<Scalar>::type DefaultPacketType;
541  return internal::first_aligned<int(unpacket_traits<DefaultPacketType>::alignment), Derived>(m);
542 }
543 
544 template <typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
545 struct inner_stride_at_compile_time {
546  enum { ret = traits<Derived>::InnerStrideAtCompileTime };
547 };
548 
549 template <typename Derived>
550 struct inner_stride_at_compile_time<Derived, false> {
551  enum { ret = 0 };
552 };
553 
554 template <typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
555 struct outer_stride_at_compile_time {
556  enum { ret = traits<Derived>::OuterStrideAtCompileTime };
557 };
558 
559 template <typename Derived>
560 struct outer_stride_at_compile_time<Derived, false> {
561  enum { ret = 0 };
562 };
563 
564 } // end namespace internal
565 
566 } // end namespace Eigen
567 
568 #endif // EIGEN_DENSECOEFFSBASE_H
constexpr CoeffReturnType x() const
Definition: DenseCoeffsBase.h:170
constexpr Scalar & operator()(Index row, Index col)
Definition: DenseCoeffsBase.h:320
Definition: Constants.h:374
constexpr CoeffReturnType operator()(Index row, Index col) const
Definition: DenseCoeffsBase.h:111
constexpr Index rowStride() const
Definition: DenseCoeffsBase.h:445
constexpr Scalar & x()
Definition: DenseCoeffsBase.h:377
const unsigned int DirectAccessBit
Definition: Constants.h:159
constexpr CoeffReturnType coeff(Index row, Index col) const
Definition: DenseCoeffsBase.h:98
constexpr Index outerStride() const noexcept
Definition: DenseCoeffsBase.h:489
const unsigned int LvalueBit
Definition: Constants.h:148
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:232
constexpr CoeffReturnType z() const
Definition: DenseCoeffsBase.h:181
constexpr CoeffReturnType coeff(Index index) const
Definition: DenseCoeffsBase.h:131
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:43
const unsigned int RowMajorBit
Definition: Constants.h:70
constexpr Index colStride() const noexcept
Definition: DenseCoeffsBase.h:506
constexpr Index innerStride() const
Definition: DenseCoeffsBase.h:429
Definition: EigenBase.h:33
Definition: Constants.h:372
constexpr Scalar & operator()(Index index)
Definition: DenseCoeffsBase.h:370
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
constexpr CoeffReturnType y() const
Definition: DenseCoeffsBase.h:174
constexpr CoeffReturnType operator()(Index index) const
Definition: DenseCoeffsBase.h:163
constexpr Scalar & coeffRef(Index row, Index col)
Definition: DenseCoeffsBase.h:306
Definition: Constants.h:376
constexpr Scalar & z()
Definition: DenseCoeffsBase.h:388
constexpr Scalar & operator[](Index index)
Definition: DenseCoeffsBase.h:354
constexpr Scalar & y()
Definition: DenseCoeffsBase.h:381
Definition: Constants.h:378
constexpr Scalar & w()
Definition: DenseCoeffsBase.h:395
constexpr CoeffReturnType operator[](Index index) const
Definition: DenseCoeffsBase.h:146
constexpr CoeffReturnType w() const
Definition: DenseCoeffsBase.h:188
Base class providing read-only coefficient access to matrices and arrays.
Definition: DenseCoeffsBase.h:38
constexpr Index rowStride() const noexcept
Definition: DenseCoeffsBase.h:498
constexpr Index innerStride() const noexcept
Definition: DenseCoeffsBase.h:482
Base class providing read/write coefficient access to matrices and arrays.
Definition: DenseCoeffsBase.h:269
constexpr Index outerStride() const
Definition: DenseCoeffsBase.h:436
const unsigned int LinearAccessBit
Definition: Constants.h:133
constexpr Index colStride() const
Definition: DenseCoeffsBase.h:451
constexpr Scalar & coeffRef(Index index)
Definition: DenseCoeffsBase.h:340