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 internal::packet_traits<Scalar>::type Packet;
32  typedef typename NumTraits<Scalar>::Real RealScalar;
33  typedef typename Base::CoeffReturnType CoeffReturnType;
34 
35  /* typedef typename internal::conditional<
36  bool(internal::is_lvalue<PlainObjectType>::value),
37  Scalar *,
38  const Scalar *>::type
39  PointerType;*/
40  typedef Scalar* PointerType;
41  typedef PointerType PointerArgType;
42 
43  static const int Options = Options_;
44 
45  static const Index NumIndices = PlainObjectType::NumIndices;
46  typedef typename PlainObjectType::Dimensions Dimensions;
47 
48  enum {
49  IsAligned = ((int(Options_)&Aligned)==Aligned),
50  PacketAccess = (internal::packet_traits<Scalar>::size > 1),
51  Layout = PlainObjectType::Layout,
52  CoordAccess = true
53  };
54 
55  EIGEN_DEVICE_FUNC
56  EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr) : m_data(dataPtr), m_dimensions() {
57  // The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
58  EIGEN_STATIC_ASSERT((0 == NumIndices || NumIndices == Dynamic), YOU_MADE_A_PROGRAMMING_MISTAKE)
59  }
60 
61 #ifdef EIGEN_HAS_VARIADIC_TEMPLATES
62  template<typename... IndexTypes> EIGEN_DEVICE_FUNC
63  EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index firstDimension, IndexTypes... otherDimensions) : m_data(dataPtr), m_dimensions(firstDimension, otherDimensions...) {
64  // The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
65  EIGEN_STATIC_ASSERT((sizeof...(otherDimensions) + 1 == NumIndices || NumIndices == Dynamic), YOU_MADE_A_PROGRAMMING_MISTAKE)
66  }
67 #else
68  EIGEN_DEVICE_FUNC
69  EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index firstDimension) : m_data(dataPtr), m_dimensions(firstDimension) {
70  // The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
71  EIGEN_STATIC_ASSERT((1 == NumIndices || NumIndices == Dynamic), YOU_MADE_A_PROGRAMMING_MISTAKE)
72  }
73  EIGEN_DEVICE_FUNC
74  EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index dim1, Index dim2) : m_data(dataPtr), m_dimensions(dim1, dim2) {
75  EIGEN_STATIC_ASSERT(2 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
76  }
77  EIGEN_DEVICE_FUNC
78  EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index dim1, Index dim2, Index dim3) : m_data(dataPtr), m_dimensions(dim1, dim2, dim3) {
79  EIGEN_STATIC_ASSERT(3 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
80  }
81  EIGEN_DEVICE_FUNC
82  EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index dim1, Index dim2, Index dim3, Index dim4) : m_data(dataPtr), m_dimensions(dim1, dim2, dim3, dim4) {
83  EIGEN_STATIC_ASSERT(4 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
84  }
85  EIGEN_DEVICE_FUNC
86  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) {
87  EIGEN_STATIC_ASSERT(5 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
88  }
89 #endif
90 
91  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, const array<Index, NumIndices>& dimensions)
92  : m_data(dataPtr), m_dimensions(dimensions)
93  { }
94 
95  template <typename Dimensions>
96  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, const Dimensions& dimensions)
97  : m_data(dataPtr), m_dimensions(dimensions)
98  { }
99 
100  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap(PlainObjectType& tensor)
101  : m_data(tensor.data()), m_dimensions(tensor.dimensions())
102  { }
103 
104  EIGEN_DEVICE_FUNC
105  EIGEN_STRONG_INLINE Index rank() const { return m_dimensions.rank(); }
106  EIGEN_DEVICE_FUNC
107  EIGEN_STRONG_INLINE Index dimension(Index n) const { return m_dimensions[n]; }
108  EIGEN_DEVICE_FUNC
109  EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }
110  EIGEN_DEVICE_FUNC
111  EIGEN_STRONG_INLINE Index size() const { return m_dimensions.TotalSize(); }
112  EIGEN_DEVICE_FUNC
113  EIGEN_STRONG_INLINE Scalar* data() { return m_data; }
114  EIGEN_DEVICE_FUNC
115  EIGEN_STRONG_INLINE const Scalar* data() const { return m_data; }
116 
117  EIGEN_DEVICE_FUNC
118  EIGEN_STRONG_INLINE const Scalar& operator()(const array<Index, NumIndices>& indices) const
119  {
120  // eigen_assert(checkIndexRange(indices));
121  if (PlainObjectType::Options&RowMajor) {
122  const Index index = m_dimensions.IndexOfRowMajor(indices);
123  return m_data[index];
124  } else {
125  const Index index = m_dimensions.IndexOfColMajor(indices);
126  return m_data[index];
127  }
128  }
129 
130  EIGEN_DEVICE_FUNC
131  EIGEN_STRONG_INLINE const Scalar& operator()() const
132  {
133  EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE)
134  return m_data[0];
135  }
136 
137 #ifdef EIGEN_HAS_VARIADIC_TEMPLATES
138  template<typename... IndexTypes> EIGEN_DEVICE_FUNC
139  EIGEN_STRONG_INLINE const Scalar& operator()(Index firstIndex, IndexTypes... otherIndices) const
140  {
141  EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
142  if (PlainObjectType::Options&RowMajor) {
143  const Index index = m_dimensions.IndexOfRowMajor(array<Index, NumIndices>{{firstIndex, otherIndices...}});
144  return m_data[index];
145  } else {
146  const Index index = m_dimensions.IndexOfColMajor(array<Index, NumIndices>{{firstIndex, otherIndices...}});
147  return m_data[index];
148  }
149  }
150 #else
151  EIGEN_DEVICE_FUNC
152  EIGEN_STRONG_INLINE const Scalar& operator()(Index index) const
153  {
154  eigen_internal_assert(index >= 0 && index < size());
155  return m_data[index];
156  }
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 #ifdef EIGEN_HAS_VARIADIC_TEMPLATES
224  template<typename... IndexTypes> EIGEN_DEVICE_FUNC
225  EIGEN_STRONG_INLINE Scalar& operator()(Index firstIndex, IndexTypes... otherIndices)
226  {
227  static_assert(sizeof...(otherIndices) + 1 == NumIndices || NumIndices == Dynamic, "Number of indices used to access a tensor coefficient must be equal to the rank of the tensor.");
228  const std::size_t NumDims = sizeof...(otherIndices) + 1;
229  if (PlainObjectType::Options&RowMajor) {
230  const Index index = m_dimensions.IndexOfRowMajor(array<Index, NumDims>{{firstIndex, otherIndices...}});
231  return m_data[index];
232  } else {
233  const Index index = m_dimensions.IndexOfColMajor(array<Index, NumDims>{{firstIndex, otherIndices...}});
234  return m_data[index];
235  }
236  }
237 #else
238  EIGEN_DEVICE_FUNC
239  EIGEN_STRONG_INLINE Scalar& operator()(Index index)
240  {
241  eigen_internal_assert(index >= 0 && index < size());
242  return m_data[index];
243  }
244  EIGEN_DEVICE_FUNC
245  EIGEN_STRONG_INLINE Scalar& operator()(Index i0, Index i1)
246  {
247  if (PlainObjectType::Options&RowMajor) {
248  const Index index = i1 + i0 * m_dimensions[1];
249  return m_data[index];
250  } else {
251  const Index index = i0 + i1 * m_dimensions[0];
252  return m_data[index];
253  }
254  }
255  EIGEN_DEVICE_FUNC
256  EIGEN_STRONG_INLINE Scalar& operator()(Index i0, Index i1, Index i2)
257  {
258  if (PlainObjectType::Options&RowMajor) {
259  const Index index = i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0);
260  return m_data[index];
261  } else {
262  const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * i2);
263  return m_data[index];
264  }
265  }
266  EIGEN_DEVICE_FUNC
267  EIGEN_STRONG_INLINE Scalar& operator()(Index i0, Index i1, Index i2, Index i3)
268  {
269  if (PlainObjectType::Options&RowMajor) {
270  const Index index = i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0));
271  return m_data[index];
272  } else {
273  const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * i3));
274  return m_data[index];
275  }
276  }
277  EIGEN_DEVICE_FUNC
278  EIGEN_STRONG_INLINE Scalar& operator()(Index i0, Index i1, Index i2, Index i3, Index i4)
279  {
280  if (PlainObjectType::Options&RowMajor) {
281  const Index index = i4 + m_dimensions[4] * (i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0)));
282  return m_data[index];
283  } else {
284  const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * (i3 + m_dimensions[3] * i4)));
285  return m_data[index];
286  }
287  }
288 #endif
289 
290  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Self& operator=(const Self& other)
291  {
292  typedef TensorAssignOp<Self, const Self> Assign;
293  Assign assign(*this, other);
294  internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
295  return *this;
296  }
297 
298  template<typename OtherDerived>
299  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
300  Self& operator=(const OtherDerived& other)
301  {
302  typedef TensorAssignOp<Self, const OtherDerived> Assign;
303  Assign assign(*this, other);
304  internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
305  return *this;
306  }
307 
308  private:
309  Scalar* m_data;
310  Dimensions m_dimensions;
311 };
312 
313 } // end namespace Eigen
314 
315 #endif // EIGEN_CXX11_TENSOR_TENSOR_MAP_H
Namespace containing all symbols from the Eigen library.
Definition: CXX11Meta.h:13