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