TensorMap.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
00005 //
00006 // This Source Code Form is subject to the terms of the Mozilla
00007 // Public License v. 2.0. If a copy of the MPL was not distributed
00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00009 
00010 #ifndef EIGEN_CXX11_TENSOR_TENSOR_MAP_H
00011 #define EIGEN_CXX11_TENSOR_TENSOR_MAP_H
00012 
00013 namespace Eigen {
00014 
00021 
00022 
00023 
00024 
00025 
00026 
00027 template<typename PlainObjectType, int Options_, template <class> class MakePointer_> class TensorMap : public TensorBase<TensorMap<PlainObjectType, Options_, MakePointer_> >
00028 {
00029   public:
00030     typedef TensorMap<PlainObjectType, Options_, MakePointer_> Self;
00031     typedef typename PlainObjectType::Base Base;
00032     typedef typename Eigen::internal::nested<Self>::type Nested;
00033     typedef typename internal::traits<PlainObjectType>::StorageKind StorageKind;
00034     typedef typename internal::traits<PlainObjectType>::Index Index;
00035     typedef typename internal::traits<PlainObjectType>::Scalar Scalar;
00036     typedef typename NumTraits<Scalar>::Real RealScalar;
00037     typedef typename Base::CoeffReturnType CoeffReturnType;
00038 
00039   /*    typedef typename internal::conditional<
00040                          bool(internal::is_lvalue<PlainObjectType>::value),
00041                          Scalar *,
00042                          const Scalar *>::type
00043                      PointerType;*/
00044     typedef typename MakePointer_<Scalar>::Type PointerType;
00045     typedef PointerType PointerArgType;
00046 
00047     static const int Options = Options_;
00048 
00049     static const Index NumIndices = PlainObjectType::NumIndices;
00050     typedef typename PlainObjectType::Dimensions Dimensions;
00051 
00052     enum {
00053       IsAligned = ((int(Options_)&Aligned)==Aligned),
00054       Layout = PlainObjectType::Layout,
00055       CoordAccess = true,
00056       RawAccess = true
00057     };
00058 
00059     EIGEN_DEVICE_FUNC
00060     EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr) : m_data(dataPtr), m_dimensions() {
00061       // The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
00062       EIGEN_STATIC_ASSERT((0 == NumIndices || NumIndices == Dynamic), YOU_MADE_A_PROGRAMMING_MISTAKE)
00063     }
00064 
00065 #if EIGEN_HAS_VARIADIC_TEMPLATES
00066     template<typename... IndexTypes> EIGEN_DEVICE_FUNC
00067     EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index firstDimension, IndexTypes... otherDimensions) : m_data(dataPtr), m_dimensions(firstDimension, otherDimensions...) {
00068       // The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
00069       EIGEN_STATIC_ASSERT((sizeof...(otherDimensions) + 1 == NumIndices || NumIndices == Dynamic), YOU_MADE_A_PROGRAMMING_MISTAKE)
00070     }
00071 #else
00072     EIGEN_DEVICE_FUNC
00073     EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index firstDimension) : m_data(dataPtr), m_dimensions(firstDimension) {
00074       // The number of dimensions used to construct a tensor must be equal to the rank of the tensor.
00075       EIGEN_STATIC_ASSERT((1 == NumIndices || NumIndices == Dynamic), YOU_MADE_A_PROGRAMMING_MISTAKE)
00076     }
00077     EIGEN_DEVICE_FUNC
00078     EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index dim1, Index dim2) : m_data(dataPtr), m_dimensions(dim1, dim2) {
00079       EIGEN_STATIC_ASSERT(2 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
00080     }
00081     EIGEN_DEVICE_FUNC
00082     EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index dim1, Index dim2, Index dim3) : m_data(dataPtr), m_dimensions(dim1, dim2, dim3) {
00083       EIGEN_STATIC_ASSERT(3 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
00084     }
00085     EIGEN_DEVICE_FUNC
00086     EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, Index dim1, Index dim2, Index dim3, Index dim4) : m_data(dataPtr), m_dimensions(dim1, dim2, dim3, dim4) {
00087       EIGEN_STATIC_ASSERT(4 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
00088     }
00089     EIGEN_DEVICE_FUNC
00090     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) {
00091       EIGEN_STATIC_ASSERT(5 == NumIndices || NumIndices == Dynamic, YOU_MADE_A_PROGRAMMING_MISTAKE)
00092     }
00093 #endif
00094 
00095    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, const array<Index, NumIndices>& dimensions)
00096       : m_data(dataPtr), m_dimensions(dimensions)
00097     { }
00098 
00099     template <typename Dimensions>
00100     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap(PointerArgType dataPtr, const Dimensions& dimensions)
00101       : m_data(dataPtr), m_dimensions(dimensions)
00102     { }
00103 
00104     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorMap(PlainObjectType& tensor)
00105       : m_data(tensor.data()), m_dimensions(tensor.dimensions())
00106     { }
00107 
00108     EIGEN_DEVICE_FUNC
00109     EIGEN_STRONG_INLINE Index rank() const { return m_dimensions.rank(); }
00110     EIGEN_DEVICE_FUNC
00111     EIGEN_STRONG_INLINE Index dimension(Index n) const { return m_dimensions[n]; }
00112     EIGEN_DEVICE_FUNC
00113     EIGEN_STRONG_INLINE const Dimensions& dimensions() const { return m_dimensions; }
00114     EIGEN_DEVICE_FUNC
00115     EIGEN_STRONG_INLINE Index size() const { return m_dimensions.TotalSize(); }
00116     EIGEN_DEVICE_FUNC
00117     EIGEN_STRONG_INLINE PointerType data() { return m_data; }
00118     EIGEN_DEVICE_FUNC
00119     EIGEN_STRONG_INLINE const PointerType data() const { return m_data; }
00120 
00121     EIGEN_DEVICE_FUNC
00122     EIGEN_STRONG_INLINE const Scalar& operator()(const array<Index, NumIndices>& indices) const
00123     {
00124       //      eigen_assert(checkIndexRange(indices));
00125       if (PlainObjectType::Options&RowMajor) {
00126         const Index index = m_dimensions.IndexOfRowMajor(indices);
00127         return m_data[index];
00128       } else {
00129         const Index index = m_dimensions.IndexOfColMajor(indices);
00130         return m_data[index];
00131       }
00132     }
00133 
00134     EIGEN_DEVICE_FUNC
00135     EIGEN_STRONG_INLINE const Scalar& operator()() const
00136     {
00137       EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE)
00138       return m_data[0];
00139     }
00140 
00141     EIGEN_DEVICE_FUNC
00142     EIGEN_STRONG_INLINE const Scalar& operator()(Index index) const
00143     {
00144       eigen_internal_assert(index >= 0 && index < size());
00145       return m_data[index];
00146     }
00147 
00148 #if EIGEN_HAS_VARIADIC_TEMPLATES
00149     template<typename... IndexTypes> EIGEN_DEVICE_FUNC
00150     EIGEN_STRONG_INLINE const Scalar& operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) const
00151     {
00152       EIGEN_STATIC_ASSERT(sizeof...(otherIndices) + 2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
00153       if (PlainObjectType::Options&RowMajor) {
00154         const Index index = m_dimensions.IndexOfRowMajor(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
00155         return m_data[index];
00156       } else {
00157         const Index index = m_dimensions.IndexOfColMajor(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
00158         return m_data[index];
00159       }
00160     }
00161 #else
00162     EIGEN_DEVICE_FUNC
00163     EIGEN_STRONG_INLINE const Scalar& operator()(Index i0, Index i1) const
00164     {
00165       if (PlainObjectType::Options&RowMajor) {
00166         const Index index = i1 + i0 * m_dimensions[1];
00167         return m_data[index];
00168       } else {
00169         const Index index = i0 + i1 * m_dimensions[0];
00170         return m_data[index];
00171       }
00172     }
00173     EIGEN_DEVICE_FUNC
00174     EIGEN_STRONG_INLINE const Scalar& operator()(Index i0, Index i1, Index i2) const
00175     {
00176       if (PlainObjectType::Options&RowMajor) {
00177          const Index index = i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0);
00178          return m_data[index];
00179       } else {
00180          const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * i2);
00181         return m_data[index];
00182       }
00183     }
00184     EIGEN_DEVICE_FUNC
00185     EIGEN_STRONG_INLINE const Scalar& operator()(Index i0, Index i1, Index i2, Index i3) const
00186     {
00187       if (PlainObjectType::Options&RowMajor) {
00188         const Index index = i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0));
00189         return m_data[index];
00190       } else {
00191         const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * i3));
00192         return m_data[index];
00193       }
00194     }
00195     EIGEN_DEVICE_FUNC
00196     EIGEN_STRONG_INLINE const Scalar& operator()(Index i0, Index i1, Index i2, Index i3, Index i4) const
00197     {
00198       if (PlainObjectType::Options&RowMajor) {
00199         const Index index = i4 + m_dimensions[4] * (i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0)));
00200         return m_data[index];
00201       } else {
00202         const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * (i3 + m_dimensions[3] * i4)));
00203         return m_data[index];
00204       }
00205     }
00206 #endif
00207 
00208     EIGEN_DEVICE_FUNC
00209     EIGEN_STRONG_INLINE Scalar& operator()(const array<Index, NumIndices>& indices)
00210     {
00211       //      eigen_assert(checkIndexRange(indices));
00212       if (PlainObjectType::Options&RowMajor) {
00213         const Index index = m_dimensions.IndexOfRowMajor(indices);
00214         return m_data[index];
00215       } else {
00216         const Index index = m_dimensions.IndexOfColMajor(indices);
00217         return m_data[index];
00218       }
00219     }
00220 
00221     EIGEN_DEVICE_FUNC
00222     EIGEN_STRONG_INLINE Scalar& operator()()
00223     {
00224       EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE)
00225       return m_data[0];
00226     }
00227 
00228     EIGEN_DEVICE_FUNC
00229     EIGEN_STRONG_INLINE Scalar& operator()(Index index)
00230     {
00231       eigen_internal_assert(index >= 0 && index < size());
00232       return m_data[index];
00233     }
00234 
00235 #if EIGEN_HAS_VARIADIC_TEMPLATES
00236     template<typename... IndexTypes> EIGEN_DEVICE_FUNC
00237     EIGEN_STRONG_INLINE Scalar& operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices)
00238     {
00239       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.");
00240       const std::size_t NumDims = sizeof...(otherIndices) + 2;
00241       if (PlainObjectType::Options&RowMajor) {
00242         const Index index = m_dimensions.IndexOfRowMajor(array<Index, NumDims>{{firstIndex, secondIndex, otherIndices...}});
00243         return m_data[index];
00244       } else {
00245         const Index index = m_dimensions.IndexOfColMajor(array<Index, NumDims>{{firstIndex, secondIndex, otherIndices...}});
00246         return m_data[index];
00247       }
00248     }
00249 #else
00250     EIGEN_DEVICE_FUNC
00251     EIGEN_STRONG_INLINE Scalar& operator()(Index i0, Index i1)
00252     {
00253        if (PlainObjectType::Options&RowMajor) {
00254          const Index index = i1 + i0 * m_dimensions[1];
00255         return m_data[index];
00256       } else {
00257         const Index index = i0 + i1 * m_dimensions[0];
00258         return m_data[index];
00259       }
00260     }
00261     EIGEN_DEVICE_FUNC
00262     EIGEN_STRONG_INLINE Scalar& operator()(Index i0, Index i1, Index i2)
00263     {
00264        if (PlainObjectType::Options&RowMajor) {
00265          const Index index = i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0);
00266         return m_data[index];
00267       } else {
00268          const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * i2);
00269         return m_data[index];
00270       }
00271     }
00272     EIGEN_DEVICE_FUNC
00273     EIGEN_STRONG_INLINE Scalar& operator()(Index i0, Index i1, Index i2, Index i3)
00274     {
00275       if (PlainObjectType::Options&RowMajor) {
00276         const Index index = i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0));
00277         return m_data[index];
00278       } else {
00279         const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * i3));
00280         return m_data[index];
00281       }
00282     }
00283     EIGEN_DEVICE_FUNC
00284     EIGEN_STRONG_INLINE Scalar& operator()(Index i0, Index i1, Index i2, Index i3, Index i4)
00285     {
00286       if (PlainObjectType::Options&RowMajor) {
00287         const Index index = i4 + m_dimensions[4] * (i3 + m_dimensions[3] * (i2 + m_dimensions[2] * (i1 + m_dimensions[1] * i0)));
00288         return m_data[index];
00289       } else {
00290         const Index index = i0 + m_dimensions[0] * (i1 + m_dimensions[1] * (i2 + m_dimensions[2] * (i3 + m_dimensions[3] * i4)));
00291         return m_data[index];
00292       }
00293     }
00294 #endif
00295 
00296     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Self& operator=(const Self& other)
00297     {
00298       typedef TensorAssignOp<Self, const Self> Assign;
00299       Assign assign(*this, other);
00300       internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
00301       return *this;
00302     }
00303 
00304     template<typename OtherDerived>
00305     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00306     Self& operator=(const OtherDerived& other)
00307     {
00308       typedef TensorAssignOp<Self, const OtherDerived> Assign;
00309       Assign assign(*this, other);
00310       internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
00311       return *this;
00312     }
00313 
00314   private:
00315     typename MakePointer_<Scalar>::Type m_data;
00316     Dimensions m_dimensions;
00317 };
00318 
00319 } // end namespace Eigen
00320 
00321 #endif // EIGEN_CXX11_TENSOR_TENSOR_MAP_H
 All Classes Functions Variables Typedefs Enumerator