TensorMap.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_MAP_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_MAP_H
12 
13 namespace Eigen {
14 
22 template<typename PlainObjectType, int Options_> class TensorMap : public TensorBase<TensorMap<PlainObjectType, Options_> >
23 {
24  public:
25  typedef TensorMap<PlainObjectType, Options_> Self;
26  typedef typename PlainObjectType::Base Base;
27  typedef typename Eigen::internal::nested<Self>::type Nested;
28  typedef typename internal::traits<PlainObjectType>::StorageKind StorageKind;
29  typedef typename internal::traits<PlainObjectType>::Index Index;
30  typedef typename internal::traits<PlainObjectType>::Scalar Scalar;
31  typedef typename NumTraits<Scalar>::Real RealScalar;
32  typedef typename Base::CoeffReturnType CoeffReturnType;
33 
34  /* typedef typename internal::conditional<
35  bool(internal::is_lvalue<PlainObjectType>::value),
36  Scalar *,
37  const Scalar *>::type
38  PointerType;*/
39  typedef Scalar* PointerType;
40  typedef PointerType PointerArgType;
41 
42  static const int Options = Options_;
43 
44  static const Index NumIndices = PlainObjectType::NumIndices;
45  typedef typename PlainObjectType::Dimensions Dimensions;
46 
47  enum {
48  IsAligned = ((int(Options_)&Aligned)==Aligned),
49  Layout = PlainObjectType::Layout,
50  CoordAccess = true,
51  RawAccess = true
52  };
53 
54  EIGEN_DEVICE_FUNC
55  EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr) : m_data(dataPtr), m_dimensions() {
56  // The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
57  EIGEN_STATIC_ASSERT((0 == NumIndices || NumIndices == Dynamic), YOU_MADE_A_PROGRAMMING_MISTAKE)
58  }
59 
60 #if EIGEN_HAS_VARIADIC_TEMPLATES
61  template<typename... IndexTypes> EIGEN_DEVICE_FUNC
62  EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index firstDimension, IndexTypes... otherDimensions) : m_data(dataPtr), m_dimensions(firstDimension, otherDimensions...) {
63  // The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
64  EIGEN_STATIC_ASSERT((sizeof...(otherDimensions) + 1 == NumIndices || NumIndices == Dynamic), YOU_MADE_A_PROGRAMMING_MISTAKE)
65  }
66 #else
67  EIGEN_DEVICE_FUNC
68  EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index firstDimension) : m_data(dataPtr), m_dimensions(firstDimension) {
69  // The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
70  EIGEN_STATIC_ASSERT((1 == NumIndices || NumIndices == Dynamic), YOU_MADE_A_PROGRAMMING_MISTAKE)
71  }
72  EIGEN_DEVICE_FUNC
73  EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index dim1, Index dim2) : m_data(dataPtr), m_dimensions(dim1, dim2) {
74  EIGEN_STATIC_ASSERT(2 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
75  }
76  EIGEN_DEVICE_FUNC
77  EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index dim1, Index dim2, Index dim3) : m_data(dataPtr), m_dimensions(dim1, dim2, dim3) {
78  EIGEN_STATIC_ASSERT(3 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
79  }
80  EIGEN_DEVICE_FUNC
81  EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index dim1, Index dim2, Index dim3, Index dim4) : m_data(dataPtr), m_dimensions(dim1, dim2, dim3, dim4) {
82  EIGEN_STATIC_ASSERT(4 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
83  }
84  EIGEN_DEVICE_FUNC
85  EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index dim1, Index dim2, Index dim3, Index dim4, Index dim5) : m_data(dataPtr), m_dimensions(dim1, dim2, dim3, dim4, dim5) {
86  EIGEN_STATIC_ASSERT(5 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
87  }
88 #endif
89 
90  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, const array<Index, NumIndices>& dimensions)
91  : m_data(dataPtr), m_dimensions(dimensions)
92  { }
93 
94  template <typename Dimensions>
95  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, const Dimensions& dimensions)
96  : m_data(dataPtr), m_dimensions(dimensions)
97  { }
98 
99  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap(PlainObjectType& tensor)
100  : m_data(tensor.data()), m_dimensions(tensor.dimensions())
101  { }
102 
103  EIGEN_DEVICE_FUNC
104  EIGEN_STRONG_INLINE Index rank() const { return m_dimensions.rank(); }
105  EIGEN_DEVICE_FUNC
106  EIGEN_STRONG_INLINE Index dimension(Index n) const { return m_dimensions[n]; }
107  EIGEN_DEVICE_FUNC
108  EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }
109  EIGEN_DEVICE_FUNC
110  EIGEN_STRONG_INLINE Index size() const { return m_dimensions.TotalSize(); }
111  EIGEN_DEVICE_FUNC
112  EIGEN_STRONG_INLINE Scalar* data() { return m_data; }
113  EIGEN_DEVICE_FUNC
114  EIGEN_STRONG_INLINE const Scalar* data() const { return m_data; }
115 
116  EIGEN_DEVICE_FUNC
117  EIGEN_STRONG_INLINE const Scalar& operator()(const array<Index, NumIndices>& indices) const
118  {
119  // eigen_assert(checkIndexRange(indices));
120  if (PlainObjectType::Options&RowMajor) {
121  const Index index = m_dimensions.IndexOfRowMajor(indices);
122  return m_data[index];
123  } else {
124  const Index index = m_dimensions.IndexOfColMajor(indices);
125  return m_data[index];
126  }
127  }
128 
129  EIGEN_DEVICE_FUNC
130  EIGEN_STRONG_INLINE const Scalar& operator()() const
131  {
132  EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE)
133  return m_data[0];
134  }
135 
136  EIGEN_DEVICE_FUNC
137  EIGEN_STRONG_INLINE const Scalar& operator()(Index index) const
138  {
139  eigen_internal_assert(index >= 0 && index < size());
140  return m_data[index];
141  }
142 
143 #if EIGEN_HAS_VARIADIC_TEMPLATES
144  template<typename... IndexTypes> EIGEN_DEVICE_FUNC
145  EIGEN_STRONG_INLINE const Scalar& operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) const
146  {
147  EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
148  if (PlainObjectType::Options&RowMajor) {
149  const Index index = m_dimensions.IndexOfRowMajor(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
150  return m_data[index];
151  } else {
152  const Index index = m_dimensions.IndexOfColMajor(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
153  return m_data[index];
154  }
155  }
156 #else
157  EIGEN_DEVICE_FUNC
158  EIGEN_STRONG_INLINE const Scalar& operator()(Index i0, Index i1) const
159  {
160  if (PlainObjectType::Options&RowMajor) {
161  const Index index = i1 + i0 * m_dimensions[1];
162  return m_data[index];
163  } else {
164  const Index index = i0 + i1 * m_dimensions[0];
165  return m_data[index];
166  }
167  }
168  EIGEN_DEVICE_FUNC
169  EIGEN_STRONG_INLINE const Scalar& operator()(Index i0, Index i1, Index i2) const
170  {
171  if (PlainObjectType::Options&RowMajor) {
172  const Index index = i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0);
173  return m_data[index];
174  } else {
175  const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * i2);
176  return m_data[index];
177  }
178  }
179  EIGEN_DEVICE_FUNC
180  EIGEN_STRONG_INLINE const Scalar& operator()(Index i0, Index i1, Index i2, Index i3) const
181  {
182  if (PlainObjectType::Options&RowMajor) {
183  const Index index = i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0));
184  return m_data[index];
185  } else {
186  const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * i3));
187  return m_data[index];
188  }
189  }
190  EIGEN_DEVICE_FUNC
191  EIGEN_STRONG_INLINE const Scalar& operator()(Index i0, Index i1, Index i2, Index i3, Index i4) const
192  {
193  if (PlainObjectType::Options&RowMajor) {
194  const Index index = i4 + m_dimensions[4] * (i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0)));
195  return m_data[index];
196  } else {
197  const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * (i3 + m_dimensions[3] * i4)));
198  return m_data[index];
199  }
200  }
201 #endif
202 
203  EIGEN_DEVICE_FUNC
204  EIGEN_STRONG_INLINE Scalar& operator()(const array<Index, NumIndices>& indices)
205  {
206  // eigen_assert(checkIndexRange(indices));
207  if (PlainObjectType::Options&RowMajor) {
208  const Index index = m_dimensions.IndexOfRowMajor(indices);
209  return m_data[index];
210  } else {
211  const Index index = m_dimensions.IndexOfColMajor(indices);
212  return m_data[index];
213  }
214  }
215 
216  EIGEN_DEVICE_FUNC
217  EIGEN_STRONG_INLINE Scalar& operator()()
218  {
219  EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE)
220  return m_data[0];
221  }
222 
223  EIGEN_DEVICE_FUNC
224  EIGEN_STRONG_INLINE Scalar& operator()(Index index)
225  {
226  eigen_internal_assert(index >= 0 && index < size());
227  return m_data[index];
228  }
229 
230 #if EIGEN_HAS_VARIADIC_TEMPLATES
231  template<typename... IndexTypes> EIGEN_DEVICE_FUNC
232  EIGEN_STRONG_INLINE Scalar& operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices)
233  {
234  static_assert(sizeof...(otherIndices) + 2 == NumIndices || NumIndices == Dynamic, "Number of indices used to access a tensor coefficient must be equal to the rank of the tensor.");
235  const std::size_t NumDims = sizeof...(otherIndices) + 2;
236  if (PlainObjectType::Options&RowMajor) {
237  const Index index = m_dimensions.IndexOfRowMajor(array<Index, NumDims>{{firstIndex, secondIndex, otherIndices...}});
238  return m_data[index];
239  } else {
240  const Index index = m_dimensions.IndexOfColMajor(array<Index, NumDims>{{firstIndex, secondIndex, otherIndices...}});
241  return m_data[index];
242  }
243  }
244 #else
245  EIGEN_DEVICE_FUNC
246  EIGEN_STRONG_INLINE Scalar& operator()(Index i0, Index i1)
247  {
248  if (PlainObjectType::Options&RowMajor) {
249  const Index index = i1 + i0 * m_dimensions[1];
250  return m_data[index];
251  } else {
252  const Index index = i0 + i1 * m_dimensions[0];
253  return m_data[index];
254  }
255  }
256  EIGEN_DEVICE_FUNC
257  EIGEN_STRONG_INLINE Scalar& operator()(Index i0, Index i1, Index i2)
258  {
259  if (PlainObjectType::Options&RowMajor) {
260  const Index index = i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0);
261  return m_data[index];
262  } else {
263  const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * i2);
264  return m_data[index];
265  }
266  }
267  EIGEN_DEVICE_FUNC
268  EIGEN_STRONG_INLINE Scalar& operator()(Index i0, Index i1, Index i2, Index i3)
269  {
270  if (PlainObjectType::Options&RowMajor) {
271  const Index index = i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0));
272  return m_data[index];
273  } else {
274  const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * i3));
275  return m_data[index];
276  }
277  }
278  EIGEN_DEVICE_FUNC
279  EIGEN_STRONG_INLINE Scalar& operator()(Index i0, Index i1, Index i2, Index i3, Index i4)
280  {
281  if (PlainObjectType::Options&RowMajor) {
282  const Index index = i4 + m_dimensions[4] * (i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0)));
283  return m_data[index];
284  } else {
285  const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * (i3 + m_dimensions[3] * i4)));
286  return m_data[index];
287  }
288  }
289 #endif
290 
291  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Self& operator=(const Self& other)
292  {
293  typedef TensorAssignOp<Self, const Self> Assign;
294  Assign assign(*this, other);
295  internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
296  return *this;
297  }
298 
299  template<typename OtherDerived>
300  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
301  Self& operator=(const OtherDerived& other)
302  {
303  typedef TensorAssignOp<Self, const OtherDerived> Assign;
304  Assign assign(*this, other);
305  internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
306  return *this;
307  }
308 
309  private:
310  Scalar* m_data;
311  Dimensions m_dimensions;
312 };
313 
314 } // end namespace Eigen
315 
316 #endif // EIGEN_CXX11_TENSOR_TENSOR_MAP_H
Namespace containing all symbols from the Eigen library.
Definition: AdolcForward:45