$darkmode
Eigen-unsupported  5.0.1-dev
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 
16 namespace Eigen {
17 
28 template <typename Scalar_, typename Dimensions_, int Options_, typename IndexType>
29 class TensorFixedSize : public TensorBase<TensorFixedSize<Scalar_, Dimensions_, Options_, IndexType> > {
30  public:
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());
187  }
188  template <typename OtherDerived>
189  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorFixedSize(const TensorBase<OtherDerived, WriteAccessors>& other) {
191  Assign assign(*this, other.derived());
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
The tensor executor class.
Definition: TensorExecutor.h:76
Namespace containing all symbols from the Eigen library.
Definition: TensorAssign.h:55
The fixed sized version of the tensor class.
Definition: TensorFixedSize.h:29
The tensor base class.
Definition: TensorForwardDeclarations.h:68