Eigen  5.0.1
 
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// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_DENSECOEFFSBASE_H
12#define EIGEN_DENSECOEFFSBASE_H
13
14// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18
31template <typename Derived>
32class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
33 public:
34 using StorageKind = typename internal::traits<Derived>::StorageKind;
35 using Scalar = typename internal::traits<Derived>::Scalar;
36 using PacketScalar = typename internal::packet_traits<Scalar>::type;
37
38 // Explanation for this CoeffReturnType typedef.
39 // - This is the return type of the coeff() method.
40 // - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references
41 // to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value).
42 // - The DirectAccessBit means exactly that the underlying data of coefficients can be directly accessed as a plain
43 // strided array, which means exactly that the underlying data of coefficients does exist in memory, which means
44 // exactly that the coefficients is const-referencable, which means exactly that we can have coeff() return a const
45 // reference. For example, Map<const Matrix> have DirectAccessBit but not LvalueBit, so that Map<const Matrix>.coeff()
46 // does points to a const Scalar& which exists in memory, while does not allow coeffRef() as it would not provide a
47 // lvalue. Notice that DirectAccessBit and LvalueBit are mutually orthogonal.
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 using CoeffReturnType =
52 std::conditional_t<bool(internal::traits<Derived>::Flags&(LvalueBit | DirectAccessBit)), const Scalar&,
53 std::conditional_t<internal::is_arithmetic<Scalar>::value, Scalar, const Scalar>>;
54
55 using PacketReturnType = std::conditional_t<internal::is_arithmetic<PacketScalar>::value, PacketScalar,
56 internal::add_const_on_value_type_t<PacketScalar>>;
57
58 using Base = EigenBase<Derived>;
59 using Base::cols;
60 using Base::derived;
61 using Base::rows;
62 using Base::size;
63
64 EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const {
65 return int(Derived::RowsAtCompileTime) == 1 ? 0
66 : int(Derived::ColsAtCompileTime) == 1 ? inner
67 : int(Derived::Flags) & RowMajorBit ? outer
68 : inner;
69 }
70
71 EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const {
72 return int(Derived::ColsAtCompileTime) == 1 ? 0
73 : int(Derived::RowsAtCompileTime) == 1 ? inner
74 : int(Derived::Flags) & RowMajorBit ? inner
75 : outer;
76 }
77
92 EIGEN_DEVICE_FUNC constexpr CoeffReturnType coeff(Index row, Index col) const {
93 eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
94 return internal::evaluator<Derived>(derived()).coeff(row, col);
95 }
96
97 EIGEN_DEVICE_FUNC constexpr CoeffReturnType coeffByOuterInner(Index outer, Index inner) const {
98 return coeff(rowIndexByOuterInner(outer, inner), colIndexByOuterInner(outer, inner));
99 }
100
105 EIGEN_DEVICE_FUNC constexpr CoeffReturnType operator()(Index row, Index col) const {
106 eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
107 return coeff(row, col);
108 }
109
110#ifdef EIGEN_MULTIDIMENSIONAL_SUBSCRIPT
115 EIGEN_DEVICE_FUNC constexpr CoeffReturnType operator[](Index row, Index col) const { return operator()(row, col); }
116#endif
117
132
133 EIGEN_DEVICE_FUNC constexpr CoeffReturnType coeff(Index index) const {
134 EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
135 THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
136 eigen_internal_assert(index >= 0 && index < size());
137 return internal::evaluator<Derived>(derived()).coeff(index);
138 }
139
148
149 EIGEN_DEVICE_FUNC constexpr CoeffReturnType operator[](Index index) const {
150 EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
151 THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
152 eigen_assert(index >= 0 && index < size());
153 return coeff(index);
154 }
155
165
166 EIGEN_DEVICE_FUNC constexpr CoeffReturnType operator()(Index index) const {
167 eigen_assert(index >= 0 && index < size());
168 return coeff(index);
169 }
170
172
173 EIGEN_DEVICE_FUNC constexpr CoeffReturnType x() const { return (*this)[0]; }
174
176
177 EIGEN_DEVICE_FUNC constexpr CoeffReturnType y() const {
178 EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 2, OUT_OF_RANGE_ACCESS);
179 return (*this)[1];
180 }
181
183
184 EIGEN_DEVICE_FUNC constexpr CoeffReturnType z() const {
185 EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 3, OUT_OF_RANGE_ACCESS);
186 return (*this)[2];
187 }
188
190
191 EIGEN_DEVICE_FUNC constexpr CoeffReturnType w() const {
192 EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 4, OUT_OF_RANGE_ACCESS);
193 return (*this)[3];
194 }
195
205
206 template <int LoadMode>
207 EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const {
208 using DefaultPacketType = typename internal::packet_traits<Scalar>::type;
209 eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
210 return internal::evaluator<Derived>(derived()).template packet<LoadMode, DefaultPacketType>(row, col);
211 }
212
214 template <int LoadMode>
215 EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const {
216 return packet<LoadMode>(rowIndexByOuterInner(outer, inner), colIndexByOuterInner(outer, inner));
217 }
218
228
229 template <int LoadMode>
230 EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const {
231 EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
232 THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
233 using DefaultPacketType = typename internal::packet_traits<Scalar>::type;
234 eigen_internal_assert(index >= 0 && index < size());
235 return internal::evaluator<Derived>(derived()).template packet<LoadMode, DefaultPacketType>(index);
236 }
237
238 protected:
239 // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase.
240 // But some methods are only available in the DirectAccess case.
241 // So we add dummy methods here with these names, so that "using... " doesn't fail.
242 // It's not private so that the child class DenseBase can access them, and it's not public
243 // either since it's an implementation detail, so has to be protected.
244 void coeffRef();
245 void coeffRefByOuterInner();
246 void writePacket();
247 void writePacketByOuterInner();
248 void copyCoeff();
249 void copyCoeffByOuterInner();
250 void copyPacket();
251 void copyPacketByOuterInner();
252 void stride();
253 void innerStride();
254 void outerStride();
255 void rowStride();
256 void colStride();
257};
258
271template <typename Derived>
272class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors> {
273 public:
274 using Base = DenseCoeffsBase<Derived, ReadOnlyAccessors>;
275
276 using StorageKind = typename internal::traits<Derived>::StorageKind;
277 using Scalar = typename internal::traits<Derived>::Scalar;
278 using PacketScalar = typename internal::packet_traits<Scalar>::type;
279 using RealScalar = typename NumTraits<Scalar>::Real;
280
281 using Base::coeff;
282 using Base::colIndexByOuterInner;
283 using Base::cols;
284 using Base::derived;
285 using Base::rowIndexByOuterInner;
286 using Base::rows;
287 using Base::size;
288 using Base::operator[];
289 using Base::operator();
290 using Base::w;
291 using Base::x;
292 using Base::y;
293 using Base::z;
294
309 EIGEN_DEVICE_FUNC constexpr Scalar& coeffRef(Index row, Index col) {
310 eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
311 return internal::evaluator<Derived>(derived()).coeffRef(row, col);
312 }
313
314 EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Scalar& coeffRefByOuterInner(Index outer, Index inner) {
315 return coeffRef(rowIndexByOuterInner(outer, inner), colIndexByOuterInner(outer, inner));
316 }
317
322 EIGEN_DEVICE_FUNC constexpr Scalar& operator()(Index row, Index col) {
323 eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
324 return coeffRef(row, col);
325 }
326
327#ifdef EIGEN_MULTIDIMENSIONAL_SUBSCRIPT
332 EIGEN_DEVICE_FUNC constexpr Scalar& operator[](Index row, Index col) { return operator()(row, col); }
333#endif
334
349
350 EIGEN_DEVICE_FUNC constexpr Scalar& coeffRef(Index index) {
351 EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
352 THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
353 eigen_internal_assert(index >= 0 && index < size());
354 return internal::evaluator<Derived>(derived()).coeffRef(index);
355 }
356
364
365 EIGEN_DEVICE_FUNC constexpr Scalar& operator[](Index index) {
366 EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
367 THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
368 eigen_assert(index >= 0 && index < size());
369 return coeffRef(index);
370 }
371
380
381 EIGEN_DEVICE_FUNC constexpr Scalar& operator()(Index index) {
382 eigen_assert(index >= 0 && index < size());
383 return coeffRef(index);
384 }
385
387
388 EIGEN_DEVICE_FUNC constexpr Scalar& x() { return (*this)[0]; }
389
391
392 EIGEN_DEVICE_FUNC constexpr Scalar& y() {
393 EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 2, OUT_OF_RANGE_ACCESS);
394 return (*this)[1];
395 }
396
398
399 EIGEN_DEVICE_FUNC constexpr Scalar& z() {
400 EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 3, OUT_OF_RANGE_ACCESS);
401 return (*this)[2];
402 }
403
405
406 EIGEN_DEVICE_FUNC constexpr Scalar& w() {
407 EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime == -1 || Derived::SizeAtCompileTime >= 4, OUT_OF_RANGE_ACCESS);
408 return (*this)[3];
409 }
410};
411
424template <typename Derived>
425class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors> {
426 public:
427 using Base = DenseCoeffsBase<Derived, ReadOnlyAccessors>;
428 using Scalar = typename internal::traits<Derived>::Scalar;
429 using RealScalar = typename NumTraits<Scalar>::Real;
430
431 using Base::cols;
432 using Base::derived;
433 using Base::rows;
434 using Base::size;
435
440 EIGEN_DEVICE_FUNC constexpr Index innerStride() const { return derived().innerStride(); }
441
447 EIGEN_DEVICE_FUNC constexpr Index outerStride() const { return derived().outerStride(); }
448
449 // FIXME shall we remove it ?
450 constexpr Index stride() const { return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); }
451
456 EIGEN_DEVICE_FUNC constexpr Index rowStride() const { return Derived::IsRowMajor ? outerStride() : innerStride(); }
457
462 EIGEN_DEVICE_FUNC constexpr Index colStride() const { return Derived::IsRowMajor ? innerStride() : outerStride(); }
463};
464
477template <typename Derived>
478class DenseCoeffsBase<Derived, DirectWriteAccessors> : public DenseCoeffsBase<Derived, WriteAccessors> {
479 public:
480 using Base = DenseCoeffsBase<Derived, WriteAccessors>;
481 using Scalar = typename internal::traits<Derived>::Scalar;
482 using RealScalar = typename NumTraits<Scalar>::Real;
483
484 using Base::cols;
485 using Base::derived;
486 using Base::rows;
487 using Base::size;
488
493 EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept { return derived().innerStride(); }
494
500 EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept { return derived().outerStride(); }
501
502 // FIXME shall we remove it ?
503 constexpr Index stride() const noexcept { return Derived::IsVectorAtCompileTime ? innerStride() : outerStride(); }
504
509 EIGEN_DEVICE_FUNC constexpr Index rowStride() const noexcept {
510 return Derived::IsRowMajor ? outerStride() : innerStride();
511 }
512
517 EIGEN_DEVICE_FUNC constexpr Index colStride() const noexcept {
518 return Derived::IsRowMajor ? innerStride() : outerStride();
519 }
520};
521
522namespace internal {
523
524template <int Alignment, typename Derived, bool JustReturnZero>
525struct first_aligned_impl {
526 static constexpr Index run(const Derived&) noexcept { return 0; }
527};
528
529template <int Alignment, typename Derived>
530struct first_aligned_impl<Alignment, Derived, false> {
531 static inline Index run(const Derived& m) { return internal::first_aligned<Alignment>(m.data(), m.size()); }
532};
533
542template <int Alignment, typename Derived>
543static inline Index first_aligned(const DenseBase<Derived>& m) {
544 enum { ReturnZero = (int(evaluator<Derived>::Alignment) >= Alignment) || !(Derived::Flags & DirectAccessBit) };
545 return first_aligned_impl<Alignment, Derived, ReturnZero>::run(m.derived());
546}
547
548template <typename Derived>
549static inline Index first_default_aligned(const DenseBase<Derived>& m) {
550 using Scalar = typename Derived::Scalar;
551 using DefaultPacketType = typename packet_traits<Scalar>::type;
552 return internal::first_aligned<int(unpacket_traits<DefaultPacketType>::alignment), Derived>(m);
553}
554
555template <typename Derived, bool HasDirectAccess = has_direct_access<Derived>::value>
556struct inner_stride_at_compile_time : std::integral_constant<int, traits<Derived>::InnerStrideAtCompileTime> {};
557
558template <typename Derived>
559struct inner_stride_at_compile_time<Derived, false> : std::integral_constant<int, 0> {};
560
561template <typename Derived, bool HasDirectAccess = has_direct_access<Derived>::value>
562struct outer_stride_at_compile_time : std::integral_constant<int, traits<Derived>::OuterStrideAtCompileTime> {};
563
564template <typename Derived>
565struct outer_stride_at_compile_time<Derived, false> : std::integral_constant<int, 0> {};
566
567} // end namespace internal
568
569} // end namespace Eigen
570
571#endif // EIGEN_DENSECOEFFSBASE_H
constexpr Index rowStride() const
Definition DenseCoeffsBase.h:456
constexpr Index innerStride() const
Definition DenseCoeffsBase.h:440
constexpr Index colStride() const
Definition DenseCoeffsBase.h:462
constexpr Index outerStride() const
Definition DenseCoeffsBase.h:447
constexpr Index colStride() const noexcept
Definition DenseCoeffsBase.h:517
constexpr Index innerStride() const noexcept
Definition DenseCoeffsBase.h:493
constexpr Index outerStride() const noexcept
Definition DenseCoeffsBase.h:500
constexpr Index rowStride() const noexcept
Definition DenseCoeffsBase.h:509
@ DirectAccessors
Definition Constants.h:381
@ ReadOnlyAccessors
Definition Constants.h:377
@ WriteAccessors
Definition Constants.h:379
@ DirectWriteAccessors
Definition Constants.h:383
constexpr unsigned int DirectAccessBit
Definition Constants.h:160
constexpr unsigned int LinearAccessBit
Definition Constants.h:134
constexpr unsigned int LvalueBit
Definition Constants.h:149
constexpr unsigned int RowMajorBit
Definition Constants.h:71
Definition EigenBase.h:34