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