Eigen  3.4.90 (git rev 67eeba6e720c5745abc77ae6c92ce0a44aa7b7ae)
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 #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>
54  > CoeffReturnType;
55 
56  typedef typename internal::add_const_on_value_type_if_arithmetic<
57  typename internal::packet_traits<Scalar>::type
58  >::type PacketReturnType;
59 
60  typedef EigenBase<Derived> Base;
61  using Base::rows;
62  using Base::cols;
63  using Base::size;
64  using Base::derived;
65 
66  EIGEN_DEVICE_FUNC
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 
75  EIGEN_DEVICE_FUNC
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 
98  EIGEN_DEVICE_FUNC
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 
106  EIGEN_DEVICE_FUNC
107  EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
108  {
109  return coeff(rowIndexByOuterInner(outer, inner),
110  colIndexByOuterInner(outer, inner));
111  }
112 
117  EIGEN_DEVICE_FUNC
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 
140  EIGEN_DEVICE_FUNC
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 
159  EIGEN_DEVICE_FUNC
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 
179  EIGEN_DEVICE_FUNC
180  EIGEN_STRONG_INLINE CoeffReturnType
181  operator()(Index index) const
182  {
183  eigen_assert(index >= 0 && index < size());
184  return coeff(index);
185  }
186 
189  EIGEN_DEVICE_FUNC
190  EIGEN_STRONG_INLINE CoeffReturnType
191  x() const { return (*this)[0]; }
192 
195  EIGEN_DEVICE_FUNC
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 
205  EIGEN_DEVICE_FUNC
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 
215  EIGEN_DEVICE_FUNC
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();
277  void coeffRefByOuterInner();
278  void writePacket();
279  void writePacketByOuterInner();
280  void copyCoeff();
281  void copyCoeffByOuterInner();
282  void copyPacket();
283  void copyPacketByOuterInner();
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;
313  typedef typename NumTraits<Scalar>::Real RealScalar;
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 
343  EIGEN_DEVICE_FUNC
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 
351  EIGEN_DEVICE_FUNC
352  EIGEN_STRONG_INLINE Scalar&
353  coeffRefByOuterInner(Index outer, Index inner)
354  {
355  return coeffRef(rowIndexByOuterInner(outer, inner),
356  colIndexByOuterInner(outer, inner));
357  }
358 
364  EIGEN_DEVICE_FUNC
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 
389  EIGEN_DEVICE_FUNC
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 
406  EIGEN_DEVICE_FUNC
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 
425  EIGEN_DEVICE_FUNC
426  EIGEN_STRONG_INLINE Scalar&
428  {
429  eigen_assert(index >= 0 && index < size());
430  return coeffRef(index);
431  }
432 
435  EIGEN_DEVICE_FUNC
436  EIGEN_STRONG_INLINE Scalar&
437  x() { return (*this)[0]; }
438 
441  EIGEN_DEVICE_FUNC
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 
451  EIGEN_DEVICE_FUNC
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 
461  EIGEN_DEVICE_FUNC
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;
489  typedef typename NumTraits<Scalar>::Real RealScalar;
490 
491  using Base::rows;
492  using Base::cols;
493  using Base::size;
494  using Base::derived;
495 
500  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
501  inline Index innerStride() const
502  {
503  return derived().innerStride();
504  }
505 
511  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
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 
527  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
528  inline Index rowStride() const
529  {
530  return Derived::IsRowMajor ? outerStride() : innerStride();
531  }
532 
537  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
538  inline Index colStride() const
539  {
540  return Derived::IsRowMajor ? innerStride() : outerStride();
541  }
542 };
543 
556 template<typename Derived>
557 class DenseCoeffsBase<Derived, DirectWriteAccessors>
558  : public DenseCoeffsBase<Derived, WriteAccessors>
559 {
560  public:
561 
563  typedef typename internal::traits<Derived>::Scalar Scalar;
564  typedef typename NumTraits<Scalar>::Real RealScalar;
565 
566  using Base::rows;
567  using Base::cols;
568  using Base::size;
569  using Base::derived;
570 
575  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
576  inline Index innerStride() const EIGEN_NOEXCEPT
577  {
578  return derived().innerStride();
579  }
580 
586  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
587  inline Index outerStride() const EIGEN_NOEXCEPT
588  {
589  return derived().outerStride();
590  }
591 
592  // FIXME shall we remove it ?
593  EIGEN_CONSTEXPR inline Index stride() const EIGEN_NOEXCEPT
594  {
595  return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
596  }
597 
602  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
603  inline Index rowStride() const EIGEN_NOEXCEPT
604  {
605  return Derived::IsRowMajor ? outerStride() : innerStride();
606  }
607 
612  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
613  inline Index colStride() const EIGEN_NOEXCEPT
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>
645 static inline Index first_aligned(const DenseBase<Derived>& m)
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>
652 static inline Index first_default_aligned(const DenseBase<Derived>& m)
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
EIGEN_CONSTEXPR Index innerStride() const
Definition: DenseCoeffsBase.h:501
EIGEN_CONSTEXPR Index rowStride() const
Definition: DenseCoeffsBase.h:528
EIGEN_CONSTEXPR Index outerStride() const
Definition: DenseCoeffsBase.h:512
EIGEN_CONSTEXPR Index colStride() const
Definition: DenseCoeffsBase.h:538
EIGEN_CONSTEXPR Index innerStride() const EIGEN_NOEXCEPT
Definition: DenseCoeffsBase.h:576
EIGEN_CONSTEXPR Index rowStride() const EIGEN_NOEXCEPT
Definition: DenseCoeffsBase.h:603
EIGEN_CONSTEXPR Index outerStride() const EIGEN_NOEXCEPT
Definition: DenseCoeffsBase.h:587
EIGEN_CONSTEXPR Index colStride() const EIGEN_NOEXCEPT
Definition: DenseCoeffsBase.h:613
Base class providing read-only coefficient access to matrices and arrays.
Definition: DenseCoeffsBase.h:38
CoeffReturnType y() const
Definition: DenseCoeffsBase.h:197
CoeffReturnType x() const
Definition: DenseCoeffsBase.h:191
CoeffReturnType operator[](Index index) const
Definition: DenseCoeffsBase.h:161
CoeffReturnType z() const
Definition: DenseCoeffsBase.h:207
CoeffReturnType w() const
Definition: DenseCoeffsBase.h:217
CoeffReturnType coeff(Index index) const
Definition: DenseCoeffsBase.h:142
CoeffReturnType operator()(Index row, Index col) const
Definition: DenseCoeffsBase.h:118
CoeffReturnType coeff(Index row, Index col) const
Definition: DenseCoeffsBase.h:99
CoeffReturnType operator()(Index index) const
Definition: DenseCoeffsBase.h:181
Base class providing read/write coefficient access to matrices and arrays.
Definition: DenseCoeffsBase.h:305
Scalar & operator()(Index index)
Definition: DenseCoeffsBase.h:427
Scalar & z()
Definition: DenseCoeffsBase.h:453
Scalar & operator[](Index index)
Definition: DenseCoeffsBase.h:408
Scalar & coeffRef(Index row, Index col)
Definition: DenseCoeffsBase.h:344
Scalar & coeffRef(Index index)
Definition: DenseCoeffsBase.h:391
Scalar & operator()(Index row, Index col)
Definition: DenseCoeffsBase.h:366
Scalar & x()
Definition: DenseCoeffsBase.h:437
Scalar & w()
Definition: DenseCoeffsBase.h:463
Scalar & y()
Definition: DenseCoeffsBase.h:443
@ 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
Namespace containing all symbols from the Eigen library.
Definition: Core:139
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:59
Definition: EigenBase.h:32
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