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