![]() |
Eigen-unsupported
3.3.3
|
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