68class Tensor :
public TensorBase<Tensor<Scalar_, NumIndices_, Options_, IndexType_> > {
70 typedef Tensor<Scalar_, NumIndices_, Options_, IndexType_> Self;
72 typedef typename Eigen::internal::nested<Self>::type Nested;
73 typedef typename internal::traits<Self>::StorageKind StorageKind;
74 typedef typename internal::traits<Self>::Index Index;
75 typedef Scalar_ Scalar;
77 typedef typename Base::CoeffReturnType CoeffReturnType;
79 enum { IsAligned = (EIGEN_MAX_ALIGN_BYTES > 0) && !(Options_ &
DontAlign), CoordAccess =
true, RawAccess =
true };
82 static constexpr int Options = Options_;
83 static constexpr int NumIndices = NumIndices_;
84 typedef DSizes<Index, NumIndices_> Dimensions;
87 TensorStorage<Scalar, Dimensions, Options> m_storage;
89 template <
typename CustomIndices>
90 struct isOfNormalIndex {
91 static const bool is_array = internal::is_base_of<array<Index, NumIndices>, CustomIndices>::value;
93 static const bool value = is_array | is_int;
98 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rank()
const {
return NumIndices; }
99 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index dimension(std::size_t n)
const {
return m_storage.dimensions()[n]; }
100 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Dimensions& dimensions()
const {
return m_storage.dimensions(); }
101 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index size()
const {
return m_storage.size(); }
102 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar* data() {
return m_storage.data(); }
103 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar* data()
const {
return m_storage.data(); }
108 inline Self& base() {
return *
this; }
109 inline const Self& base()
const {
return *
this; }
111 template <
typename... IndexTypes>
112 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar& coeff(Index firstIndex, Index secondIndex,
113 IndexTypes... otherIndices)
const {
115 EIGEN_STATIC_ASSERT(
sizeof...(otherIndices) + 2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
116 return coeff(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
120 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar& coeff(
const array<Index, NumIndices>& indices)
const {
121 eigen_internal_assert(checkIndexRange(indices));
122 return m_storage.data()[linearizedIndex(indices)];
126 template <
typename CustomIndices, EIGEN_SFINAE_ENABLE_IF(!(isOfNormalIndex<CustomIndices>::value))>
127 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar& coeff(CustomIndices& indices)
const {
128 return coeff(internal::customIndices2Array<Index, NumIndices>(indices));
131 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar& coeff()
const {
132 EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
133 return m_storage.data()[0];
136 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar& coeff(Index index)
const {
137 eigen_internal_assert(index >= 0 && index < size());
138 return m_storage.data()[index];
141 template <
typename... IndexTypes>
142 inline Scalar& coeffRef(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) {
144 EIGEN_STATIC_ASSERT(
sizeof...(otherIndices) + 2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
145 return coeffRef(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
149 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(
const array<Index, NumIndices>& indices) {
150 eigen_internal_assert(checkIndexRange(indices));
151 return m_storage.data()[linearizedIndex(indices)];
155 template <
typename CustomIndices, EIGEN_SFINAE_ENABLE_IF(!(isOfNormalIndex<CustomIndices>::value))>
156 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(CustomIndices& indices) {
157 return coeffRef(internal::customIndices2Array<Index, NumIndices>(indices));
160 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef() {
161 EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
162 return m_storage.data()[0];
165 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& coeffRef(Index index) {
166 eigen_internal_assert(index >= 0 && index < size());
167 return m_storage.data()[index];
170 template <
typename... IndexTypes>
171 inline const Scalar& operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices)
const {
173 EIGEN_STATIC_ASSERT(
sizeof...(otherIndices) + 2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
174 return this->operator()(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
178 template <
typename CustomIndices, EIGEN_SFINAE_ENABLE_IF(!(isOfNormalIndex<CustomIndices>::value))>
179 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar& operator()(CustomIndices& indices)
const {
180 return coeff(internal::customIndices2Array<Index, NumIndices>(indices));
184 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar& operator()(
const array<Index, NumIndices>& indices)
const {
185 return coeff(indices);
188 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar& operator()(Index index)
const {
189 eigen_internal_assert(index >= 0 && index < size());
193 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar& operator()()
const {
194 EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
198 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar& operator[](Index index)
const {
200 EIGEN_STATIC_ASSERT(NumIndices == 1, YOU_MADE_A_PROGRAMMING_MISTAKE);
204 template <
typename... IndexTypes>
205 inline Scalar& operator()(Index firstIndex, Index secondIndex, IndexTypes... otherIndices) {
207 EIGEN_STATIC_ASSERT(
sizeof...(otherIndices) + 2 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
208 return operator()(array<Index, NumIndices>{{firstIndex, secondIndex, otherIndices...}});
212 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(
const array<Index, NumIndices>& indices) {
213 return coeffRef(indices);
217 template <
typename CustomIndices, EIGEN_SFINAE_ENABLE_IF(!(isOfNormalIndex<CustomIndices>::value))>
218 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(CustomIndices& indices) {
219 return coeffRef(internal::customIndices2Array<Index, NumIndices>(indices));
222 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()(Index index) {
223 eigen_assert(index >= 0 && index < size());
224 return coeffRef(index);
227 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator()() {
228 EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
232 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar& operator[](Index index) {
234 EIGEN_STATIC_ASSERT(NumIndices == 1, YOU_MADE_A_PROGRAMMING_MISTAKE)
235 return coeffRef(index);
238 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor() : m_storage() {}
240 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor(
const Self& other) : Base(other), m_storage(other.m_storage) {}
242 template <
typename... IndexTypes>
243 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor(Index firstDimension, IndexTypes... otherDimensions)
244 : m_storage(firstDimension, otherDimensions...) {
246 EIGEN_STATIC_ASSERT(
sizeof...(otherDimensions) + 1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
250 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
explicit Tensor(
const array<Index, NumIndices>& dimensions)
251 : m_storage(
internal::array_prod(dimensions), dimensions) {
252 EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
255 template <
typename OtherDerived>
257 EIGEN_STATIC_ASSERT(OtherDerived::NumDimensions == Base::NumDimensions, Number_of_dimensions_must_match)
259 Assign assign(*
this, other.derived());
261 internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
264 template <
typename OtherDerived>
265 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor(
const TensorBase<OtherDerived, WriteAccessors>& other) {
266 EIGEN_STATIC_ASSERT(OtherDerived::NumDimensions == Base::NumDimensions, Number_of_dimensions_must_match)
267 typedef TensorAssignOp<Tensor, const OtherDerived> Assign;
268 Assign assign(*
this, other.derived());
269 resize(TensorEvaluator<const Assign, DefaultDevice>(assign, DefaultDevice()).dimensions());
270 internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
273 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor(Self&& other) : m_storage(std::move(other.m_storage)) {}
274 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor& operator=(Self&& other) {
275 m_storage = std::move(other.m_storage);
279 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor& operator=(
const Tensor& other) {
280 typedef TensorAssignOp<Tensor, const Tensor> Assign;
281 Assign assign(*
this, other);
282 resize(TensorEvaluator<const Assign, DefaultDevice>(assign, DefaultDevice()).dimensions());
283 internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
286 template <
typename OtherDerived>
287 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Tensor& operator=(
const OtherDerived& other) {
288 typedef TensorAssignOp<Tensor, const OtherDerived> Assign;
289 Assign assign(*
this, other);
290 resize(TensorEvaluator<const Assign, DefaultDevice>(assign, DefaultDevice()).dimensions());
291 internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
295 template <
typename... IndexTypes>
296 EIGEN_DEVICE_FUNC
void resize(Index firstDimension, IndexTypes... otherDimensions) {
298 EIGEN_STATIC_ASSERT(
sizeof...(otherDimensions) + 1 == NumIndices, YOU_MADE_A_PROGRAMMING_MISTAKE)
299 resize(array<Index, NumIndices>{{firstDimension, otherDimensions...}});
303 EIGEN_DEVICE_FUNC
void resize(
const array<Index, NumIndices>& dimensions) {
304#ifndef EIGEN_NO_DEBUG
305 Index size = Index(1);
306 for (
int i = 0; i < NumIndices; i++) {
307 internal::check_rows_cols_for_overflow<Dynamic, Dynamic, Dynamic>::run(size, dimensions[i]);
308 size *= dimensions[i];
311 Index size = internal::array_prod(dimensions);
314#ifdef EIGEN_INITIALIZE_COEFFS
315 bool size_changed = size != this->size();
316 m_storage.resize(size, dimensions);
317 if (size_changed) EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
319 m_storage.resize(size, dimensions);
323 EIGEN_DEVICE_FUNC
void resize() {
324 EIGEN_STATIC_ASSERT(NumIndices == 0, YOU_MADE_A_PROGRAMMING_MISTAKE);
328 template <
typename FirstType,
typename... OtherTypes>
329 EIGEN_DEVICE_FUNC
void resize(
const Eigen::IndexList<FirstType, OtherTypes...>& dimensions) {
330 array<Index, NumIndices> dims;
331 for (
int i = 0; i < NumIndices; ++i) {
332 dims[i] =
static_cast<Index
>(dimensions[i]);
338 template <
typename CustomDimension, EIGEN_SFINAE_ENABLE_IF(!(isOfNormalIndex<CustomDimension>::value))>
339 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void resize(CustomDimension& dimensions) {
340 resize(internal::customIndices2Array<Index, NumIndices>(dimensions));
343 template <
typename std::ptrdiff_t... Indices>
344 EIGEN_DEVICE_FUNC
void resize(
const Sizes<Indices...>& dimensions) {
345 array<Index, NumIndices> dims;
346 for (
int i = 0; i < NumIndices; ++i) {
347 dims[i] =
static_cast<Index>(dimensions[i]);
352#ifdef EIGEN_TENSOR_PLUGIN
353#include EIGEN_TENSOR_PLUGIN
357 bool checkIndexRange(
const array<Index, NumIndices>& indices)
const {
358 using internal::array_apply_and_reduce;
359 using internal::array_zip_and_reduce;
360 using internal::greater_equal_zero_op;
361 using internal::lesser_op;
362 using internal::logical_and_op;
366 array_apply_and_reduce<logical_and_op, greater_equal_zero_op>(indices) &&
368 array_zip_and_reduce<logical_and_op, lesser_op>(indices, m_storage.dimensions());
371 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index linearizedIndex(
const array<Index, NumIndices>& indices)
const {
373 return m_storage.dimensions().IndexOfRowMajor(indices);
375 return m_storage.dimensions().IndexOfColMajor(indices);