Eigen-Contrib  5.0.1
 
Loading...
Searching...
No Matches
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// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_TENSOR_TENSOR_BASE_H
12#define EIGEN_TENSOR_TENSOR_BASE_H
13
14// clang-format off
15
16// IWYU pragma: private
17#include "./InternalHeaderCheck.h"
18
19namespace Eigen {
20
21namespace internal {
22// Const TensorMap expressions expose a const-qualified Scalar. Ignore cv-qualifiers for an exact scalar match, while
23// keeping mixed arithmetic and enum operands within the existing implicit-conversion boundary.
24template <typename OtherScalar, typename Scalar>
25struct is_scalar_operand
26 : bool_constant<std::is_same<typename std::remove_cv<OtherScalar>::type,
27 typename std::remove_cv<Scalar>::type>::value ||
28 ((std::is_arithmetic<OtherScalar>::value || std::is_enum<OtherScalar>::value) &&
29 std::is_convertible<OtherScalar, Scalar>::value)> {};
30} // namespace internal
31
40#ifndef EIGEN_PARSED_BY_DOXYGEN
41// FIXME: Doxygen does not like the inheritance with different template parameters
42// Since there is no doxygen documentation inside, we disable it for now
43template<typename Derived>
44class TensorBase<Derived, ReadOnlyAccessors>
45{
46 public:
47 typedef internal::traits<Derived> DerivedTraits;
48 typedef typename DerivedTraits::Scalar Scalar;
49 typedef typename DerivedTraits::Index Index;
50 typedef std::remove_const_t<Scalar> CoeffReturnType;
51 static constexpr int NumDimensions = DerivedTraits::NumDimensions;
52
53 // Generic nullary operation support.
54 template <typename CustomNullaryOp> EIGEN_DEVICE_FUNC
55 EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<CustomNullaryOp, const Derived>
56 nullaryExpr(const CustomNullaryOp& func) const {
57 return TensorCwiseNullaryOp<CustomNullaryOp, const Derived>(derived(), func);
58 }
59
60 // Coefficient-wise nullary operators
61 EIGEN_DEVICE_FUNC
62 EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived>
63 constant(const Scalar& value) const {
64 return nullaryExpr(internal::scalar_constant_op<Scalar>(value));
65 }
66
67 EIGEN_DEVICE_FUNC
68 EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<internal::UniformRandomGenerator<Scalar>, const Derived>
69 random() const {
70 return nullaryExpr(internal::UniformRandomGenerator<Scalar>());
71 }
72 template <typename RandomGenerator> EIGEN_DEVICE_FUNC
73 EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<RandomGenerator, const Derived>
74 random(const RandomGenerator& gen = RandomGenerator()) const {
75 return nullaryExpr(gen);
76 }
77
78 // Tensor generation
79 template <typename Generator> EIGEN_DEVICE_FUNC
80 EIGEN_STRONG_INLINE const TensorGeneratorOp<Generator, const Derived>
81 generate(const Generator& generator) const {
82 return TensorGeneratorOp<Generator, const Derived>(derived(), generator);
83 }
84
85 // Generic unary operation support.
86 template <typename CustomUnaryOp> EIGEN_DEVICE_FUNC
87 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<CustomUnaryOp, const Derived>
88 unaryExpr(const CustomUnaryOp& func) const {
89 return TensorCwiseUnaryOp<CustomUnaryOp, const Derived>(derived(), func);
90 }
91
92 // Coefficient-wise unary operators
93 EIGEN_DEVICE_FUNC
94 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const Derived>
95 operator-() const {
96 return unaryExpr(internal::scalar_opposite_op<Scalar>());
97 }
98
99 EIGEN_DEVICE_FUNC
100 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sqrt_op<Scalar>, const Derived>
101 sqrt() const {
102 return unaryExpr(internal::scalar_sqrt_op<Scalar>());
103 }
104
105 EIGEN_DEVICE_FUNC
106 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sign_op<Scalar>, const Derived>
107 sign() const {
108 return unaryExpr(internal::scalar_sign_op<Scalar>());
109 }
110
111 EIGEN_DEVICE_FUNC
112 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_rsqrt_op<Scalar>, const Derived>
113 rsqrt() const {
114 return unaryExpr(internal::scalar_rsqrt_op<Scalar>());
115 }
116
117 EIGEN_DEVICE_FUNC
118 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_square_op<Scalar>, const Derived>
119 square() const {
120 return unaryExpr(internal::scalar_square_op<Scalar>());
121 }
122
123 EIGEN_DEVICE_FUNC
124 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_cube_op<Scalar>, const Derived>
125 cube() const {
126 return unaryExpr(internal::scalar_cube_op<Scalar>());
127 }
128
129 EIGEN_DEVICE_FUNC
130 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const Derived>
131 inverse() const {
132 return unaryExpr(internal::scalar_inverse_op<Scalar>());
133 }
134
135 EIGEN_DEVICE_FUNC
136 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_tanh_op<Scalar>, const Derived>
137 tanh() const {
138 return unaryExpr(internal::scalar_tanh_op<Scalar>());
139 }
140
141 EIGEN_DEVICE_FUNC
142 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_lgamma_op<Scalar>, const Derived>
143 lgamma() const {
144 return unaryExpr(internal::scalar_lgamma_op<Scalar>());
145 }
146
147 EIGEN_DEVICE_FUNC
148 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_digamma_op<Scalar>, const Derived>
149 digamma() const {
150 return unaryExpr(internal::scalar_digamma_op<Scalar>());
151 }
152
153 EIGEN_DEVICE_FUNC
154 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_i0_op<Scalar>, const Derived>
155 bessel_i0() const {
156 return unaryExpr(internal::scalar_bessel_i0_op<Scalar>());
157 }
158
159 EIGEN_DEVICE_FUNC
160 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_i0e_op<Scalar>, const Derived>
161 bessel_i0e() const {
162 return unaryExpr(internal::scalar_bessel_i0e_op<Scalar>());
163 }
164
165 EIGEN_DEVICE_FUNC
166 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_i1_op<Scalar>, const Derived>
167 bessel_i1() const {
168 return unaryExpr(internal::scalar_bessel_i1_op<Scalar>());
169 }
170
171 EIGEN_DEVICE_FUNC
172 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_i1e_op<Scalar>, const Derived>
173 bessel_i1e() const {
174 return unaryExpr(internal::scalar_bessel_i1e_op<Scalar>());
175 }
176
177 EIGEN_DEVICE_FUNC
178 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_j0_op<Scalar>, const Derived>
179 bessel_j0() const {
180 return unaryExpr(internal::scalar_bessel_j0_op<Scalar>());
181 }
182
183 EIGEN_DEVICE_FUNC
184 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_y0_op<Scalar>, const Derived>
185 bessel_y0() const {
186 return unaryExpr(internal::scalar_bessel_y0_op<Scalar>());
187 }
188
189 EIGEN_DEVICE_FUNC
190 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_j1_op<Scalar>, const Derived>
191 bessel_j1() const {
192 return unaryExpr(internal::scalar_bessel_j1_op<Scalar>());
193 }
194
195 EIGEN_DEVICE_FUNC
196 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_y1_op<Scalar>, const Derived>
197 bessel_y1() const {
198 return unaryExpr(internal::scalar_bessel_y1_op<Scalar>());
199 }
200
201 EIGEN_DEVICE_FUNC
202 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_k0_op<Scalar>, const Derived>
203 bessel_k0() const {
204 return unaryExpr(internal::scalar_bessel_k0_op<Scalar>());
205 }
206
207 EIGEN_DEVICE_FUNC
208 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_k0e_op<Scalar>, const Derived>
209 bessel_k0e() const {
210 return unaryExpr(internal::scalar_bessel_k0e_op<Scalar>());
211 }
212
213 EIGEN_DEVICE_FUNC
214 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_k1_op<Scalar>, const Derived>
215 bessel_k1() const {
216 return unaryExpr(internal::scalar_bessel_k1_op<Scalar>());
217 }
218
219 EIGEN_DEVICE_FUNC
220 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_k1e_op<Scalar>, const Derived>
221 bessel_k1e() const {
222 return unaryExpr(internal::scalar_bessel_k1e_op<Scalar>());
223 }
224
225 // igamma(a = this, x = other)
226 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
227 const TensorCwiseBinaryOp<internal::scalar_igamma_op<Scalar>, const Derived, const OtherDerived>
228 igamma(const OtherDerived& other) const {
229 return binaryExpr(other.derived(), internal::scalar_igamma_op<Scalar>());
230 }
231
232 // igamma_der_a(a = this, x = other)
233 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
234 const TensorCwiseBinaryOp<internal::scalar_igamma_der_a_op<Scalar>, const Derived, const OtherDerived>
235 igamma_der_a(const OtherDerived& other) const {
236 return binaryExpr(other.derived(), internal::scalar_igamma_der_a_op<Scalar>());
237 }
238
239 // gamma_sample_der_alpha(alpha = this, sample = other)
240 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
241 const TensorCwiseBinaryOp<internal::scalar_gamma_sample_der_alpha_op<Scalar>, const Derived, const OtherDerived>
242 gamma_sample_der_alpha(const OtherDerived& other) const {
243 return binaryExpr(other.derived(), internal::scalar_gamma_sample_der_alpha_op<Scalar>());
244 }
245
246 // igammac(a = this, x = other)
247 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
248 const TensorCwiseBinaryOp<internal::scalar_igammac_op<Scalar>, const Derived, const OtherDerived>
249 igammac(const OtherDerived& other) const {
250 return binaryExpr(other.derived(), internal::scalar_igammac_op<Scalar>());
251 }
252
253 // zeta(x = this, q = other)
254 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
255 const TensorCwiseBinaryOp<internal::scalar_zeta_op<Scalar>, const Derived, const OtherDerived>
256 zeta(const OtherDerived& other) const {
257 return binaryExpr(other.derived(), internal::scalar_zeta_op<Scalar>());
258 }
259
260 // polygamma(n = this, x = other)
261 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
262 const TensorCwiseBinaryOp<internal::scalar_polygamma_op<Scalar>, const Derived, const OtherDerived>
263 polygamma(const OtherDerived& other) const {
264 return binaryExpr(other.derived(), internal::scalar_polygamma_op<Scalar>());
265 }
266
267 EIGEN_DEVICE_FUNC
268 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_erf_op<Scalar>, const Derived>
269 erf() const {
270 return unaryExpr(internal::scalar_erf_op<Scalar>());
271 }
272
273 EIGEN_DEVICE_FUNC
274 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_erfc_op<Scalar>, const Derived>
275 erfc() const {
276 return unaryExpr(internal::scalar_erfc_op<Scalar>());
277 }
278
279 EIGEN_DEVICE_FUNC
280 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_ndtri_op<Scalar>, const Derived>
281 ndtri() const {
282 return unaryExpr(internal::scalar_ndtri_op<Scalar>());
283 }
284
285 EIGEN_DEVICE_FUNC
286 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_logistic_op<Scalar>, const Derived>
287 sigmoid() const {
288 return unaryExpr(internal::scalar_logistic_op<Scalar>());
289 }
290
291 EIGEN_DEVICE_FUNC
292 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_exp_op<Scalar>, const Derived>
293 exp() const {
294 return unaryExpr(internal::scalar_exp_op<Scalar>());
295 }
296
297 EIGEN_DEVICE_FUNC
298 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_expm1_op<Scalar>, const Derived>
299 expm1() const {
300 return unaryExpr(internal::scalar_expm1_op<Scalar>());
301 }
302
303 EIGEN_DEVICE_FUNC
304 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log_op<Scalar>, const Derived>
305 log() const {
306 return unaryExpr(internal::scalar_log_op<Scalar>());
307 }
308
309 EIGEN_DEVICE_FUNC
310 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log1p_op<Scalar>, const Derived>
311 log1p() const {
312 return unaryExpr(internal::scalar_log1p_op<Scalar>());
313 }
314
315 EIGEN_DEVICE_FUNC
316 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log2_op<Scalar>, const Derived>
317 log2() const {
318 return unaryExpr(internal::scalar_log2_op<Scalar>());
319 }
320
321 EIGEN_DEVICE_FUNC
322 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_abs_op<Scalar>, const Derived>
323 abs() const {
324 return unaryExpr(internal::scalar_abs_op<Scalar>());
325 }
326
327 EIGEN_DEVICE_FUNC
328 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_arg_op<Scalar>, const Derived>
329 arg() const {
330 return unaryExpr(internal::scalar_arg_op<Scalar>());
331 }
332
333 EIGEN_DEVICE_FUNC
334 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_clamp_op<Scalar>, const Derived>
335 clip(Scalar min, Scalar max) const {
336 return unaryExpr(internal::scalar_clamp_op<Scalar>(min, max));
337 }
338
339 EIGEN_DEVICE_FUNC
340 EIGEN_STRONG_INLINE const std::conditional_t<NumTraits<CoeffReturnType>::IsComplex,
341 TensorCwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, const Derived>,
342 Derived>
343 conjugate() const {
344 return choose(Cond<NumTraits<CoeffReturnType>::IsComplex>(), unaryExpr(internal::scalar_conjugate_op<Scalar>()), derived());
345 }
346
347 template<typename ScalarExponent>
348 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const std::enable_if_t<internal::is_arithmetic<typename NumTraits<ScalarExponent>::Real>::value,
349 TensorCwiseUnaryOp<internal::scalar_unary_pow_op<Scalar, ScalarExponent>, const Derived>>
350 pow(ScalarExponent exponent) const
351 {
352 return unaryExpr(internal::scalar_unary_pow_op<Scalar, ScalarExponent>(exponent));
353 }
354
355 EIGEN_DEVICE_FUNC
356 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_real_op<Scalar>, const Derived>
357 real() const {
358 return unaryExpr(internal::scalar_real_op<Scalar>());
359 }
360
361 EIGEN_DEVICE_FUNC
362 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_imag_op<Scalar>, const Derived>
363 imag() const {
364 return unaryExpr(internal::scalar_imag_op<Scalar>());
365 }
366
367 EIGEN_DEVICE_FUNC
368 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_sum_op<Scalar,Scalar> >, const Derived>
369 operator+ (Scalar rhs) const {
370 return unaryExpr(internal::bind2nd_op<internal::scalar_sum_op<Scalar,Scalar> >(rhs));
371 }
372
373 EIGEN_DEVICE_FUNC
374 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_difference_op<Scalar,Scalar> >, const Derived>
375 operator- (Scalar rhs) const {
376 EIGEN_STATIC_ASSERT((NumTraits<Scalar>::IsSigned || std::is_same<Scalar, const std::complex<float> >::value), YOU_MADE_A_PROGRAMMING_MISTAKE);
377 return unaryExpr(internal::bind2nd_op<internal::scalar_difference_op<Scalar,Scalar> >(rhs));
378 }
379
380 EIGEN_DEVICE_FUNC
381 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_product_op<Scalar,Scalar> >, const Derived>
382 operator* (Scalar rhs) const {
383 return unaryExpr(internal::bind2nd_op<internal::scalar_product_op<Scalar,Scalar> >(rhs));
384 }
385
386 EIGEN_DEVICE_FUNC
387 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_quotient_op<Scalar,Scalar> >, const Derived>
388 operator/ (Scalar rhs) const {
389 return unaryExpr(internal::bind2nd_op<internal::scalar_quotient_op<Scalar,Scalar> >(rhs));
390 }
391
392 EIGEN_DEVICE_FUNC
393 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_mod_op<Scalar>, const Derived>
394 operator% (Scalar rhs) const {
395 EIGEN_STATIC_ASSERT(NumTraits<Scalar>::IsInteger, YOU_MADE_A_PROGRAMMING_MISTAKE_TRY_MOD);
396 return unaryExpr(internal::scalar_mod_op<Scalar>(rhs));
397 }
398
399 template <typename OtherScalar, EIGEN_SFINAE_ENABLE_IF((internal::is_scalar_operand<OtherScalar, Scalar>::value))>
400 EIGEN_DEVICE_FUNC
401 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_mod_op<Scalar>, const Derived>
402 operator% (OtherScalar rhs) const {
403 return operator%(static_cast<Scalar>(rhs));
404 }
405
406 template <int NanPropagation=PropagateFast>
407 EIGEN_DEVICE_FUNC
408 EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar,NanPropagation>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
409 cwiseMax(Scalar threshold) const {
410 return cwiseMax<NanPropagation>(constant(threshold));
411 }
412
413 template <int NanPropagation=PropagateFast>
414 EIGEN_DEVICE_FUNC
415 EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar,NanPropagation>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
416 cwiseMin(Scalar threshold) const {
417 return cwiseMin<NanPropagation>(constant(threshold));
418 }
419
420 template<typename NewType>
421 EIGEN_DEVICE_FUNC
422 EIGEN_STRONG_INLINE const std::conditional_t<std::is_same<NewType, CoeffReturnType>::value,
423 Derived,
424 TensorConversionOp<NewType, const Derived> >
425 cast() const {
426 return choose(Cond<std::is_same<NewType, CoeffReturnType>::value>(), derived(), TensorConversionOp<NewType, const Derived>(derived()));
427 }
428
429 EIGEN_DEVICE_FUNC
430 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_round_op<Scalar>, const Derived>
431 round() const {
432 return unaryExpr(internal::scalar_round_op<Scalar>());
433 }
434
435 EIGEN_DEVICE_FUNC
436 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_rint_op<Scalar>, const Derived>
437 rint() const {
438 return unaryExpr(internal::scalar_rint_op<Scalar>());
439 }
440
441 EIGEN_DEVICE_FUNC
442 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_ceil_op<Scalar>, const Derived>
443 ceil() const {
444 return unaryExpr(internal::scalar_ceil_op<Scalar>());
445 }
446
447 EIGEN_DEVICE_FUNC
448 EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_floor_op<Scalar>, const Derived>
449 floor() const {
450 return unaryExpr(internal::scalar_floor_op<Scalar>());
451 }
452
453 // Generic binary operation support.
454 template <typename CustomBinaryOp, typename OtherDerived> EIGEN_DEVICE_FUNC
455 EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>
456 binaryExpr(const OtherDerived& other, const CustomBinaryOp& func) const {
457 return TensorCwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>(derived(), other, func);
458 }
459
460 // Coefficient-wise binary operators. The TensorBase-constrained operand keeps scalar
461 // right-hand sides on the scalar overloads instead of a deduced tensor-tensor expression
462 // whose instantiation fails.
463 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
464 const TensorCwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const OtherDerived>
465 operator+(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
466 return binaryExpr(other.derived(), internal::scalar_sum_op<Scalar>());
467 }
468
469 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
470 const TensorCwiseBinaryOp<internal::scalar_difference_op<Scalar>, const Derived, const OtherDerived>
471 operator-(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
472 return binaryExpr(other.derived(), internal::scalar_difference_op<Scalar>());
473 }
474
475 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
476 const TensorCwiseBinaryOp<internal::scalar_product_op<Scalar>, const Derived, const OtherDerived>
477 operator*(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
478 return binaryExpr(other.derived(), internal::scalar_product_op<Scalar>());
479 }
480
481 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
482 const TensorCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, const Derived, const OtherDerived>
483 operator/(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
484 return binaryExpr(other.derived(), internal::scalar_quotient_op<Scalar>());
485 }
486
487 template<int NaNPropagation=PropagateFast, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
488 const TensorCwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar, NaNPropagation>, const Derived, const OtherDerived>
489 cwiseMax(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
490 return binaryExpr(other.derived(), internal::scalar_max_op<Scalar,Scalar, NaNPropagation>());
491 }
492
493 template<int NaNPropagation=PropagateFast, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
494 const TensorCwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar, NaNPropagation>, const Derived, const OtherDerived>
495 cwiseMin(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
496 return binaryExpr(other.derived(), internal::scalar_min_op<Scalar,Scalar, NaNPropagation>());
497 }
498
499 // logical operators
500 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
501 const TensorCwiseBinaryOp<internal::scalar_boolean_and_op<Scalar>, const Derived, const OtherDerived>
502 operator&&(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
503 return binaryExpr(other.derived(), internal::scalar_boolean_and_op<Scalar>());
504 }
505
506 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
507 const TensorCwiseBinaryOp<internal::scalar_boolean_or_op<Scalar>, const Derived, const OtherDerived>
508 operator||(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
509 return binaryExpr(other.derived(), internal::scalar_boolean_or_op<Scalar>());
510 }
511
512 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
513 const TensorCwiseBinaryOp<internal::scalar_bitwise_and_op<Scalar>, const Derived, const OtherDerived>
514 operator&(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
515 return binaryExpr(other.derived(), internal::scalar_bitwise_and_op<Scalar>());
516 }
517
518 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
519 const TensorCwiseBinaryOp<internal::scalar_bitwise_or_op<Scalar>, const Derived, const OtherDerived>
520 operator|(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
521 return binaryExpr(other.derived(), internal::scalar_bitwise_or_op<Scalar>());
522 }
523
524 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
525 const TensorCwiseBinaryOp<internal::scalar_bitwise_xor_op<Scalar>, const Derived, const OtherDerived>
526 operator^(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
527 return binaryExpr(other.derived(), internal::scalar_bitwise_xor_op<Scalar>());
528 }
529
530 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
531 const TensorCwiseUnaryOp<internal::scalar_boolean_not_op<Scalar>, const Derived>
532 operator!() const {
533 return unaryExpr(internal::scalar_boolean_not_op<Scalar>());
534 }
535
536 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
537 const TensorCwiseUnaryOp<internal::scalar_bitwise_not_op<Scalar>, const Derived>
538 operator~() const {
539 return unaryExpr(internal::scalar_bitwise_not_op<Scalar>());
540 }
541
542 // Comparisons and tests.
543 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
544 const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LT>, const Derived, const OtherDerived>
545 operator<(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
546 return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LT>());
547 }
548 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
549 const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LE>, const Derived, const OtherDerived>
550 operator<=(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
551 return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LE>());
552 }
553 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
554 const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GT>, const Derived, const OtherDerived>
555 operator>(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
556 return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GT>());
557 }
558 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
559 const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GE>, const Derived, const OtherDerived>
560 operator>=(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
561 return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GE>());
562 }
563
564 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
565 const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_EQ>, const Derived, const OtherDerived>
566 operator==(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
567 return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_EQ>());
568 }
569
570 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
571 const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_NEQ>, const Derived, const OtherDerived>
572 operator!=(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
573 return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_NEQ>());
574 }
575
576 // comparisons and tests for Scalars
577 EIGEN_DEVICE_FUNC
578 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> >
579 operator<(Scalar threshold) const {
580 return operator<(constant(threshold));
581 }
582 EIGEN_DEVICE_FUNC
583 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> >
584 operator<=(Scalar threshold) const {
585 return operator<=(constant(threshold));
586 }
587 EIGEN_DEVICE_FUNC
588 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> >
589 operator>(Scalar threshold) const {
590 return operator>(constant(threshold));
591 }
592 EIGEN_DEVICE_FUNC
593 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> >
594 operator>=(Scalar threshold) const {
595 return operator>=(constant(threshold));
596 }
597 EIGEN_DEVICE_FUNC
598 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> >
599 operator==(Scalar threshold) const {
600 return operator==(constant(threshold));
601 }
602 EIGEN_DEVICE_FUNC
603 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> >
604 operator!=(Scalar threshold) const {
605 return operator!=(constant(threshold));
606 }
607
608 // Exact matches keep rank-0 reductions' mixed-scalar comparisons from becoming ambiguous with built-ins.
609#define EIGEN_FORWARD_SCALAR_CMP(op, tag) \
610 template <typename OtherScalar, EIGEN_SFINAE_ENABLE_IF((internal::is_scalar_operand<OtherScalar, Scalar>::value))> \
611 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const \
612 TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_##tag>, const Derived, \
613 const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> > \
614 op(OtherScalar threshold) const { \
615 return op(static_cast<Scalar>(threshold)); \
616 }
617 EIGEN_FORWARD_SCALAR_CMP(operator<, LT)
618 EIGEN_FORWARD_SCALAR_CMP(operator<=, LE)
619 EIGEN_FORWARD_SCALAR_CMP(operator>, GT)
620 EIGEN_FORWARD_SCALAR_CMP(operator>=, GE)
621 EIGEN_FORWARD_SCALAR_CMP(operator==, EQ)
622 EIGEN_FORWARD_SCALAR_CMP(operator!=, NEQ)
623#undef EIGEN_FORWARD_SCALAR_CMP
624
625 // Predicates.
626 EIGEN_DEVICE_FUNC
627 EIGEN_STRONG_INLINE const TensorConversionOp<bool, const TensorCwiseUnaryOp<internal::scalar_isnan_op<Scalar, true>, const Derived>>
628 (isnan)() const {
629 return unaryExpr(internal::scalar_isnan_op<Scalar, true>()).template cast<bool>();
630 }
631 EIGEN_DEVICE_FUNC
632 EIGEN_STRONG_INLINE const TensorConversionOp<bool, const TensorCwiseUnaryOp<internal::scalar_isinf_op<Scalar, true>, const Derived>>
633 (isinf)() const {
634 return unaryExpr(internal::scalar_isinf_op<Scalar, true>()).template cast<bool>();
635 }
636 EIGEN_DEVICE_FUNC
637 EIGEN_STRONG_INLINE const TensorConversionOp<bool, const TensorCwiseUnaryOp<internal::scalar_isfinite_op<Scalar, true>, const Derived>>
638 (isfinite)() const {
639 return unaryExpr(internal::scalar_isfinite_op<Scalar, true>()).template cast<bool>();
640 }
641
642 // Coefficient-wise ternary operators.
643 template<typename ThenDerived, typename ElseDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
644 const TensorSelectOp<const Derived, const ThenDerived, const ElseDerived>
645 select(const ThenDerived& thenTensor, const ElseDerived& elseTensor) const {
646 return TensorSelectOp<const Derived, const ThenDerived, const ElseDerived>(derived(), thenTensor.derived(), elseTensor.derived());
647 }
648
649 // Contractions.
650 typedef Eigen::IndexPair<Index> DimensionPair;
651
652 template<typename OtherDerived, typename Dimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
653 const TensorContractionOp<const Dimensions, const Derived, const OtherDerived, const NoOpOutputKernel>
654 contract(const OtherDerived& other, const Dimensions& dims) const {
655 return TensorContractionOp<const Dimensions, const Derived, const OtherDerived, const NoOpOutputKernel>(derived(), other.derived(), dims);
656 }
657
658 template<typename OtherDerived, typename Dimensions, typename OutputKernel> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
659 const TensorContractionOp<const Dimensions, const Derived, const OtherDerived, const OutputKernel>
660 contract(const OtherDerived& other, const Dimensions& dims, const OutputKernel& output_kernel) const {
661 return TensorContractionOp<const Dimensions, const Derived, const OtherDerived, const OutputKernel>(derived(), other.derived(), dims, output_kernel);
662 }
663
664 // Convolutions.
665 template<typename KernelDerived, typename Dimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
666 const TensorConvolutionOp<const Dimensions, const Derived, const KernelDerived>
667 convolve(const KernelDerived& kernel, const Dimensions& dims) const {
668 return TensorConvolutionOp<const Dimensions, const Derived, const KernelDerived>(derived(), kernel.derived(), dims);
669 }
670
671 // Fourier transforms
672 template <int FFTDataType, int FFTDirection, typename FFT> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
673 const TensorFFTOp<const FFT, const Derived, FFTDataType, FFTDirection>
674 fft(const FFT& dims) const {
675 return TensorFFTOp<const FFT, const Derived, FFTDataType, FFTDirection>(derived(), dims);
676 }
677
678 // Scan.
679 typedef TensorScanOp<internal::SumReducer<CoeffReturnType>, const Derived> TensorScanSumOp;
680 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
681 const TensorScanSumOp
682 cumsum(const Index& axis, bool exclusive = false) const {
683 return TensorScanSumOp(derived(), axis, exclusive);
684 }
685
686 typedef TensorScanOp<internal::ProdReducer<CoeffReturnType>, const Derived> TensorScanProdOp;
687 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
688 const TensorScanProdOp
689 cumprod(const Index& axis, bool exclusive = false) const {
690 return TensorScanProdOp(derived(), axis, exclusive);
691 }
692
693 template <typename Reducer>
694 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
695 const TensorScanOp<Reducer, const Derived>
696 scan(const Index& axis, const Reducer& reducer, bool exclusive = false) const {
697 return TensorScanOp<Reducer, const Derived>(derived(), axis, exclusive, reducer);
698 }
699
700 // Reductions.
701 template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
702 const TensorReductionOp<internal::SumReducer<CoeffReturnType>, const Dims, const Derived>
703 sum(const Dims& dims) const {
704 return TensorReductionOp<internal::SumReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::SumReducer<CoeffReturnType>());
705 }
706
707 const TensorReductionOp<internal::SumReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
708 sum() const {
709 DimensionList<Index, NumDimensions> in_dims;
710 return TensorReductionOp<internal::SumReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::SumReducer<CoeffReturnType>());
711 }
712
713 template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
714 const TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const Dims, const Derived>
715 mean(const Dims& dims) const {
716 return TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::MeanReducer<CoeffReturnType>());
717 }
718
719 const TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
720 mean() const {
721 DimensionList<Index, NumDimensions> in_dims;
722 return TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MeanReducer<CoeffReturnType>());
723 }
724
725 template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
726 const TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const Dims, const Derived>
727 prod(const Dims& dims) const {
728 return TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::ProdReducer<CoeffReturnType>());
729 }
730
731 const TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
732 prod() const {
733 DimensionList<Index, NumDimensions> in_dims;
734 return TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::ProdReducer<CoeffReturnType>());
735 }
736
737 template <typename Dims,int NanPropagation=PropagateFast> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
738 const TensorReductionOp<internal::MaxReducer<CoeffReturnType,NanPropagation>, const Dims, const Derived>
739 maximum(const Dims& dims) const {
740 return TensorReductionOp<internal::MaxReducer<CoeffReturnType,NanPropagation>, const Dims, const Derived>(derived(), dims, internal::MaxReducer<CoeffReturnType,NanPropagation>());
741 }
742
743 template <int NanPropagation=PropagateFast>
744 const TensorReductionOp<internal::MaxReducer<CoeffReturnType,NanPropagation>, const DimensionList<Index, NumDimensions>, const Derived>
745 maximum() const {
746 DimensionList<Index, NumDimensions> in_dims;
747 return TensorReductionOp<internal::MaxReducer<CoeffReturnType,NanPropagation>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MaxReducer<CoeffReturnType,NanPropagation>());
748 }
749
750 template <typename Dims,int NanPropagation=PropagateFast> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
751 const TensorReductionOp<internal::MinReducer<CoeffReturnType,NanPropagation>, const Dims, const Derived>
752 minimum(const Dims& dims) const {
753 return TensorReductionOp<internal::MinReducer<CoeffReturnType,NanPropagation>, const Dims, const Derived>(derived(), dims, internal::MinReducer<CoeffReturnType,NanPropagation>());
754 }
755
756 template <int NanPropagation=PropagateFast>
757 const TensorReductionOp<internal::MinReducer<CoeffReturnType,NanPropagation>, const DimensionList<Index, NumDimensions>, const Derived>
758 minimum() const {
759 DimensionList<Index, NumDimensions> in_dims;
760 return TensorReductionOp<internal::MinReducer<CoeffReturnType,NanPropagation>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MinReducer<CoeffReturnType,NanPropagation>());
761 }
762
763 template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
764 const TensorReductionOp<internal::AndReducer, const Dims, const std::conditional_t<std::is_same<bool, CoeffReturnType>::value, Derived, TensorConversionOp<bool, const Derived> > >
765 all(const Dims& dims) const {
766 return cast<bool>().reduce(dims, internal::AndReducer());
767 }
768
769 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
770 const TensorReductionOp<internal::AndReducer, const DimensionList<Index, NumDimensions>, const std::conditional_t<std::is_same<bool, CoeffReturnType>::value, Derived, TensorConversionOp<bool, const Derived> > >
771 all() const {
772 DimensionList<Index, NumDimensions> in_dims;
773 return cast<bool>().reduce(in_dims, internal::AndReducer());
774 }
775
776 template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
777 const TensorReductionOp<internal::OrReducer, const Dims, const std::conditional_t<std::is_same<bool, CoeffReturnType>::value, Derived, TensorConversionOp<bool, const Derived> > >
778 any(const Dims& dims) const {
779 return cast<bool>().reduce(dims, internal::OrReducer());
780 }
781
782 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
783 const TensorReductionOp<internal::OrReducer, const DimensionList<Index, NumDimensions>, const std::conditional_t<std::is_same<bool, CoeffReturnType>::value, Derived, TensorConversionOp<bool, const Derived> > >
784 any() const {
785 DimensionList<Index, NumDimensions> in_dims;
786 return cast<bool>().reduce(in_dims, internal::OrReducer());
787 }
788
789 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
790 const TensorPairReducerOp<
791 internal::ArgMaxPairReducer<Pair<Index, CoeffReturnType> >,
792 const array<Index, NumDimensions>, const Derived>
793 argmax() const {
794 array<Index, NumDimensions> in_dims;
795 for (Index d = 0; d < NumDimensions; ++d) in_dims[d] = d;
796 return TensorPairReducerOp<
797 internal::ArgMaxPairReducer<Pair<Index, CoeffReturnType> >,
798 const array<Index, NumDimensions>,
799 const Derived>(derived(), internal::ArgMaxPairReducer<Pair<Index, CoeffReturnType> >(), -1, in_dims);
800 }
801
802 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
803 const TensorPairReducerOp<
804 internal::ArgMinPairReducer<Pair<Index, CoeffReturnType> >,
805 const array<Index, NumDimensions>, const Derived>
806 argmin() const {
807 array<Index, NumDimensions> in_dims;
808 for (Index d = 0; d < NumDimensions; ++d) in_dims[d] = d;
809 return TensorPairReducerOp<
810 internal::ArgMinPairReducer<Pair<Index, CoeffReturnType> >,
811 const array<Index, NumDimensions>,
812 const Derived>(derived(), internal::ArgMinPairReducer<Pair<Index, CoeffReturnType> >(), -1, in_dims);
813 }
814
815 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
816 const TensorPairReducerOp<
817 internal::ArgMaxPairReducer<Pair<Index, CoeffReturnType> >,
818 const array<Index, 1>, const Derived>
819 argmax(const Index return_dim) const {
820 array<Index, 1> in_dims;
821 in_dims[0] = return_dim;
822 return TensorPairReducerOp<
823 internal::ArgMaxPairReducer<Pair<Index, CoeffReturnType> >,
824 const array<Index, 1>,
825 const Derived>(derived(), internal::ArgMaxPairReducer<Pair<Index, CoeffReturnType> >(), return_dim, in_dims);
826 }
827
828 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
829 const TensorPairReducerOp<
830 internal::ArgMinPairReducer<Pair<Index, CoeffReturnType> >,
831 const array<Index, 1>, const Derived>
832 argmin(const Index return_dim) const {
833 array<Index, 1> in_dims;
834 in_dims[0] = return_dim;
835 return TensorPairReducerOp<
836 internal::ArgMinPairReducer<Pair<Index, CoeffReturnType> >,
837 const array<Index, 1>,
838 const Derived>(derived(), internal::ArgMinPairReducer<Pair<Index, CoeffReturnType> >(), return_dim, in_dims);
839 }
840
841 template <typename Reducer, typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
842 const TensorReductionOp<Reducer, const Dims, const Derived>
843 reduce(const Dims& dims, const Reducer& reducer) const {
844 return TensorReductionOp<Reducer, const Dims, const Derived>(derived(), dims, reducer);
845 }
846
847 template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
848 const TensorTraceOp<const Dims, const Derived>
849 trace(const Dims& dims) const {
850 return TensorTraceOp<const Dims, const Derived>(derived(), dims);
851 }
852
853 const TensorTraceOp<const DimensionList<Index, NumDimensions>, const Derived>
854 trace() const {
855 DimensionList<Index, NumDimensions> in_dims;
856 return TensorTraceOp<const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims);
857 }
858
859 template <typename Broadcast> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
860 const TensorBroadcastingOp<const Broadcast, const Derived>
861 broadcast(const Broadcast& bcast) const {
862 return TensorBroadcastingOp<const Broadcast, const Derived>(derived(), bcast);
863 }
864
865 template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
866 const TensorConcatenationOp<Axis, const Derived, const OtherDerived>
867 concatenate(const OtherDerived& other, Axis axis) const {
868 return TensorConcatenationOp<Axis, const Derived, const OtherDerived>(derived(), other.derived(), axis);
869 }
870
871 template <typename PatchDims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
872 const TensorPatchOp<const PatchDims, const Derived>
873 extract_patches(const PatchDims& patch_dims) const {
874 return TensorPatchOp<const PatchDims, const Derived>(derived(), patch_dims);
875 }
876
877 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
878 const TensorImagePatchOp<Dynamic, Dynamic, const Derived>
879 extract_image_patches(const Index patch_rows = 1, const Index patch_cols = 1,
880 const Index row_stride = 1, const Index col_stride = 1,
881 const Index in_row_stride = 1, const Index in_col_stride = 1,
882 const PaddingType padding_type = PADDING_SAME, const Scalar padding_value = Scalar(0)) const {
883 return TensorImagePatchOp<Dynamic, Dynamic, const Derived>(derived(), patch_rows, patch_cols, row_stride, col_stride,
884 in_row_stride, in_col_stride, 1, 1, padding_type, padding_value);
885 }
886
887 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
888 const TensorImagePatchOp<Dynamic, Dynamic, const Derived>
889 extract_image_patches(const Index patch_rows, const Index patch_cols,
890 const Index row_stride, const Index col_stride,
891 const Index in_row_stride, const Index in_col_stride,
892 const Index row_inflate_stride, const Index col_inflate_stride,
893 const Index padding_top, const Index padding_bottom,
894 const Index padding_left,const Index padding_right,
895 const Scalar padding_value) const {
896 return TensorImagePatchOp<Dynamic, Dynamic, const Derived>(derived(), patch_rows, patch_cols, row_stride, col_stride,
897 in_row_stride, in_col_stride, row_inflate_stride, col_inflate_stride,
898 padding_top, padding_bottom, padding_left, padding_right, padding_value);
899 }
900
901 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
902 const TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>
903 extract_volume_patches(const Index patch_planes, const Index patch_rows, const Index patch_cols,
904 const Index plane_stride = 1, const Index row_stride = 1, const Index col_stride = 1,
905 const PaddingType padding_type = PADDING_SAME, const Scalar padding_value = Scalar(0)) const {
906 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);
907 }
908
909
910 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
911 const TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>
912 extract_volume_patches(const Index patch_planes, const Index patch_rows, const Index patch_cols,
913 const Index plane_stride, const Index row_stride, const Index col_stride,
914 const Index plane_inflate_stride, const Index row_inflate_stride, const Index col_inflate_stride,
915 const Index padding_top_z, const Index padding_bottom_z,
916 const Index padding_top, const Index padding_bottom,
917 const Index padding_left, const Index padding_right, const Scalar padding_value = Scalar(0)) const {
918 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);
919 }
920
921 // Morphing operators.
922 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
923 const TensorLayoutSwapOp<const Derived>
924 swap_layout() const {
925 return TensorLayoutSwapOp<const Derived>(derived());
926 }
927 template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
928 const TensorReshapingOp<const NewDimensions, const Derived>
929 reshape(const NewDimensions& newDimensions) const {
930 return TensorReshapingOp<const NewDimensions, const Derived>(derived(), newDimensions);
931 }
932 template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
933 const TensorSlicingOp<const StartIndices, const Sizes, const Derived>
934 slice(const StartIndices& startIndices, const Sizes& sizes) const {
935 return TensorSlicingOp<const StartIndices, const Sizes, const Derived>(derived(), startIndices, sizes);
936 }
937 template <typename StartIndices, typename StopIndices, typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
938 const TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides, const Derived>
939 stridedSlice(const StartIndices& startIndices, const StopIndices& stopIndices, const Strides& strides) const {
940 return TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides,
941 const Derived>(derived(), startIndices, stopIndices, strides);
942 }
943 template <Index DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
944 const TensorChippingOp<DimId, const Derived>
945 chip(const Index offset) const {
946 EIGEN_STATIC_ASSERT(DimId < Derived::NumDimensions && DimId >= 0, Chip_Dim_out_of_range)
947 return TensorChippingOp<DimId, const Derived>(derived(), offset, DimId);
948 }
949 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
950 const TensorChippingOp<Dynamic, const Derived>
951 chip(const Index offset, const Index dim) const {
952 return TensorChippingOp<Dynamic, const Derived>(derived(), offset, dim);
953 }
954 template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
955 const TensorReverseOp<const ReverseDimensions, const Derived>
956 reverse(const ReverseDimensions& rev) const {
957 return TensorReverseOp<const ReverseDimensions, const Derived>(derived(), rev);
958 }
959 template <typename Rolls> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
960 const TensorRollOp<const Rolls, const Derived>
961 roll(const Rolls& rolls) const {
962 return TensorRollOp<const Rolls, const Derived>(derived(), rolls);
963 }
964 template <typename PaddingDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
965 const TensorPaddingOp<const PaddingDimensions, const Derived>
966 pad(const PaddingDimensions& padding) const {
967 return TensorPaddingOp<const PaddingDimensions, const Derived>(derived(), padding, internal::scalar_cast_op<int, Scalar>()(0));
968 }
969 template <typename PaddingDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
970 const TensorPaddingOp<const PaddingDimensions, const Derived>
971 pad(const PaddingDimensions& padding, const Scalar padding_value) const {
972 return TensorPaddingOp<const PaddingDimensions, const Derived>(derived(), padding, padding_value);
973 }
974 template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
975 const TensorShufflingOp<const Shuffle, const Derived>
976 shuffle(const Shuffle& shfl) const {
977 return TensorShufflingOp<const Shuffle, const Derived>(derived(), shfl);
978 }
979 template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
980 const TensorStridingOp<const Strides, const Derived>
981 stride(const Strides& strides) const {
982 return TensorStridingOp<const Strides, const Derived>(derived(), strides);
983 }
984 template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
985 const TensorInflationOp<const Strides, const Derived>
986 inflate(const Strides& strides) const {
987 return TensorInflationOp<const Strides, const Derived>(derived(), strides);
988 }
989
990 // Returns a tensor containing index/value pairs
991 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
992 const TensorIndexPairOp<const Derived>
993 index_pairs() const {
994 return TensorIndexPairOp<const Derived>(derived());
995 }
996
997 // Support for custom unary and binary operations
998 template <typename CustomUnaryFunc>
999 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1000 const TensorCustomUnaryOp<const CustomUnaryFunc, const Derived> customOp(const CustomUnaryFunc& op) const {
1001 return TensorCustomUnaryOp<const CustomUnaryFunc, const Derived>(derived(), op);
1002 }
1003 template <typename OtherDerived, typename CustomBinaryFunc>
1004 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1005 const TensorCustomBinaryOp<const CustomBinaryFunc, const Derived, const OtherDerived> customOp(const OtherDerived& other, const CustomBinaryFunc& op) const {
1006 return TensorCustomBinaryOp<const CustomBinaryFunc, const Derived, const OtherDerived>(derived(), other, op);
1007 }
1008
1009 // Force the evaluation of the expression.
1010 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1011 const TensorForcedEvalOp<const Derived> eval() const {
1012 return TensorForcedEvalOp<const Derived>(derived());
1013 }
1014
1015 // Returns a formatted tensor ready for printing to a stream
1016 template<typename Format>
1017 inline const TensorWithFormat<Derived,DerivedTraits::Layout,DerivedTraits::NumDimensions, Format> format(const Format& fmt) const {
1018 return TensorWithFormat<Derived,DerivedTraits::Layout,DerivedTraits::NumDimensions, Format>(derived(), fmt);
1019 }
1020
1021 #ifdef EIGEN_READONLY_TENSORBASE_PLUGIN
1022 #include EIGEN_READONLY_TENSORBASE_PLUGIN
1023 #endif
1024
1025 EIGEN_DEVICE_FUNC
1026 EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); }
1027
1028 protected:
1029 template <typename Scalar, int NumIndices, int Options, typename IndexType> friend class Tensor;
1030 template <typename Scalar, typename Dimensions, int Option, typename IndexTypes> friend class TensorFixedSize;
1031 // the Eigen:: prefix is required to workaround a compilation issue with nvcc 9.0
1032 template <typename OtherDerived, int AccessLevel> friend class Eigen::TensorBase;
1033};
1034
1035template<typename Derived, int AccessLevel = internal::accessors_level<Derived>::value>
1036class TensorBase : public TensorBase<Derived, ReadOnlyAccessors> {
1037 public:
1038 typedef TensorBase<Derived, ReadOnlyAccessors> Base;
1039 typedef internal::traits<Derived> DerivedTraits;
1040 typedef typename DerivedTraits::Scalar Scalar;
1041 typedef typename DerivedTraits::Index Index;
1042 typedef Scalar CoeffReturnType;
1043 static constexpr int NumDimensions = DerivedTraits::NumDimensions;
1044
1045 template <typename Scalar, int NumIndices, int Options, typename IndexType> friend class Tensor;
1046 template <typename Scalar, typename Dimensions, int Option, typename IndexTypes> friend class TensorFixedSize;
1047 // the Eigen:: prefix is required to workaround a compilation issue with nvcc 9.0
1048 template <typename OtherDerived, int OtherAccessLevel> friend class Eigen::TensorBase;
1049
1050 EIGEN_DEVICE_FUNC
1051 EIGEN_STRONG_INLINE Derived& setZero() {
1052 return setConstant(Scalar(0));
1053 }
1054 EIGEN_DEVICE_FUNC
1055 EIGEN_STRONG_INLINE Derived& setConstant(const Scalar& val) {
1056 return derived() = this->constant(val);
1057 }
1058 EIGEN_DEVICE_FUNC
1059 EIGEN_STRONG_INLINE Derived& setRandom() {
1060 return derived() = this->random();
1061 }
1062 template <typename RandomGenerator> EIGEN_DEVICE_FUNC
1063 EIGEN_STRONG_INLINE Derived& setRandom() {
1064 return derived() = this->template random<RandomGenerator>();
1065 }
1066
1067 EIGEN_DEVICE_FUNC
1068 EIGEN_STRONG_INLINE Derived& setValues(
1069 const typename internal::Initializer<Derived, NumDimensions>::InitList& vals) {
1070 TensorEvaluator<Derived, DefaultDevice> eval(derived(), DefaultDevice());
1071 internal::initialize_tensor<Derived, NumDimensions>(eval, vals);
1072 return derived();
1073 }
1074
1075 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1076 Derived& operator+=(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) {
1077 return derived() = derived() + other.derived();
1078 }
1079 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1080 Derived& operator-=(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) {
1081 return derived() = derived() - other.derived();
1082 }
1083 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1084 Derived& operator*=(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) {
1085 return derived() = derived() * other.derived();
1086 }
1087 template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1088 Derived& operator/=(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) {
1089 return derived() = derived() / other.derived();
1090 }
1091
1092 template <typename OtherScalar, EIGEN_SFINAE_ENABLE_IF((internal::is_scalar_operand<OtherScalar, Scalar>::value))>
1093 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator+=(OtherScalar other) {
1094 return derived() = derived() + static_cast<Scalar>(other);
1095 }
1096 template <typename OtherScalar, EIGEN_SFINAE_ENABLE_IF((internal::is_scalar_operand<OtherScalar, Scalar>::value))>
1097 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator-=(OtherScalar other) {
1098 return derived() = derived() - static_cast<Scalar>(other);
1099 }
1100 template <typename OtherScalar, EIGEN_SFINAE_ENABLE_IF((internal::is_scalar_operand<OtherScalar, Scalar>::value))>
1101 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator*=(OtherScalar other) {
1102 return derived() = derived() * static_cast<Scalar>(other);
1103 }
1104 template <typename OtherScalar, EIGEN_SFINAE_ENABLE_IF((internal::is_scalar_operand<OtherScalar, Scalar>::value))>
1105 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator/=(OtherScalar other) {
1106 return derived() = derived() / static_cast<Scalar>(other);
1107 }
1108
1109 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1110 const TensorLayoutSwapOp<const Derived>
1111 swap_layout() const {
1112 return TensorLayoutSwapOp<const Derived>(derived());
1113 }
1114 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1115 TensorLayoutSwapOp<Derived>
1116 swap_layout() {
1117 return TensorLayoutSwapOp<Derived>(derived());
1118 }
1119
1120 template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1121 const TensorConcatenationOp<const Axis, const Derived, const OtherDerived>
1122 concatenate(const OtherDerived& other, const Axis& axis) const {
1123 return TensorConcatenationOp<const Axis, const Derived, const OtherDerived>(derived(), other, axis);
1124 }
1125 template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1126 TensorConcatenationOp<const Axis, Derived, OtherDerived>
1127 concatenate(const OtherDerived& other, const Axis& axis) {
1128 return TensorConcatenationOp<const Axis, Derived, OtherDerived>(derived(), other, axis);
1129 }
1130
1131 template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1132 const TensorReshapingOp<const NewDimensions, const Derived>
1133 reshape(const NewDimensions& newDimensions) const {
1134 return TensorReshapingOp<const NewDimensions, const Derived>(derived(), newDimensions);
1135 }
1136 template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1137 TensorReshapingOp<const NewDimensions, Derived>
1138 reshape(const NewDimensions& newDimensions) {
1139 return TensorReshapingOp<const NewDimensions, Derived>(derived(), newDimensions);
1140 }
1141
1142 template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1143 const TensorSlicingOp<const StartIndices, const Sizes, const Derived>
1144 slice(const StartIndices& startIndices, const Sizes& sizes) const {
1145 return TensorSlicingOp<const StartIndices, const Sizes, const Derived>(derived(), startIndices, sizes);
1146 }
1147 template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1148 TensorSlicingOp<const StartIndices, const Sizes, Derived>
1149 slice(const StartIndices& startIndices, const Sizes& sizes) {
1150 return TensorSlicingOp<const StartIndices, const Sizes, Derived>(derived(), startIndices, sizes);
1151 }
1152
1153 template <typename StartIndices, typename StopIndices, typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1154 const TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides, const Derived>
1155 stridedSlice(const StartIndices& startIndices, const StopIndices& stopIndices, const Strides& strides) const {
1156 return TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides,
1157 const Derived>(derived(), startIndices, stopIndices, strides);
1158 }
1159 template <typename StartIndices, typename StopIndices, typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1160 TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides, Derived>
1161 stridedSlice(const StartIndices& startIndices, const StopIndices& stopIndices, const Strides& strides) {
1162 return TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides,
1163 Derived>(derived(), startIndices, stopIndices, strides);
1164 }
1165
1166 template <DenseIndex DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1167 const TensorChippingOp<DimId, const Derived>
1168 chip(const Index offset) const {
1169 EIGEN_STATIC_ASSERT(DimId < Derived::NumDimensions && DimId >= 0, Chip_Dim_out_of_range)
1170 return TensorChippingOp<DimId, const Derived>(derived(), offset, DimId);
1171 }
1172 template <Index DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1173 TensorChippingOp<DimId, Derived>
1174 chip(const Index offset) {
1175 EIGEN_STATIC_ASSERT(DimId < Derived::NumDimensions && DimId >= 0, Chip_Dim_out_of_range)
1176 return TensorChippingOp<DimId, Derived>(derived(), offset, DimId);
1177 }
1178
1179 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1180 const TensorChippingOp<Dynamic, const Derived>
1181 chip(const Index offset, const Index dim) const {
1182 return TensorChippingOp<Dynamic, const Derived>(derived(), offset, dim);
1183 }
1184 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1185 TensorChippingOp<Dynamic, Derived>
1186 chip(const Index offset, const Index dim) {
1187 return TensorChippingOp<Dynamic, Derived>(derived(), offset, dim);
1188 }
1189
1190 template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1191 const TensorReverseOp<const ReverseDimensions, const Derived>
1192 reverse(const ReverseDimensions& rev) const {
1193 return TensorReverseOp<const ReverseDimensions, const Derived>(derived(), rev);
1194 }
1195 template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1196 TensorReverseOp<const ReverseDimensions, Derived>
1197 reverse(const ReverseDimensions& rev) {
1198 return TensorReverseOp<const ReverseDimensions, Derived>(derived(), rev);
1199 }
1200
1201 template <typename Rolls> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1202 const TensorRollOp<const Rolls, const Derived>
1203 roll(const Rolls& roll) const {
1204 return TensorRollOp<const Rolls, const Derived>(derived(), roll);
1205 }
1206 template <typename Rolls> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1207 TensorRollOp<const Rolls, Derived>
1208 roll(const Rolls& roll) {
1209 return TensorRollOp<const Rolls, Derived>(derived(), roll);
1210 }
1211
1212 template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1213 const TensorShufflingOp<const Shuffle, const Derived>
1214 shuffle(const Shuffle& shfl) const {
1215 return TensorShufflingOp<const Shuffle, const Derived>(derived(), shfl);
1216 }
1217 template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1218 TensorShufflingOp<const Shuffle, Derived>
1219 shuffle(const Shuffle& shfl) {
1220 return TensorShufflingOp<const Shuffle, Derived>(derived(), shfl);
1221 }
1222
1223 template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1224 const TensorStridingOp<const Strides, const Derived>
1225 stride(const Strides& strides) const {
1226 return TensorStridingOp<const Strides, const Derived>(derived(), strides);
1227 }
1228 template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1229 TensorStridingOp<const Strides, Derived>
1230 stride(const Strides& strides) {
1231 return TensorStridingOp<const Strides, Derived>(derived(), strides);
1232 }
1233
1234 // Select the device on which to evaluate the expression.
1235 template <typename DeviceType>
1236 TensorDevice<Derived, DeviceType> device(const DeviceType& dev) {
1237 return TensorDevice<Derived, DeviceType>(dev, derived());
1238 }
1239
1240 // Select the async device on which to evaluate the expression.
1241 template <typename DeviceType, typename DoneCallback>
1242 TensorAsyncDevice<Derived, DeviceType, DoneCallback> device(const DeviceType& dev, DoneCallback done) {
1243 return TensorAsyncDevice<Derived, DeviceType, DoneCallback>(dev, derived(), std::move(done));
1244 }
1245
1246 EIGEN_DEVICE_FUNC
1247 EIGEN_STRONG_INLINE Derived& derived() { return *static_cast<Derived*>(this); }
1248 EIGEN_DEVICE_FUNC
1249 EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); }
1250
1251 #ifdef EIGEN_TENSORBASE_PLUGIN
1252 #include EIGEN_TENSORBASE_PLUGIN
1253 #endif
1254
1255 protected:
1256 EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(TensorBase)
1257 EIGEN_DEFAULT_COPY_CONSTRUCTOR(TensorBase)
1258
1259 template<typename OtherDerived> EIGEN_DEVICE_FUNC
1260 EIGEN_STRONG_INLINE Derived& operator=(const OtherDerived& other)
1261 {
1262 typedef TensorAssignOp<Derived, const OtherDerived> Assign;
1263 Assign assign(derived(), other.derived());
1264 internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
1265 return derived();
1266 }
1267};
1268#endif // EIGEN_PARSED_BY_DOXYGEN
1269
1270// Exact matches keep rank-0 reductions' mixed-scalar arithmetic from becoming ambiguous with built-ins.
1271// Namespace scope avoids hidden-friend ADL pollution of NumTraits enum arithmetic on MSVC 14.29.
1272#define EIGEN_FORWARD_SCALAR_BINOP(op, name) \
1273 template <typename OtherScalar, typename Derived, \
1274 EIGEN_SFINAE_ENABLE_IF((internal::is_scalar_operand< \
1275 OtherScalar, typename internal::traits<Derived>::Scalar>::value))> \
1276 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const TensorCwiseUnaryOp< \
1277 internal::bind1st_op<internal::scalar_##name##_op<typename internal::traits<Derived>::Scalar> >, const Derived> \
1278 op(OtherScalar lhs, const TensorBase<Derived, ReadOnlyAccessors>& rhs) { \
1279 typedef typename internal::traits<Derived>::Scalar Scalar; \
1280 return rhs.derived().unaryExpr( \
1281 internal::bind1st_op<internal::scalar_##name##_op<Scalar> >(static_cast<Scalar>(lhs))); \
1282 }
1283EIGEN_FORWARD_SCALAR_BINOP(operator+, sum)
1284EIGEN_FORWARD_SCALAR_BINOP(operator-, difference)
1285EIGEN_FORWARD_SCALAR_BINOP(operator*, product)
1286EIGEN_FORWARD_SCALAR_BINOP(operator/, quotient)
1287#undef EIGEN_FORWARD_SCALAR_BINOP
1288
1289// Scalar-on-the-left comparisons reflect the operator, so scalar < tensor yields the same rank-0
1290// tensor expression as the member tensor > scalar. The scalar operand has no rank-0 conversion the
1291// built-in comparison could use, so without these the left-hand scalar form does not compile.
1292#define EIGEN_FORWARD_SCALAR_CMP_LHS(op, reflected, tag) \
1293 template <typename OtherScalar, typename Derived, \
1294 EIGEN_SFINAE_ENABLE_IF((internal::is_scalar_operand< \
1295 OtherScalar, typename internal::traits<Derived>::Scalar>::value))> \
1296 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const TensorCwiseBinaryOp< \
1297 internal::scalar_cmp_op<typename internal::traits<Derived>::Scalar, \
1298 typename internal::traits<Derived>::Scalar, internal::cmp_##tag>, \
1299 const Derived, \
1300 const TensorCwiseNullaryOp<internal::scalar_constant_op<typename internal::traits<Derived>::Scalar>, \
1301 const Derived> > \
1302 op(OtherScalar lhs, const TensorBase<Derived, ReadOnlyAccessors>& rhs) { \
1303 typedef typename internal::traits<Derived>::Scalar Scalar; \
1304 return rhs.derived().reflected(static_cast<Scalar>(lhs)); \
1305 }
1306EIGEN_FORWARD_SCALAR_CMP_LHS(operator<, operator>, GT)
1307EIGEN_FORWARD_SCALAR_CMP_LHS(operator<=, operator>=, GE)
1308EIGEN_FORWARD_SCALAR_CMP_LHS(operator>, operator<, LT)
1309EIGEN_FORWARD_SCALAR_CMP_LHS(operator>=, operator<=, LE)
1310EIGEN_FORWARD_SCALAR_CMP_LHS(operator==, operator==, EQ)
1311EIGEN_FORWARD_SCALAR_CMP_LHS(operator!=, operator!=, NEQ)
1312#undef EIGEN_FORWARD_SCALAR_CMP_LHS
1313
1314} // end namespace Eigen
1315
1316#endif // EIGEN_TENSOR_TENSOR_BASE_H
The tensor base class.
Definition TensorForwardDeclarations.h:69
ReadOnlyAccessors
Namespace containing all symbols from the Eigen library.
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_bessel_y1_op< typename Derived::Scalar >, const Derived > bessel_y1(const Eigen::ArrayBase< Derived > &x)
Definition BesselFunctionsArrayAPI.h:270
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_bessel_k0e_op< typename Derived::Scalar >, const Derived > bessel_k0e(const Eigen::ArrayBase< Derived > &x)
Definition BesselFunctionsArrayAPI.h:143
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_bessel_k0_op< typename Derived::Scalar >, const Derived > bessel_k0(const Eigen::ArrayBase< Derived > &x)
Definition BesselFunctionsArrayAPI.h:121
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:86
const Eigen::CwiseBinaryOp< Eigen::internal::scalar_igamma_der_a_op< typename Derived::Scalar >, const Derived, const ExponentDerived > igamma_der_a(const Eigen::ArrayBase< Derived > &a, const Eigen::ArrayBase< ExponentDerived > &x)
Definition SpecialFunctionsArrayAPI.h:49
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_bessel_k1_op< typename Derived::Scalar >, const Derived > bessel_k1(const Eigen::ArrayBase< Derived > &x)
Definition BesselFunctionsArrayAPI.h:164
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_bessel_i1_op< typename Derived::Scalar >, const Derived > bessel_i1(const Eigen::ArrayBase< Derived > &x)
Definition BesselFunctionsArrayAPI.h:78
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_bessel_i0e_op< typename Derived::Scalar >, const Derived > bessel_i0e(const Eigen::ArrayBase< Derived > &x)
Definition BesselFunctionsArrayAPI.h:57
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_bessel_i1e_op< typename Derived::Scalar >, const Derived > bessel_i1e(const Eigen::ArrayBase< Derived > &x)
Definition BesselFunctionsArrayAPI.h:100
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_bessel_j1_op< typename Derived::Scalar >, const Derived > bessel_j1(const Eigen::ArrayBase< Derived > &x)
Definition BesselFunctionsArrayAPI.h:249
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_bessel_y0_op< typename Derived::Scalar >, const Derived > bessel_y0(const Eigen::ArrayBase< Derived > &x)
Definition BesselFunctionsArrayAPI.h:228
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_bessel_i0_op< typename Derived::Scalar >, const Derived > bessel_i0(const Eigen::ArrayBase< Derived > &x)
Definition BesselFunctionsArrayAPI.h:35
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_bessel_k1e_op< typename Derived::Scalar >, const Derived > bessel_k1e(const Eigen::ArrayBase< Derived > &x)
Definition BesselFunctionsArrayAPI.h:186
const Eigen::CwiseBinaryOp< Eigen::internal::scalar_gamma_sample_der_alpha_op< typename AlphaDerived::Scalar >, const AlphaDerived, const SampleDerived > gamma_sample_der_alpha(const Eigen::ArrayBase< AlphaDerived > &alpha, const Eigen::ArrayBase< SampleDerived > &sample)
Definition SpecialFunctionsArrayAPI.h:69
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:103
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_bessel_j0_op< typename Derived::Scalar >, const Derived > bessel_j0(const Eigen::ArrayBase< Derived > &x)
Definition BesselFunctionsArrayAPI.h:207
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:31
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:141