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