TensorBase.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_BASE_H
11 #define EIGEN_CXX11_TENSOR_TENSOR_BASE_H
12 
13 // clang-format off
14 
15 namespace Eigen {
16 
26 template<typename Derived>
27 class TensorBase<Derived, ReadOnlyAccessors>
28 {
29  public:
30  typedef internal::traits<Derived> DerivedTraits;
31  typedef typename DerivedTraits::Scalar Scalar;
32  typedef typename DerivedTraits::Index Index;
33  typedef typename internal::remove_const<Scalar>::type CoeffReturnType;
34  typedef typename internal::packet_traits<CoeffReturnType>::type PacketReturnType;
35  static const int NumDimensions = DerivedTraits::NumDimensions;
36 
37  // Generic nullary operation support.
38  template <typename CustomNullaryOp> EIGEN_DEVICE_FUNC
39  EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<CustomNullaryOp, const Derived>
40  nullaryExpr(const CustomNullaryOp& func) const {
41  return TensorCwiseNullaryOp<CustomNullaryOp, const Derived>(derived(), func);
42  }
43 
44  // Coefficient-wise nullary operators
45  EIGEN_DEVICE_FUNC
46  EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived>
47  constant(const Scalar& value) const {
48  return nullaryExpr(internal::scalar_constant_op<Scalar>(value));
49  }
50 
51  EIGEN_DEVICE_FUNC
52  EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<internal::UniformRandomGenerator<Scalar>, const Derived>
53  random() const {
54  return nullaryExpr(internal::UniformRandomGenerator<Scalar>());
55  }
56  template <typename RandomGenerator> EIGEN_DEVICE_FUNC
57  EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<RandomGenerator, const Derived>
58  random(const RandomGenerator& gen = RandomGenerator()) const {
59  return nullaryExpr(gen);
60  }
61 
62  // Tensor generation
63  template <typename Generator> EIGEN_DEVICE_FUNC
64  EIGEN_STRONG_INLINE const TensorGeneratorOp<Generator, const Derived>
65  generate(const Generator& generator) const {
66  return TensorGeneratorOp<Generator, const Derived>(derived(), generator);
67  }
68 
69  // Generic unary operation support.
70  template <typename CustomUnaryOp> EIGEN_DEVICE_FUNC
71  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<CustomUnaryOp, const Derived>
72  unaryExpr(const CustomUnaryOp& func) const {
73  return TensorCwiseUnaryOp<CustomUnaryOp, const Derived>(derived(), func);
74  }
75 
76  // Coefficient-wise unary operators
77  EIGEN_DEVICE_FUNC
78  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const Derived>
79  operator-() const {
80  return unaryExpr(internal::scalar_opposite_op<Scalar>());
81  }
82 
83  EIGEN_DEVICE_FUNC
84  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sqrt_op<Scalar>, const Derived>
85  sqrt() const {
86  return unaryExpr(internal::scalar_sqrt_op<Scalar>());
87  }
88 
89  EIGEN_DEVICE_FUNC
90  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sign_op<Scalar>, const Derived>
91  sign() const {
92  return unaryExpr(internal::scalar_sign_op<Scalar>());
93  }
94 
95  EIGEN_DEVICE_FUNC
96  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_rsqrt_op<Scalar>, const Derived>
97  rsqrt() const {
98  return unaryExpr(internal::scalar_rsqrt_op<Scalar>());
99  }
100 
101  EIGEN_DEVICE_FUNC
102  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_square_op<Scalar>, const Derived>
103  square() const {
104  return unaryExpr(internal::scalar_square_op<Scalar>());
105  }
106 
107  EIGEN_DEVICE_FUNC
108  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_cube_op<Scalar>, const Derived>
109  cube() const {
110  return unaryExpr(internal::scalar_cube_op<Scalar>());
111  }
112 
113  EIGEN_DEVICE_FUNC
114  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const Derived>
115  inverse() const {
116  return unaryExpr(internal::scalar_inverse_op<Scalar>());
117  }
118 
119  EIGEN_DEVICE_FUNC
120  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_tanh_op<Scalar>, const Derived>
121  tanh() const {
122  return unaryExpr(internal::scalar_tanh_op<Scalar>());
123  }
124 
125  EIGEN_DEVICE_FUNC
126  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_lgamma_op<Scalar>, const Derived>
127  lgamma() const {
128  return unaryExpr(internal::scalar_lgamma_op<Scalar>());
129  }
130 
131  EIGEN_DEVICE_FUNC
132  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_erf_op<Scalar>, const Derived>
133  erf() const {
134  return unaryExpr(internal::scalar_erf_op<Scalar>());
135  }
136 
137  EIGEN_DEVICE_FUNC
138  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_erfc_op<Scalar>, const Derived>
139  erfc() const {
140  return unaryExpr(internal::scalar_erfc_op<Scalar>());
141  }
142 
143  EIGEN_DEVICE_FUNC
144  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sigmoid_op<Scalar>, const Derived>
145  sigmoid() const {
146  return unaryExpr(internal::scalar_sigmoid_op<Scalar>());
147  }
148 
149  EIGEN_DEVICE_FUNC
150  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_exp_op<Scalar>, const Derived>
151  exp() const {
152  return unaryExpr(internal::scalar_exp_op<Scalar>());
153  }
154 
155  EIGEN_DEVICE_FUNC
156  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log_op<Scalar>, const Derived>
157  log() const {
158  return unaryExpr(internal::scalar_log_op<Scalar>());
159  }
160 
161  EIGEN_DEVICE_FUNC
162  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_abs_op<Scalar>, const Derived>
163  abs() const {
164  return unaryExpr(internal::scalar_abs_op<Scalar>());
165  }
166 
167  EIGEN_DEVICE_FUNC
168  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_pow_op<Scalar>, const Derived>
169  pow(Scalar exponent) const {
170  return unaryExpr(internal::scalar_pow_op<Scalar>(exponent));
171  }
172 
173  EIGEN_DEVICE_FUNC
174  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_add_op<Scalar>, const Derived>
175  operator+ (Scalar rhs) const {
176  return unaryExpr(internal::scalar_add_op<Scalar>(rhs));
177  }
178 
179  EIGEN_DEVICE_FUNC
180  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sub_op<Scalar>, const Derived>
181  operator- (Scalar rhs) const {
182  EIGEN_STATIC_ASSERT((NumTraits<Scalar>::IsSigned || internal::is_same<Scalar, const std::complex<float> >::value), YOU_MADE_A_PROGRAMMING_MISTAKE);
183  return unaryExpr(internal::scalar_sub_op<Scalar>(rhs));
184  }
185 
186  EIGEN_DEVICE_FUNC
187  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const Derived>
188  operator* (Scalar rhs) const {
189  return unaryExpr(internal::scalar_multiple_op<Scalar>(rhs));
190  }
191 
192  EIGEN_DEVICE_FUNC
193  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_quotient1_op<Scalar>, const Derived>
194  operator/ (Scalar rhs) const {
195  return unaryExpr(internal::scalar_quotient1_op<Scalar>(rhs));
196  }
197 
198  EIGEN_DEVICE_FUNC
199  EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_mod_op<Scalar>, const Derived>
200  operator% (Scalar rhs) const {
201  EIGEN_STATIC_ASSERT(NumTraits<Scalar>::IsInteger, YOU_MADE_A_PROGRAMMING_MISTAKE_TRY_MOD);
202  return unaryExpr(internal::scalar_mod_op<Scalar>(rhs));
203  }
204 
205  EIGEN_DEVICE_FUNC
206  EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
207  cwiseMax(Scalar threshold) const {
208  return cwiseMax(constant(threshold));
209  }
210 
211  EIGEN_DEVICE_FUNC
212  EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
213  cwiseMin(Scalar threshold) const {
214  return cwiseMin(constant(threshold));
215  }
216 
217  template <typename NewType> EIGEN_DEVICE_FUNC
218  EIGEN_STRONG_INLINE const TensorConversionOp<NewType, const Derived>
219  cast() const {
220  return TensorConversionOp<NewType, const Derived>(derived());
221  }
222 
223  // Generic binary operation support.
224  template <typename CustomBinaryOp, typename OtherDerived> EIGEN_DEVICE_FUNC
225  EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>
226  binaryExpr(const OtherDerived& other, const CustomBinaryOp& func) const {
227  return TensorCwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>(derived(), other, func);
228  }
229 
230  // Coefficient-wise binary operators.
231  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
232  const TensorCwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const OtherDerived>
233  operator+(const OtherDerived& other) const {
234  return binaryExpr(other.derived(), internal::scalar_sum_op<Scalar>());
235  }
236 
237  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
238  const TensorCwiseBinaryOp<internal::scalar_difference_op<Scalar>, const Derived, const OtherDerived>
239  operator-(const OtherDerived& other) const {
240  return binaryExpr(other.derived(), internal::scalar_difference_op<Scalar>());
241  }
242 
243  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
244  const TensorCwiseBinaryOp<internal::scalar_product_op<Scalar>, const Derived, const OtherDerived>
245  operator*(const OtherDerived& other) const {
246  return binaryExpr(other.derived(), internal::scalar_product_op<Scalar>());
247  }
248 
249  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
250  const TensorCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, const Derived, const OtherDerived>
251  operator/(const OtherDerived& other) const {
252  return binaryExpr(other.derived(), internal::scalar_quotient_op<Scalar>());
253  }
254 
255  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
256  const TensorCwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const OtherDerived>
257  cwiseMax(const OtherDerived& other) const {
258  return binaryExpr(other.derived(), internal::scalar_max_op<Scalar>());
259  }
260 
261  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
262  const TensorCwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const OtherDerived>
263  cwiseMin(const OtherDerived& other) const {
264  return binaryExpr(other.derived(), internal::scalar_min_op<Scalar>());
265  }
266 
267  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
268  const TensorCwiseBinaryOp<internal::scalar_boolean_and_op, const Derived, const OtherDerived>
269  operator&&(const OtherDerived& other) const {
270  return binaryExpr(other.derived(), internal::scalar_boolean_and_op());
271  }
272 
273  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
274  const TensorCwiseBinaryOp<internal::scalar_boolean_or_op, const Derived, const OtherDerived>
275  operator||(const OtherDerived& other) const {
276  return binaryExpr(other.derived(), internal::scalar_boolean_or_op());
277  }
278 
279  // Comparisons and tests.
280  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
281  const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_LT>, const Derived, const OtherDerived>
282  operator<(const OtherDerived& other) const {
283  return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, internal::cmp_LT>());
284  }
285  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
286  const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_LE>, const Derived, const OtherDerived>
287  operator<=(const OtherDerived& other) const {
288  return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, internal::cmp_LE>());
289  }
290  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
291  const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_GT>, const Derived, const OtherDerived>
292  operator>(const OtherDerived& other) const {
293  return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, internal::cmp_GT>());
294  }
295  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
296  const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_GE>, const Derived, const OtherDerived>
297  operator>=(const OtherDerived& other) const {
298  return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, internal::cmp_GE>());
299  }
300 
301  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
302  const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_EQ>, const Derived, const OtherDerived>
303  operator==(const OtherDerived& other) const {
304  return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, internal::cmp_EQ>());
305  }
306  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
307  const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_NEQ>, const Derived, const OtherDerived>
308  operator!=(const OtherDerived& other) const {
309  return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, internal::cmp_NEQ>());
310  }
311 
312  // comparisons and tests for Scalars
313  EIGEN_DEVICE_FUNC
314  EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_LT>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
315  operator<(Scalar threshold) const {
316  return operator<(constant(threshold));
317  }
318  EIGEN_DEVICE_FUNC
319  EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_LE>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
320  operator<=(Scalar threshold) const {
321  return operator<=(constant(threshold));
322  }
323  EIGEN_DEVICE_FUNC
324  EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_GT>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
325  operator>(Scalar threshold) const {
326  return operator>(constant(threshold));
327  }
328  EIGEN_DEVICE_FUNC
329  EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_GE>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
330  operator>=(Scalar threshold) const {
331  return operator>=(constant(threshold));
332  }
333  EIGEN_DEVICE_FUNC
334  EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_EQ>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
335  operator==(Scalar threshold) const {
336  return operator==(constant(threshold));
337  }
338  EIGEN_DEVICE_FUNC
339  EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_NEQ>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
340  operator!=(Scalar threshold) const {
341  return operator!=(constant(threshold));
342  }
343 
344  // Coefficient-wise ternary operators.
345  template<typename ThenDerived, typename ElseDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
346  const TensorSelectOp<const Derived, const ThenDerived, const ElseDerived>
347  select(const ThenDerived& thenTensor, const ElseDerived& elseTensor) const {
348  return TensorSelectOp<const Derived, const ThenDerived, const ElseDerived>(derived(), thenTensor.derived(), elseTensor.derived());
349  }
350 
351  // Contractions.
352  typedef Eigen::IndexPair<Index> DimensionPair;
353 
354  template<typename OtherDerived, typename Dimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
355  const TensorContractionOp<const Dimensions, const Derived, const OtherDerived>
356  contract(const OtherDerived& other, const Dimensions& dims) const {
357  return TensorContractionOp<const Dimensions, const Derived, const OtherDerived>(derived(), other.derived(), dims);
358  }
359 
360  // Convolutions.
361  template<typename KernelDerived, typename Dimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
362  const TensorConvolutionOp<const Dimensions, const Derived, const KernelDerived>
363  convolve(const KernelDerived& kernel, const Dimensions& dims) const {
364  return TensorConvolutionOp<const Dimensions, const Derived, const KernelDerived>(derived(), kernel.derived(), dims);
365  }
366 
367  // Fourier transforms
368  template <int FFTDataType, int FFTDirection, typename FFT> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
369  const TensorFFTOp<const FFT, const Derived, FFTDataType, FFTDirection>
370  fft(const FFT& fft) const {
371  return TensorFFTOp<const FFT, const Derived, FFTDataType, FFTDirection>(derived(), fft);
372  }
373 
374  // Reductions.
375  template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
376  const TensorReductionOp<internal::SumReducer<CoeffReturnType>, const Dims, const Derived>
377  sum(const Dims& dims) const {
378  return TensorReductionOp<internal::SumReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::SumReducer<CoeffReturnType>());
379  }
380 
381  const TensorReductionOp<internal::SumReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
382  sum() const {
383  DimensionList<Index, NumDimensions> in_dims;
384  return TensorReductionOp<internal::SumReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::SumReducer<CoeffReturnType>());
385  }
386 
387  template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
388  const TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const Dims, const Derived>
389  mean(const Dims& dims) const {
390  return TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::MeanReducer<CoeffReturnType>());
391  }
392 
393  const TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
394  mean() const {
395  DimensionList<Index, NumDimensions> in_dims;
396  return TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MeanReducer<CoeffReturnType>());
397  }
398 
399  template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
400  const TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const Dims, const Derived>
401  prod(const Dims& dims) const {
402  return TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::ProdReducer<CoeffReturnType>());
403  }
404 
405  const TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
406  prod() const {
407  DimensionList<Index, NumDimensions> in_dims;
408  return TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::ProdReducer<CoeffReturnType>());
409  }
410 
411  template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
412  const TensorReductionOp<internal::MaxReducer<CoeffReturnType>, const Dims, const Derived>
413  maximum(const Dims& dims) const {
414  return TensorReductionOp<internal::MaxReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::MaxReducer<CoeffReturnType>());
415  }
416 
417  const TensorReductionOp<internal::MaxReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
418  maximum() const {
419  DimensionList<Index, NumDimensions> in_dims;
420  return TensorReductionOp<internal::MaxReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MaxReducer<CoeffReturnType>());
421  }
422 
423  template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
424  const TensorReductionOp<internal::MinReducer<CoeffReturnType>, const Dims, const Derived>
425  minimum(const Dims& dims) const {
426  return TensorReductionOp<internal::MinReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::MinReducer<CoeffReturnType>());
427  }
428 
429  const TensorReductionOp<internal::MinReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
430  minimum() const {
431  DimensionList<Index, NumDimensions> in_dims;
432  return TensorReductionOp<internal::MinReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MinReducer<CoeffReturnType>());
433  }
434 
435  template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
436  const TensorReductionOp<internal::AndReducer, const Dims, const TensorConversionOp<bool, const Derived> >
437  all(const Dims& dims) const {
438  return cast<bool>().reduce(dims, internal::AndReducer());
439  }
440 
441  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
442  const TensorReductionOp<internal::AndReducer, const DimensionList<Index, NumDimensions>, const TensorConversionOp<bool, const Derived> >
443  all() const {
444  DimensionList<Index, NumDimensions> in_dims;
445  return cast<bool>().reduce(in_dims, internal::AndReducer());
446  }
447 
448  template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
449  const TensorReductionOp<internal::OrReducer, const Dims, const TensorConversionOp<bool, const Derived> >
450  any(const Dims& dims) const {
451  return cast<bool>().reduce(dims, internal::OrReducer());
452  }
453 
454  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
455  const TensorReductionOp<internal::OrReducer, const DimensionList<Index, NumDimensions>, const TensorConversionOp<bool, const Derived> >
456  any() const {
457  DimensionList<Index, NumDimensions> in_dims;
458  return cast<bool>().reduce(in_dims, internal::OrReducer());
459  }
460 
461  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
462  const TensorTupleReducerOp<
463  internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
464  const array<Index, NumDimensions>, const Derived>
465  argmax() const {
466  array<Index, NumDimensions> in_dims;
467  for (int d = 0; d < NumDimensions; ++d) in_dims[d] = d;
468  return TensorTupleReducerOp<
469  internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
470  const array<Index, NumDimensions>,
471  const Derived>(derived(), internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >(), -1, in_dims);
472  }
473 
474  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
475  const TensorTupleReducerOp<
476  internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
477  const array<Index, NumDimensions>, const Derived>
478  argmin() const {
479  array<Index, NumDimensions> in_dims;
480  for (int d = 0; d < NumDimensions; ++d) in_dims[d] = d;
481  return TensorTupleReducerOp<
482  internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
483  const array<Index, NumDimensions>,
484  const Derived>(derived(), internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >(), -1, in_dims);
485  }
486 
487  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
488  const TensorTupleReducerOp<
489  internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
490  const array<Index, 1>, const Derived>
491  argmax(const int return_dim) const {
492  array<Index, 1> in_dims;
493  in_dims[0] = return_dim;
494  return TensorTupleReducerOp<
495  internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
496  const array<Index, 1>,
497  const Derived>(derived(), internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >(), return_dim, in_dims);
498  }
499 
500  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
501  const TensorTupleReducerOp<
502  internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
503  const array<Index, 1>, const Derived>
504  argmin(const int return_dim) const {
505  array<Index, 1> in_dims;
506  in_dims[0] = return_dim;
507  return TensorTupleReducerOp<
508  internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
509  const array<Index, 1>,
510  const Derived>(derived(), internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >(), return_dim, in_dims);
511  }
512 
513  template <typename Reducer, typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
514  const TensorReductionOp<Reducer, const Dims, const Derived>
515  reduce(const Dims& dims, const Reducer& reducer) const {
516  return TensorReductionOp<Reducer, const Dims, const Derived>(derived(), dims, reducer);
517  }
518 
519  template <typename Broadcast> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
520  const TensorBroadcastingOp<const Broadcast, const Derived>
521  broadcast(const Broadcast& broadcast) const {
522  return TensorBroadcastingOp<const Broadcast, const Derived>(derived(), broadcast);
523  }
524 
525  template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
526  const TensorConcatenationOp<Axis, const Derived, const OtherDerived>
527  concatenate(const OtherDerived& other, Axis axis) const {
528  return TensorConcatenationOp<Axis, const Derived, const OtherDerived>(derived(), other.derived(), axis);
529  }
530 
531  template <typename PatchDims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
532  const TensorPatchOp<const PatchDims, const Derived>
533  extract_patches(const PatchDims& patch_dims) const {
534  return TensorPatchOp<const PatchDims, const Derived>(derived(), patch_dims);
535  }
536 
537  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
538  const TensorImagePatchOp<Dynamic, Dynamic, const Derived>
539  extract_image_patches(const Index patch_rows = 1, const Index patch_cols = 1,
540  const Index row_stride = 1, const Index col_stride = 1,
541  const Index in_row_stride = 1, const Index in_col_stride = 1,
542  const PaddingType padding_type = PADDING_SAME, const Scalar padding_value = Scalar(0)) const {
543  return TensorImagePatchOp<Dynamic, Dynamic, const Derived>(derived(), patch_rows, patch_cols, row_stride, col_stride,
544  in_row_stride, in_col_stride, 1, 1, padding_type, padding_value);
545  }
546 
547  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
548  const TensorImagePatchOp<Dynamic, Dynamic, const Derived>
549  extract_image_patches(const Index patch_rows, const Index patch_cols,
550  const Index row_stride, const Index col_stride,
551  const Index in_row_stride, const Index in_col_stride,
552  const Index row_inflate_stride, const Index col_inflate_stride,
553  const Index padding_top, const Index padding_bottom,
554  const Index padding_left,const Index padding_right,
555  const Scalar padding_value) const {
556  return TensorImagePatchOp<Dynamic, Dynamic, const Derived>(derived(), patch_rows, patch_cols, row_stride, col_stride,
557  in_row_stride, in_col_stride, row_inflate_stride, col_inflate_stride,
558  padding_top, padding_bottom, padding_left, padding_right, padding_value);
559  }
560 
561  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
562  const TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>
563  extract_volume_patches(const Index patch_planes, const Index patch_rows, const Index patch_cols,
564  const Index plane_stride = 1, const Index row_stride = 1, const Index col_stride = 1,
565  const PaddingType padding_type = PADDING_SAME, const Scalar padding_value = 0) const {
566  return TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>(derived(), patch_planes, patch_rows, patch_cols, plane_stride, row_stride, col_stride, 1, 1, 1, 1, 1, 1, padding_type, padding_value);
567  }
568 
569 
570  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
571  const TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>
572  extract_volume_patches(const Index patch_planes, const Index patch_rows, const Index patch_cols,
573  const Index plane_stride, const Index row_stride, const Index col_stride,
574  const Index plane_inflate_stride, const Index row_inflate_stride, const Index col_inflate_stride,
575  const Index padding_top_z, const Index padding_bottom_z,
576  const Index padding_top, const Index padding_bottom,
577  const Index padding_left, const Index padding_right, const Scalar padding_value = 0) const {
578  return TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>(derived(), patch_planes, patch_rows, patch_cols, plane_stride, row_stride, col_stride, 1, 1, 1, plane_inflate_stride, row_inflate_stride, col_inflate_stride, padding_top_z, padding_bottom_z, padding_top, padding_bottom, padding_left, padding_right, padding_value);
579  }
580 
581  // Morphing operators.
582  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
583  const TensorLayoutSwapOp<const Derived>
584  swap_layout() const {
585  return TensorLayoutSwapOp<const Derived>(derived());
586  }
587  template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
588  const TensorReshapingOp<const NewDimensions, const Derived>
589  reshape(const NewDimensions& newDimensions) const {
590  return TensorReshapingOp<const NewDimensions, const Derived>(derived(), newDimensions);
591  }
592  template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
593  const TensorSlicingOp<const StartIndices, const Sizes, const Derived>
594  slice(const StartIndices& startIndices, const Sizes& sizes) const {
595  return TensorSlicingOp<const StartIndices, const Sizes, const Derived>(derived(), startIndices, sizes);
596  }
597  template <Index DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
598  const TensorChippingOp<DimId, const Derived>
599  chip(const Index offset) const {
600  return TensorChippingOp<DimId, const Derived>(derived(), offset, DimId);
601  }
602  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
603  const TensorChippingOp<Dynamic, const Derived>
604  chip(const Index offset, const Index dim) const {
605  return TensorChippingOp<Dynamic, const Derived>(derived(), offset, dim);
606  }
607  template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
608  const TensorReverseOp<const ReverseDimensions, const Derived>
609  reverse(const ReverseDimensions& rev) const {
610  return TensorReverseOp<const ReverseDimensions, const Derived>(derived(), rev);
611  }
612  template <typename PaddingDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
613  const TensorPaddingOp<const PaddingDimensions, const Derived>
614  pad(const PaddingDimensions& padding) const {
615  return TensorPaddingOp<const PaddingDimensions, const Derived>(derived(), padding);
616  }
617  template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
618  const TensorShufflingOp<const Shuffle, const Derived>
619  shuffle(const Shuffle& shuffle) const {
620  return TensorShufflingOp<const Shuffle, const Derived>(derived(), shuffle);
621  }
622  template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
623  const TensorStridingOp<const Strides, const Derived>
624  stride(const Strides& strides) const {
625  return TensorStridingOp<const Strides, const Derived>(derived(), strides);
626  }
627  template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
628  const TensorInflationOp<const Strides, const Derived>
629  inflate(const Strides& strides) const {
630  return TensorInflationOp<const Strides, const Derived>(derived(), strides);
631  }
632 
633  // Returns a tensor containing index/value tuples
634  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
635  const TensorIndexTupleOp<const Derived>
636  index_tuples() const {
637  return TensorIndexTupleOp<const Derived>(derived());
638  }
639 
640  // Support for custom unary and binary operations
641  template <typename CustomUnaryFunc>
642  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
643  const TensorCustomUnaryOp<const CustomUnaryFunc, const Derived> customOp(const CustomUnaryFunc& op) const {
644  return TensorCustomUnaryOp<const CustomUnaryFunc, const Derived>(derived(), op);
645  }
646  template <typename OtherDerived, typename CustomBinaryFunc>
647  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
648  const TensorCustomBinaryOp<const CustomBinaryFunc, const Derived, const OtherDerived> customOp(const OtherDerived& other, const CustomBinaryFunc& op) const {
649  return TensorCustomBinaryOp<const CustomBinaryFunc, const Derived, const OtherDerived>(derived(), other, op);
650  }
651 
652  // Force the evaluation of the expression.
653  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
654  const TensorForcedEvalOp<const Derived> eval() const {
655  return TensorForcedEvalOp<const Derived>(derived());
656  }
657 
658  protected:
659  template <typename Scalar, int NumIndices, int Options, typename IndexType> friend class Tensor;
660  template <typename Scalar, typename Dimensions, int Option, typename IndexTypes> friend class TensorFixedSize;
661  template <typename OtherDerived, int AccessLevel> friend class TensorBase;
662  EIGEN_DEVICE_FUNC
663  EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); }
664 };
665 
666 template<typename Derived>
667 class TensorBase<Derived, WriteAccessors> : public TensorBase<Derived, ReadOnlyAccessors> {
668  public:
669  typedef internal::traits<Derived> DerivedTraits;
670  typedef typename DerivedTraits::Scalar Scalar;
671  typedef typename DerivedTraits::Index Index;
672  typedef Scalar CoeffReturnType;
673  typedef typename internal::packet_traits<Scalar>::type PacketReturnType;
674  static const int NumDimensions = DerivedTraits::NumDimensions;
675 
676  template <typename Scalar, int NumIndices, int Options, typename IndexType> friend class Tensor;
677  template <typename Scalar, typename Dimensions, int Option, typename IndexTypes> friend class TensorFixedSize;
678  template <typename OtherDerived, int AccessLevel> friend class TensorBase;
679 
680  EIGEN_DEVICE_FUNC
681  EIGEN_STRONG_INLINE Derived& setZero() {
682  return setConstant(Scalar(0));
683  }
684  EIGEN_DEVICE_FUNC
685  EIGEN_STRONG_INLINE Derived& setConstant(const Scalar& val) {
686  return derived() = this->constant(val);
687  }
688  EIGEN_DEVICE_FUNC
689  EIGEN_STRONG_INLINE Derived& setRandom() {
690  return derived() = this->random();
691  }
692  template <typename RandomGenerator> EIGEN_DEVICE_FUNC
693  EIGEN_STRONG_INLINE Derived& setRandom() {
694  return derived() = this->template random<RandomGenerator>();
695  }
696 
697 #ifdef EIGEN_HAS_VARIADIC_TEMPLATES
698  EIGEN_DEVICE_FUNC
699  EIGEN_STRONG_INLINE Derived& setValues(
700  const typename internal::Initializer<Derived, NumDimensions>::InitList& vals) {
701  TensorEvaluator<Derived, DefaultDevice> eval(derived(), DefaultDevice());
702  internal::initialize_tensor<Derived, NumDimensions>(eval, vals);
703  return derived();
704  }
705 #endif // EIGEN_HAS_VARIADIC_TEMPLATES
706 
707  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
708  Derived& operator+=(const OtherDerived& other) {
709  return derived() = derived() + other.derived();
710  }
711  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
712  Derived& operator-=(const OtherDerived& other) {
713  return derived() = derived() - other.derived();
714  }
715  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
716  Derived& operator*=(const OtherDerived& other) {
717  return derived() = derived() * other.derived();
718  }
719  template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
720  Derived& operator/=(const OtherDerived& other) {
721  return derived() = derived() / other.derived();
722  }
723 
724  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
725  const TensorLayoutSwapOp<const Derived>
726  swap_layout() const {
727  return TensorLayoutSwapOp<const Derived>(derived());
728  }
729  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
730  TensorLayoutSwapOp<Derived>
731  swap_layout() {
732  return TensorLayoutSwapOp<Derived>(derived());
733  }
734 
735  template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
736  const TensorConcatenationOp<const Axis, const Derived, const OtherDerived>
737  concatenate(const OtherDerived& other, const Axis& axis) const {
738  return TensorConcatenationOp<const Axis, const Derived, const OtherDerived>(derived(), other, axis);
739  }
740  template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
741  TensorConcatenationOp<const Axis, Derived, OtherDerived>
742  concatenate(const OtherDerived& other, const Axis& axis) {
743  return TensorConcatenationOp<const Axis, Derived, OtherDerived>(derived(), other, axis);
744  }
745 
746  template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
747  const TensorReshapingOp<const NewDimensions, const Derived>
748  reshape(const NewDimensions& newDimensions) const {
749  return TensorReshapingOp<const NewDimensions, const Derived>(derived(), newDimensions);
750  }
751  template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
752  TensorReshapingOp<const NewDimensions, Derived>
753  reshape(const NewDimensions& newDimensions) {
754  return TensorReshapingOp<const NewDimensions, Derived>(derived(), newDimensions);
755  }
756 
757  template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
758  const TensorSlicingOp<const StartIndices, const Sizes, const Derived>
759  slice(const StartIndices& startIndices, const Sizes& sizes) const {
760  return TensorSlicingOp<const StartIndices, const Sizes, const Derived>(derived(), startIndices, sizes);
761  }
762  template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
763  TensorSlicingOp<const StartIndices, const Sizes, Derived>
764  slice(const StartIndices& startIndices, const Sizes& sizes) {
765  return TensorSlicingOp<const StartIndices, const Sizes, Derived>(derived(), startIndices, sizes);
766  }
767 
768  template <DenseIndex DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
769  const TensorChippingOp<DimId, const Derived>
770  chip(const Index offset) const {
771  return TensorChippingOp<DimId, const Derived>(derived(), offset, DimId);
772  }
773  template <Index DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
774  TensorChippingOp<DimId, Derived>
775  chip(const Index offset) {
776  return TensorChippingOp<DimId, Derived>(derived(), offset, DimId);
777  }
778 
779  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
780  const TensorChippingOp<Dynamic, const Derived>
781  chip(const Index offset, const Index dim) const {
782  return TensorChippingOp<Dynamic, const Derived>(derived(), offset, dim);
783  }
784  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
785  TensorChippingOp<Dynamic, Derived>
786  chip(const Index offset, const Index dim) {
787  return TensorChippingOp<Dynamic, Derived>(derived(), offset, dim);
788  }
789 
790  template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
791  const TensorReverseOp<const ReverseDimensions, const Derived>
792  reverse(const ReverseDimensions& rev) const {
793  return TensorReverseOp<const ReverseDimensions, const Derived>(derived(), rev);
794  }
795  template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
796  TensorReverseOp<const ReverseDimensions, Derived>
797  reverse(const ReverseDimensions& rev) {
798  return TensorReverseOp<const ReverseDimensions, Derived>(derived(), rev);
799  }
800 
801  template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
802  const TensorShufflingOp<const Shuffle, const Derived>
803  shuffle(const Shuffle& shuffle) const {
804  return TensorShufflingOp<const Shuffle, const Derived>(derived(), shuffle);
805  }
806  template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
807  TensorShufflingOp<const Shuffle, Derived>
808  shuffle(const Shuffle& shuffle) {
809  return TensorShufflingOp<const Shuffle, Derived>(derived(), shuffle);
810  }
811 
812  template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
813  const TensorStridingOp<const Strides, const Derived>
814  stride(const Strides& strides) const {
815  return TensorStridingOp<const Strides, const Derived>(derived(), strides);
816  }
817  template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
818  TensorStridingOp<const Strides, Derived>
819  stride(const Strides& strides) {
820  return TensorStridingOp<const Strides, Derived>(derived(), strides);
821  }
822 
823  // Select the device on which to evaluate the expression.
824  template <typename DeviceType>
825  TensorDevice<Derived, DeviceType> device(const DeviceType& device) {
826  return TensorDevice<Derived, DeviceType>(device, derived());
827  }
828 
829  protected:
830  EIGEN_DEVICE_FUNC
831  EIGEN_STRONG_INLINE Derived& derived() { return *static_cast<Derived*>(this); }
832  EIGEN_DEVICE_FUNC
833  EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); }
834 };
835 
836 } // end namespace Eigen
837 
838 #endif // EIGEN_CXX11_TENSOR_TENSOR_BASE_H
Namespace containing all symbols from the Eigen library.
Definition: CXX11Meta.h:13