Eigen  3.2.91
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_internal_assert(index >= 0 && index < size());
142  return internal::evaluator<Derived>(derived()).coeff(index);
143  }
144 
145 
154  EIGEN_DEVICE_FUNC
155  EIGEN_STRONG_INLINE CoeffReturnType
156  operator[](Index index) const
157  {
158  EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
159  THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
160  eigen_assert(index >= 0 && index < size());
161  return coeff(index);
162  }
163 
174  EIGEN_DEVICE_FUNC
175  EIGEN_STRONG_INLINE CoeffReturnType
176  operator()(Index index) const
177  {
178  eigen_assert(index >= 0 && index < size());
179  return coeff(index);
180  }
181 
184  EIGEN_DEVICE_FUNC
185  EIGEN_STRONG_INLINE CoeffReturnType
186  x() const { return (*this)[0]; }
187 
190  EIGEN_DEVICE_FUNC
191  EIGEN_STRONG_INLINE CoeffReturnType
192  y() const { return (*this)[1]; }
193 
196  EIGEN_DEVICE_FUNC
197  EIGEN_STRONG_INLINE CoeffReturnType
198  z() const { return (*this)[2]; }
199 
202  EIGEN_DEVICE_FUNC
203  EIGEN_STRONG_INLINE CoeffReturnType
204  w() const { return (*this)[3]; }
205 
216  template<int LoadMode>
217  EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
218  {
219  typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
220  eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
221  return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(row,col);
222  }
223 
224 
226  template<int LoadMode>
227  EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const
228  {
229  return packet<LoadMode>(rowIndexByOuterInner(outer, inner),
230  colIndexByOuterInner(outer, inner));
231  }
232 
243  template<int LoadMode>
244  EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
245  {
246  typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
247  eigen_internal_assert(index >= 0 && index < size());
248  return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(index);
249  }
250 
251  protected:
252  // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase.
253  // But some methods are only available in the DirectAccess case.
254  // So we add dummy methods here with these names, so that "using... " doesn't fail.
255  // It's not private so that the child class DenseBase can access them, and it's not public
256  // either since it's an implementation detail, so has to be protected.
257  void coeffRef();
258  void coeffRefByOuterInner();
259  void writePacket();
260  void writePacketByOuterInner();
261  void copyCoeff();
262  void copyCoeffByOuterInner();
263  void copyPacket();
264  void copyPacketByOuterInner();
265  void stride();
266  void innerStride();
267  void outerStride();
268  void rowStride();
269  void colStride();
270 };
271 
283 template<typename Derived>
284 class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
285 {
286  public:
287 
289 
290  typedef typename internal::traits<Derived>::StorageKind StorageKind;
291  typedef typename internal::traits<Derived>::Scalar Scalar;
292  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
293  typedef typename NumTraits<Scalar>::Real RealScalar;
294 
295  using Base::coeff;
296  using Base::rows;
297  using Base::cols;
298  using Base::size;
299  using Base::derived;
300  using Base::rowIndexByOuterInner;
301  using Base::colIndexByOuterInner;
302  using Base::operator[];
303  using Base::operator();
304  using Base::x;
305  using Base::y;
306  using Base::z;
307  using Base::w;
308 
323  EIGEN_DEVICE_FUNC
324  EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
325  {
326  eigen_internal_assert(row >= 0 && row < rows()
327  && col >= 0 && col < cols());
328  return internal::evaluator<Derived>(derived()).coeffRef(row,col);
329  }
330 
331  EIGEN_DEVICE_FUNC
332  EIGEN_STRONG_INLINE Scalar&
333  coeffRefByOuterInner(Index outer, Index inner)
334  {
335  return coeffRef(rowIndexByOuterInner(outer, inner),
336  colIndexByOuterInner(outer, inner));
337  }
338 
344  EIGEN_DEVICE_FUNC
345  EIGEN_STRONG_INLINE Scalar&
347  {
348  eigen_assert(row >= 0 && row < rows()
349  && col >= 0 && col < cols());
350  return coeffRef(row, col);
351  }
352 
353 
369  EIGEN_DEVICE_FUNC
370  EIGEN_STRONG_INLINE Scalar&
372  {
373  eigen_internal_assert(index >= 0 && index < size());
374  return internal::evaluator<Derived>(derived()).coeffRef(index);
375  }
376 
384  EIGEN_DEVICE_FUNC
385  EIGEN_STRONG_INLINE Scalar&
387  {
388  EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
389  THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
390  eigen_assert(index >= 0 && index < size());
391  return coeffRef(index);
392  }
393 
403  EIGEN_DEVICE_FUNC
404  EIGEN_STRONG_INLINE Scalar&
406  {
407  eigen_assert(index >= 0 && index < size());
408  return coeffRef(index);
409  }
410 
413  EIGEN_DEVICE_FUNC
414  EIGEN_STRONG_INLINE Scalar&
415  x() { return (*this)[0]; }
416 
419  EIGEN_DEVICE_FUNC
420  EIGEN_STRONG_INLINE Scalar&
421  y() { return (*this)[1]; }
422 
425  EIGEN_DEVICE_FUNC
426  EIGEN_STRONG_INLINE Scalar&
427  z() { return (*this)[2]; }
428 
431  EIGEN_DEVICE_FUNC
432  EIGEN_STRONG_INLINE Scalar&
433  w() { return (*this)[3]; }
434 };
435 
447 template<typename Derived>
448 class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
449 {
450  public:
451 
453  typedef typename internal::traits<Derived>::Scalar Scalar;
454  typedef typename NumTraits<Scalar>::Real RealScalar;
455 
456  using Base::rows;
457  using Base::cols;
458  using Base::size;
459  using Base::derived;
460 
465  EIGEN_DEVICE_FUNC
466  inline Index innerStride() const
467  {
468  return derived().innerStride();
469  }
470 
476  EIGEN_DEVICE_FUNC
477  inline Index outerStride() const
478  {
479  return derived().outerStride();
480  }
481 
482  // FIXME shall we remove it ?
483  inline Index stride() const
484  {
485  return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
486  }
487 
492  EIGEN_DEVICE_FUNC
493  inline Index rowStride() const
494  {
495  return Derived::IsRowMajor ? outerStride() : innerStride();
496  }
497 
502  EIGEN_DEVICE_FUNC
503  inline Index colStride() const
504  {
505  return Derived::IsRowMajor ? innerStride() : outerStride();
506  }
507 };
508 
520 template<typename Derived>
521 class DenseCoeffsBase<Derived, DirectWriteAccessors>
522  : public DenseCoeffsBase<Derived, WriteAccessors>
523 {
524  public:
525 
527  typedef typename internal::traits<Derived>::Scalar Scalar;
528  typedef typename NumTraits<Scalar>::Real RealScalar;
529 
530  using Base::rows;
531  using Base::cols;
532  using Base::size;
533  using Base::derived;
534 
539  EIGEN_DEVICE_FUNC
540  inline Index innerStride() const
541  {
542  return derived().innerStride();
543  }
544 
550  EIGEN_DEVICE_FUNC
551  inline Index outerStride() const
552  {
553  return derived().outerStride();
554  }
555 
556  // FIXME shall we remove it ?
557  inline Index stride() const
558  {
559  return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
560  }
561 
566  EIGEN_DEVICE_FUNC
567  inline Index rowStride() const
568  {
569  return Derived::IsRowMajor ? outerStride() : innerStride();
570  }
571 
576  EIGEN_DEVICE_FUNC
577  inline Index colStride() const
578  {
579  return Derived::IsRowMajor ? innerStride() : outerStride();
580  }
581 };
582 
583 namespace internal {
584 
585 template<int Alignment, typename Derived, bool JustReturnZero>
586 struct first_aligned_impl
587 {
588  static inline Index run(const Derived&)
589  { return 0; }
590 };
591 
592 template<int Alignment, typename Derived>
593 struct first_aligned_impl<Alignment, Derived, false>
594 {
595  static inline Index run(const Derived& m)
596  {
597  return internal::first_aligned<Alignment>(&m.const_cast_derived().coeffRef(0,0), m.size());
598  }
599 };
600 
608 template<int Alignment, typename Derived>
609 static inline Index first_aligned(const DenseBase<Derived>& m)
610 {
611  enum { ReturnZero = (int(evaluator<Derived>::Alignment) >= Alignment) || !(Derived::Flags & DirectAccessBit) };
612  return first_aligned_impl<Alignment, Derived, ReturnZero>::run(m.derived());
613 }
614 
615 template<typename Derived>
616 static inline Index first_default_aligned(const DenseBase<Derived>& m)
617 {
618  typedef typename Derived::Scalar Scalar;
619  typedef typename packet_traits<Scalar>::type DefaultPacketType;
620  return first_aligned<unpacket_traits<DefaultPacketType>::alignment>(m);
621 }
622 
623 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
624 struct inner_stride_at_compile_time
625 {
626  enum { ret = traits<Derived>::InnerStrideAtCompileTime };
627 };
628 
629 template<typename Derived>
630 struct inner_stride_at_compile_time<Derived, false>
631 {
632  enum { ret = 0 };
633 };
634 
635 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
636 struct outer_stride_at_compile_time
637 {
638  enum { ret = traits<Derived>::OuterStrideAtCompileTime };
639 };
640 
641 template<typename Derived>
642 struct outer_stride_at_compile_time<Derived, false>
643 {
644  enum { ret = 0 };
645 };
646 
647 } // end namespace internal
648 
649 } // end namespace Eigen
650 
651 #endif // EIGEN_DENSECOEFFSBASE_H
Scalar & operator()(Index row, Index col)
Definition: DenseCoeffsBase.h:346
CoeffReturnType coeff(Index row, Index col) const
Definition: DenseCoeffsBase.h:96
Definition: Constants.h:360
CoeffReturnType coeff(Index index) const
Definition: DenseCoeffsBase.h:139
const unsigned int DirectAccessBit
Definition: Constants.h:141
Scalar & coeffRef(Index index)
Definition: DenseCoeffsBase.h:371
const unsigned int LvalueBit
Definition: Constants.h:130
Definition: LDLT.h:16
Scalar & operator()(Index index)
Definition: DenseCoeffsBase.h:405
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:107
Scalar & y()
Definition: DenseCoeffsBase.h:421
CoeffReturnType w() const
Definition: DenseCoeffsBase.h:204
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:37
const unsigned int RowMajorBit
Definition: Constants.h:53
Index rowStride() const
Definition: DenseCoeffsBase.h:567
CoeffReturnType z() const
Definition: DenseCoeffsBase.h:198
Scalar & operator[](Index index)
Definition: DenseCoeffsBase.h:386
CoeffReturnType operator()(Index row, Index col) const
Definition: DenseCoeffsBase.h:115
Definition: EigenBase.h:28
Scalar & z()
Definition: DenseCoeffsBase.h:427
Definition: Constants.h:358
Index outerStride() const
Definition: DenseCoeffsBase.h:477
Index outerStride() const
Definition: DenseCoeffsBase.h:551
Index colStride() const
Definition: DenseCoeffsBase.h:503
Definition: Constants.h:362
Scalar & x()
Definition: DenseCoeffsBase.h:415
Index innerStride() const
Definition: DenseCoeffsBase.h:540
Definition: Constants.h:364
Definition: Eigen_Colamd.h:54
CoeffReturnType operator()(Index index) const
Definition: DenseCoeffsBase.h:176
Index rowStride() const
Definition: DenseCoeffsBase.h:493
CoeffReturnType x() const
Definition: DenseCoeffsBase.h:186
Scalar & w()
Definition: DenseCoeffsBase.h:433
Base class providing read-only coefficient access to matrices and arrays.
Definition: DenseCoeffsBase.h:34
Index innerStride() const
Definition: DenseCoeffsBase.h:466
CoeffReturnType y() const
Definition: DenseCoeffsBase.h:192
Base class providing read/write coefficient access to matrices and arrays.
Definition: DenseCoeffsBase.h:284
Scalar & coeffRef(Index row, Index col)
Definition: DenseCoeffsBase.h:324
CoeffReturnType operator[](Index index) const
Definition: DenseCoeffsBase.h:156
Index colStride() const
Definition: DenseCoeffsBase.h:577