Eigen  5.0.1-dev+7c7d8473
 
Loading...
Searching...
No Matches
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
16namespace Eigen {
17
18namespace internal {
19template <typename T>
20struct 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
37template <typename Derived>
38class 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
116#ifdef EIGEN_MULTIDIMENSIONAL_SUBSCRIPT
121 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType operator[](Index row, Index col) const {
122 return operator()(row, col);
123 }
124#endif
125
140
141 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType coeff(Index index) const {
142 EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
143 THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
144 eigen_internal_assert(index >= 0 && index < size());
145 return internal::evaluator<Derived>(derived()).coeff(index);
146 }
147
155
156 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType operator[](Index index) const {
157 EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
158 THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
159 eigen_assert(index >= 0 && index < size());
160 return coeff(index);
161 }
162
172
173 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType operator()(Index index) const {
174 eigen_assert(index >= 0 && index < size());
175 return coeff(index);
176 }
177
179
180 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType x() const { return (*this)[0]; }
181
183
184 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType y() const {
185 EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 2, OUT_OF_RANGE_ACCESS);
186 return (*this)[1];
187 }
188
190
191 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType z() const {
192 EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 3, OUT_OF_RANGE_ACCESS);
193 return (*this)[2];
194 }
195
197
198 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr CoeffReturnType w() const {
199 EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 4, OUT_OF_RANGE_ACCESS);
200 return (*this)[3];
201 }
202
212
213 template <int LoadMode>
214 EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const {
215 typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
216 eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
217 return internal::evaluator<Derived>(derived()).template packet<LoadMode, DefaultPacketType>(row, col);
218 }
219
221 template <int LoadMode>
222 EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const {
223 return packet<LoadMode>(rowIndexByOuterInner(outer, inner), colIndexByOuterInner(outer, inner));
224 }
225
235
236 template <int LoadMode>
237 EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const {
238 EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
239 THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
240 typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
241 eigen_internal_assert(index >= 0 && index < size());
242 return internal::evaluator<Derived>(derived()).template packet<LoadMode, DefaultPacketType>(index);
243 }
244
245 protected:
246 // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase.
247 // But some methods are only available in the DirectAccess case.
248 // So we add dummy methods here with these names, so that "using... " doesn't fail.
249 // It's not private so that the child class DenseBase can access them, and it's not public
250 // either since it's an implementation detail, so has to be protected.
251 void coeffRef();
252 void coeffRefByOuterInner();
253 void writePacket();
254 void writePacketByOuterInner();
255 void copyCoeff();
256 void copyCoeffByOuterInner();
257 void copyPacket();
258 void copyPacketByOuterInner();
259 void stride();
260 void innerStride();
261 void outerStride();
262 void rowStride();
263 void colStride();
264};
265
278template <typename Derived>
279class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors> {
280 public:
281 typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
282
283 typedef typename internal::traits<Derived>::StorageKind StorageKind;
284 typedef typename internal::traits<Derived>::Scalar Scalar;
285 typedef typename internal::packet_traits<Scalar>::type PacketScalar;
286 typedef typename NumTraits<Scalar>::Real RealScalar;
287
288 using Base::coeff;
289 using Base::colIndexByOuterInner;
290 using Base::cols;
291 using Base::derived;
292 using Base::rowIndexByOuterInner;
293 using Base::rows;
294 using Base::size;
295 using Base::operator[];
296 using Base::operator();
297 using Base::w;
298 using Base::x;
299 using Base::y;
300 using Base::z;
301
316 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& coeffRef(Index row, Index col) {
317 eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
318 return internal::evaluator<Derived>(derived()).coeffRef(row, col);
319 }
320
321 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRefByOuterInner(Index outer, Index inner) {
322 return coeffRef(rowIndexByOuterInner(outer, inner), colIndexByOuterInner(outer, inner));
323 }
324
329 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& operator()(Index row, Index col) {
330 eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
331 return coeffRef(row, col);
332 }
333
334#ifdef EIGEN_MULTIDIMENSIONAL_SUBSCRIPT
339 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& operator[](Index row, Index col) {
340 return operator()(row, col);
341 }
342#endif
343
358
359 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& coeffRef(Index index) {
360 EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
361 THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
362 eigen_internal_assert(index >= 0 && index < size());
363 return internal::evaluator<Derived>(derived()).coeffRef(index);
364 }
365
372
373 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& operator[](Index index) {
374 EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
375 THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
376 eigen_assert(index >= 0 && index < size());
377 return coeffRef(index);
378 }
379
388
389 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& operator()(Index index) {
390 eigen_assert(index >= 0 && index < size());
391 return coeffRef(index);
392 }
393
395
396 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& x() { return (*this)[0]; }
397
399
400 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& y() {
401 EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 2, OUT_OF_RANGE_ACCESS);
402 return (*this)[1];
403 }
404
406
407 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& z() {
408 EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 3, OUT_OF_RANGE_ACCESS);
409 return (*this)[2];
410 }
411
413
414 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Scalar& w() {
415 EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 4, OUT_OF_RANGE_ACCESS);
416 return (*this)[3];
417 }
418};
419
432template <typename Derived>
433class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors> {
434 public:
435 typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
436 typedef typename internal::traits<Derived>::Scalar Scalar;
437 typedef typename NumTraits<Scalar>::Real RealScalar;
438
439 using Base::cols;
440 using Base::derived;
441 using Base::rows;
442 using Base::size;
443
448 EIGEN_DEVICE_FUNC constexpr Index innerStride() const { return derived().innerStride(); }
449
455 EIGEN_DEVICE_FUNC constexpr Index outerStride() const { return derived().outerStride(); }
456
457 // FIXME shall we remove it ?
458 constexpr Index stride() const { return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); }
459
464 EIGEN_DEVICE_FUNC constexpr Index rowStride() const { return Derived::IsRowMajor ? outerStride() : innerStride(); }
465
470 EIGEN_DEVICE_FUNC constexpr Index colStride() const { return Derived::IsRowMajor ? innerStride() : outerStride(); }
471};
472
485template <typename Derived>
486class DenseCoeffsBase<Derived, DirectWriteAccessors> : public DenseCoeffsBase<Derived, WriteAccessors> {
487 public:
488 typedef DenseCoeffsBase<Derived, WriteAccessors> Base;
489 typedef typename internal::traits<Derived>::Scalar Scalar;
490 typedef typename NumTraits<Scalar>::Real RealScalar;
491
492 using Base::cols;
493 using Base::derived;
494 using Base::rows;
495 using Base::size;
496
501 EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept { return derived().innerStride(); }
502
508 EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept { return derived().outerStride(); }
509
510 // FIXME shall we remove it ?
511 constexpr Index stride() const noexcept { return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); }
512
517 EIGEN_DEVICE_FUNC constexpr Index rowStride() const noexcept {
518 return Derived::IsRowMajor ? outerStride() : innerStride();
519 }
520
525 EIGEN_DEVICE_FUNC constexpr Index colStride() const noexcept {
526 return Derived::IsRowMajor ? innerStride() : outerStride();
527 }
528};
529
530namespace internal {
531
532template <int Alignment, typename Derived, bool JustReturnZero>
533struct first_aligned_impl {
534 static constexpr Index run(const Derived&) noexcept { return 0; }
535};
536
537template <int Alignment, typename Derived>
538struct first_aligned_impl<Alignment, Derived, false> {
539 static inline Index run(const Derived& m) { return internal::first_aligned<Alignment>(m.data(), m.size()); }
540};
541
550template <int Alignment, typename Derived>
551static inline Index first_aligned(const DenseBase<Derived>& m) {
552 enum { ReturnZero = (int(evaluator<Derived>::Alignment) >= Alignment) || !(Derived::Flags & DirectAccessBit) };
553 return first_aligned_impl<Alignment, Derived, ReturnZero>::run(m.derived());
554}
555
556template <typename Derived>
557static inline Index first_default_aligned(const DenseBase<Derived>& m) {
558 typedef typename Derived::Scalar Scalar;
559 typedef typename packet_traits<Scalar>::type DefaultPacketType;
560 return internal::first_aligned<int(unpacket_traits<DefaultPacketType>::alignment), Derived>(m);
561}
562
563template <typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
564struct inner_stride_at_compile_time {
565 enum { ret = traits<Derived>::InnerStrideAtCompileTime };
566};
567
568template <typename Derived>
569struct inner_stride_at_compile_time<Derived, false> {
570 enum { ret = 0 };
571};
572
573template <typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
574struct outer_stride_at_compile_time {
575 enum { ret = traits<Derived>::OuterStrideAtCompileTime };
576};
577
578template <typename Derived>
579struct outer_stride_at_compile_time<Derived, false> {
580 enum { ret = 0 };
581};
582
583} // end namespace internal
584
585} // end namespace Eigen
586
587#endif // EIGEN_DENSECOEFFSBASE_H
constexpr Index rowStride() const
Definition DenseCoeffsBase.h:464
constexpr Index innerStride() const
Definition DenseCoeffsBase.h:448
constexpr Index colStride() const
Definition DenseCoeffsBase.h:470
constexpr Index outerStride() const
Definition DenseCoeffsBase.h:455
constexpr Index colStride() const noexcept
Definition DenseCoeffsBase.h:525
constexpr Index innerStride() const noexcept
Definition DenseCoeffsBase.h:501
constexpr Index outerStride() const noexcept
Definition DenseCoeffsBase.h:508
constexpr Index rowStride() const noexcept
Definition DenseCoeffsBase.h:517
@ DirectAccessors
Definition Constants.h:376
@ ReadOnlyAccessors
Definition Constants.h:372
@ WriteAccessors
Definition Constants.h:374
@ DirectWriteAccessors
Definition Constants.h:378
const unsigned int LinearAccessBit
Definition Constants.h:133
const unsigned int DirectAccessBit
Definition Constants.h:159
const unsigned int LvalueBit
Definition Constants.h:148
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82
Definition EigenBase.h:33