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