Eigen-Contrib  5.0.1
 
Loading...
Searching...
No Matches
TensorFixedSize.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@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_TENSOR_TENSOR_FIXED_SIZE_H
12#define EIGEN_TENSOR_TENSOR_FIXED_SIZE_H
13
14// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18
29template <typename Scalar_, typename Dimensions_, int Options_, typename IndexType>
30class TensorFixedSize : public TensorBase<TensorFixedSize<Scalar_, Dimensions_, Options_, IndexType> > {
31 public:
32 typedef TensorFixedSize<Scalar_, Dimensions_, Options_, IndexType> Self;
34 typedef typename Eigen::internal::ref_selector<Self>::type Nested;
35 typedef typename internal::traits<Self>::StorageKind StorageKind;
36 typedef typename internal::traits<Self>::Index Index;
37 typedef Scalar_ Scalar;
38 typedef typename NumTraits<Scalar>::Real RealScalar;
39 typedef typename Base::CoeffReturnType CoeffReturnType;
40
41 static constexpr int Options = Options_;
42 static constexpr int Layout = Options_ & RowMajor ? RowMajor : ColMajor;
43
44 enum {
45 IsAligned = bool(EIGEN_MAX_STATIC_ALIGN_BYTES >= Aligned),
46 PacketAccess = (internal::packet_traits<Scalar>::size > 1),
47 BlockAccess = false,
48 PreferBlockAccess = false,
49 CoordAccess = true,
50 RawAccess = true
51 };
52
53 //===- Tensor block evaluation strategy (see TensorBlock.h) -------------===//
54 typedef internal::TensorBlockNotImplemented TensorBlock;
55 //===--------------------------------------------------------------------===//
56
57 typedef Dimensions_ Dimensions;
58 static constexpr std::size_t NumIndices = Dimensions::count;
59
60 protected:
61 TensorStorage<Scalar, Dimensions, Options> m_storage;
62
63 public:
64 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rank() const { return NumIndices; }
65 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index dimension(std::size_t n) const { return m_storage.dimensions()[n]; }
66 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Dimensions dimensions() const { return m_storage.dimensions(); }
67 constexpr EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size() const { return m_storage.size(); }
68 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar* data() { return m_storage.data(); }
69 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar* data() const { return m_storage.data(); }
70
71 // This makes EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
72 // work, because that uses base().coeffRef() - and we don't yet
73 // implement a similar class hierarchy
74 inline Self& base() { return *this; }
75 inline const Self& base() const { return *this; }
76
77 template <typename... IndexTypes>
78 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(Index firstIndex, IndexTypes... otherIndices) const {
79 // The number of indices used to access a tensor coefficient must be equal to the rank of the tensor.
80 EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
81 eigen_assert(internal::indices_fit<Index>(otherIndices...));
82 return coeff(array<Index, NumIndices>{{firstIndex, static_cast<Index>(otherIndices)...}});
83 }
84
85 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(const array<Index, NumIndices>& indices) const {
86 eigen_internal_assert(checkIndexRange(indices));
87 return m_storage.data()[linearizedIndex(indices)];
88 }
89
90 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff(Index index) const {
91 eigen_internal_assert(index >= 0 && index < size());
92 return m_storage.data()[index];
93 }
94
95 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& coeff() const {
96 EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
97 return m_storage.data()[0];
98 }
99
100 template <typename... IndexTypes>
101 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index firstIndex, IndexTypes... otherIndices) {
102 // The number of indices used to access a tensor coefficient must be equal to the rank of the tensor.
103 EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
104 eigen_assert(internal::indices_fit<Index>(otherIndices...));
105 return coeffRef(array<Index, NumIndices>{{firstIndex, static_cast<Index>(otherIndices)...}});
106 }
107
108 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(const array<Index, NumIndices>& indices) {
109 eigen_internal_assert(checkIndexRange(indices));
110 return m_storage.data()[linearizedIndex(indices)];
111 }
112
113 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
114 eigen_internal_assert(index >= 0 && index < size());
115 return m_storage.data()[index];
116 }
117
118 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef() {
119 EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
120 return m_storage.data()[0];
121 }
122
123 template <typename... IndexTypes>
124 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(Index firstIndex, IndexTypes... otherIndices) const {
125 // The number of indices used to access a tensor coefficient must be equal to the rank of the tensor.
126 EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
127 eigen_assert(internal::indices_fit<Index>(otherIndices...));
128 return this->operator()(array<Index, NumIndices>{{firstIndex, static_cast<Index>(otherIndices)...}});
129 }
130
131 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(const array<Index, NumIndices>& indices) const {
132 eigen_assert(checkIndexRange(indices));
133 return coeff(indices);
134 }
135
136 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()(Index index) const {
137 eigen_internal_assert(index >= 0 && index < size());
138 return coeff(index);
139 }
140
141 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator()() const {
142 EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
143 return coeff();
144 }
145
146 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar& operator[](Index index) const {
147 // The bracket operator is only for vectors, use the parenthesis operator instead.
148 EIGEN_STATIC_ASSERT(NumIndices == 1, YOU_MADE_A_PROGRAMMING_MISTAKE);
149 return coeff(index);
150 }
151
152 template <typename... IndexTypes>
153 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(Index firstIndex, IndexTypes... otherIndices) {
154 // The number of indices used to access a tensor coefficient must be equal to the rank of the tensor.
155 EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
156 eigen_assert(internal::indices_fit<Index>(otherIndices...));
157 return operator()(array<Index, NumIndices>{{firstIndex, static_cast<Index>(otherIndices)...}});
158 }
159
160 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(const array<Index, NumIndices>& indices) {
161 eigen_assert(checkIndexRange(indices));
162 return coeffRef(indices);
163 }
164
165 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(Index index) {
166 eigen_assert(index >= 0 && index < size());
167 return coeffRef(index);
168 }
169
170 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()() {
171 EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
172 return coeffRef();
173 }
174
175 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator[](Index index) {
176 // The bracket operator is only for vectors, use the parenthesis operator instead.
177 EIGEN_STATIC_ASSERT(NumIndices == 1, YOU_MADE_A_PROGRAMMING_MISTAKE)
178 return coeffRef(index);
179 }
180
181 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorFixedSize() : m_storage() {}
182
183 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorFixedSize(Self&& other) : m_storage(other.m_storage) {}
184
185 template <typename OtherDerived>
186 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorFixedSize(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) {
188 Assign assign(*this, other.derived());
189 internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
190 }
191 template <typename OtherDerived>
192 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorFixedSize(const TensorBase<OtherDerived, WriteAccessors>& other) {
194 Assign assign(*this, other.derived());
195 internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
196 }
197
198 // FIXME: check that the dimensions of other match the dimensions of *this.
199 // Unfortunately this isn't possible yet when the rhs is an expression.
200 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TensorFixedSize)
201
202 protected:
203 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool checkIndexRange(const array<Index, NumIndices>& /*indices*/) const {
204 return true;
205 }
206
207 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index linearizedIndex(const array<Index, NumIndices>& indices) const {
208 EIGEN_IF_CONSTEXPR (Options & RowMajor) {
209 return internal::convert_index<Index>(m_storage.dimensions().IndexOfRowMajor(indices));
210 } else {
211 return internal::convert_index<Index>(m_storage.dimensions().IndexOfColMajor(indices));
212 }
213 }
214};
215
216} // end namespace Eigen
217
218#endif // EIGEN_TENSOR_TENSOR_FIXED_SIZE_H
Definition TensorAssign.h:47
The tensor base class.
Definition TensorForwardDeclarations.h:69
Namespace containing all symbols from the Eigen library.