Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
0005 //
0006 // This Source Code Form is subject to the terms of the Mozilla
0007 // Public License v. 2.0. If a copy of the MPL was not distributed
0008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
0009 
0010 #ifndef EIGEN_CXX11_TENSOR_TENSOR_BASE_H
0011 #define EIGEN_CXX11_TENSOR_TENSOR_BASE_H
0012 
0013 // clang-format off
0014 
0015 namespace Eigen {
0016 
0017 /** \class TensorBase
0018   * \ingroup CXX11_Tensor_Module
0019   *
0020   * \brief The tensor base class.
0021   *
0022   * This class is the common parent of the Tensor and TensorMap class, thus
0023   * making it possible to use either class interchangeably in expressions.
0024   */
0025 #ifndef EIGEN_PARSED_BY_DOXYGEN
0026 // FIXME Doxygen does not like the inheritance with different template parameters
0027 // Since there is no doxygen documentation inside, we disable it for now
0028 template<typename Derived>
0029 class TensorBase<Derived, ReadOnlyAccessors>
0030 {
0031   public:
0032     typedef internal::traits<Derived> DerivedTraits;
0033     typedef typename DerivedTraits::Scalar Scalar;
0034     typedef typename DerivedTraits::Index Index;
0035     typedef typename internal::remove_const<Scalar>::type CoeffReturnType;
0036     static const int NumDimensions = DerivedTraits::NumDimensions;
0037 
0038     // Generic nullary operation support.
0039     template <typename CustomNullaryOp> EIGEN_DEVICE_FUNC
0040     EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<CustomNullaryOp, const Derived>
0041     nullaryExpr(const CustomNullaryOp& func) const {
0042       return TensorCwiseNullaryOp<CustomNullaryOp, const Derived>(derived(), func);
0043     }
0044 
0045     // Coefficient-wise nullary operators
0046     EIGEN_DEVICE_FUNC
0047     EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived>
0048     constant(const Scalar& value) const {
0049       return nullaryExpr(internal::scalar_constant_op<Scalar>(value));
0050     }
0051 
0052     EIGEN_DEVICE_FUNC
0053     EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<internal::UniformRandomGenerator<Scalar>, const Derived>
0054     random() const {
0055       return nullaryExpr(internal::UniformRandomGenerator<Scalar>());
0056     }
0057     template <typename RandomGenerator> EIGEN_DEVICE_FUNC
0058     EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<RandomGenerator, const Derived>
0059     random(const RandomGenerator& gen = RandomGenerator()) const {
0060       return nullaryExpr(gen);
0061     }
0062 
0063     // Tensor generation
0064     template <typename Generator> EIGEN_DEVICE_FUNC
0065     EIGEN_STRONG_INLINE const TensorGeneratorOp<Generator, const Derived>
0066     generate(const Generator& generator) const {
0067       return TensorGeneratorOp<Generator, const Derived>(derived(), generator);
0068     }
0069 
0070     // Generic unary operation support.
0071     template <typename CustomUnaryOp> EIGEN_DEVICE_FUNC
0072     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<CustomUnaryOp, const Derived>
0073     unaryExpr(const CustomUnaryOp& func) const {
0074       return TensorCwiseUnaryOp<CustomUnaryOp, const Derived>(derived(), func);
0075     }
0076 
0077     // Coefficient-wise unary operators
0078     EIGEN_DEVICE_FUNC
0079     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const Derived>
0080     operator-() const {
0081       return unaryExpr(internal::scalar_opposite_op<Scalar>());
0082     }
0083 
0084     EIGEN_DEVICE_FUNC
0085     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sqrt_op<Scalar>, const Derived>
0086     sqrt() const {
0087       return unaryExpr(internal::scalar_sqrt_op<Scalar>());
0088     }
0089 
0090     EIGEN_DEVICE_FUNC
0091     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sign_op<Scalar>, const Derived>
0092     sign() const {
0093       return unaryExpr(internal::scalar_sign_op<Scalar>());
0094     }
0095 
0096     EIGEN_DEVICE_FUNC
0097     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_rsqrt_op<Scalar>, const Derived>
0098     rsqrt() const {
0099       return unaryExpr(internal::scalar_rsqrt_op<Scalar>());
0100     }
0101 
0102     EIGEN_DEVICE_FUNC
0103     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_square_op<Scalar>, const Derived>
0104     square() const {
0105       return unaryExpr(internal::scalar_square_op<Scalar>());
0106     }
0107 
0108     EIGEN_DEVICE_FUNC
0109     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_cube_op<Scalar>, const Derived>
0110     cube() const {
0111       return unaryExpr(internal::scalar_cube_op<Scalar>());
0112     }
0113 
0114     EIGEN_DEVICE_FUNC
0115     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const Derived>
0116     inverse() const {
0117       return unaryExpr(internal::scalar_inverse_op<Scalar>());
0118     }
0119 
0120     EIGEN_DEVICE_FUNC
0121     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_tanh_op<Scalar>, const Derived>
0122     tanh() const {
0123       return unaryExpr(internal::scalar_tanh_op<Scalar>());
0124     }
0125 
0126     EIGEN_DEVICE_FUNC
0127     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_lgamma_op<Scalar>, const Derived>
0128     lgamma() const {
0129       return unaryExpr(internal::scalar_lgamma_op<Scalar>());
0130     }
0131 
0132     EIGEN_DEVICE_FUNC
0133     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_digamma_op<Scalar>, const Derived>
0134     digamma() const {
0135       return unaryExpr(internal::scalar_digamma_op<Scalar>());
0136     }
0137 
0138     EIGEN_DEVICE_FUNC
0139     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_i0_op<Scalar>, const Derived>
0140     bessel_i0() const {
0141       return unaryExpr(internal::scalar_bessel_i0_op<Scalar>());
0142     }
0143 
0144     EIGEN_DEVICE_FUNC
0145     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_i0e_op<Scalar>, const Derived>
0146     bessel_i0e() const {
0147       return unaryExpr(internal::scalar_bessel_i0e_op<Scalar>());
0148     }
0149 
0150     EIGEN_DEVICE_FUNC
0151     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_i1_op<Scalar>, const Derived>
0152     bessel_i1() const {
0153       return unaryExpr(internal::scalar_bessel_i1_op<Scalar>());
0154     }
0155 
0156     EIGEN_DEVICE_FUNC
0157     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_i1e_op<Scalar>, const Derived>
0158     bessel_i1e() const {
0159       return unaryExpr(internal::scalar_bessel_i1e_op<Scalar>());
0160     }
0161 
0162     EIGEN_DEVICE_FUNC
0163     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_j0_op<Scalar>, const Derived>
0164     bessel_j0() const {
0165       return unaryExpr(internal::scalar_bessel_j0_op<Scalar>());
0166     }
0167 
0168     EIGEN_DEVICE_FUNC
0169     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_y0_op<Scalar>, const Derived>
0170     bessel_y0() const {
0171       return unaryExpr(internal::scalar_bessel_y0_op<Scalar>());
0172     }
0173 
0174     EIGEN_DEVICE_FUNC
0175     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_j1_op<Scalar>, const Derived>
0176     bessel_j1() const {
0177       return unaryExpr(internal::scalar_bessel_j1_op<Scalar>());
0178     }
0179 
0180     EIGEN_DEVICE_FUNC
0181     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_y1_op<Scalar>, const Derived>
0182     bessel_y1() const {
0183       return unaryExpr(internal::scalar_bessel_y1_op<Scalar>());
0184     }
0185 
0186     EIGEN_DEVICE_FUNC
0187     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_k0_op<Scalar>, const Derived>
0188     bessel_k0() const {
0189       return unaryExpr(internal::scalar_bessel_k0_op<Scalar>());
0190     }
0191 
0192     EIGEN_DEVICE_FUNC
0193     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_k0e_op<Scalar>, const Derived>
0194     bessel_k0e() const {
0195       return unaryExpr(internal::scalar_bessel_k0e_op<Scalar>());
0196     }
0197 
0198     EIGEN_DEVICE_FUNC
0199     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_k1_op<Scalar>, const Derived>
0200     bessel_k1() const {
0201       return unaryExpr(internal::scalar_bessel_k1_op<Scalar>());
0202     }
0203 
0204     EIGEN_DEVICE_FUNC
0205     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_k1e_op<Scalar>, const Derived>
0206     bessel_k1e() const {
0207       return unaryExpr(internal::scalar_bessel_k1e_op<Scalar>());
0208     }
0209 
0210     // igamma(a = this, x = other)
0211     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0212     const TensorCwiseBinaryOp<internal::scalar_igamma_op<Scalar>, const Derived, const OtherDerived>
0213     igamma(const OtherDerived& other) const {
0214       return binaryExpr(other.derived(), internal::scalar_igamma_op<Scalar>());
0215     }
0216 
0217     // igamma_der_a(a = this, x = other)
0218     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0219     const TensorCwiseBinaryOp<internal::scalar_igamma_der_a_op<Scalar>, const Derived, const OtherDerived>
0220     igamma_der_a(const OtherDerived& other) const {
0221       return binaryExpr(other.derived(), internal::scalar_igamma_der_a_op<Scalar>());
0222     }
0223 
0224     // gamma_sample_der_alpha(alpha = this, sample = other)
0225     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0226     const TensorCwiseBinaryOp<internal::scalar_gamma_sample_der_alpha_op<Scalar>, const Derived, const OtherDerived>
0227     gamma_sample_der_alpha(const OtherDerived& other) const {
0228       return binaryExpr(other.derived(), internal::scalar_gamma_sample_der_alpha_op<Scalar>());
0229     }
0230 
0231     // igammac(a = this, x = other)
0232     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0233     const TensorCwiseBinaryOp<internal::scalar_igammac_op<Scalar>, const Derived, const OtherDerived>
0234     igammac(const OtherDerived& other) const {
0235       return binaryExpr(other.derived(), internal::scalar_igammac_op<Scalar>());
0236     }
0237 
0238     // zeta(x = this, q = other)
0239     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0240     const TensorCwiseBinaryOp<internal::scalar_zeta_op<Scalar>, const Derived, const OtherDerived>
0241     zeta(const OtherDerived& other) const {
0242       return binaryExpr(other.derived(), internal::scalar_zeta_op<Scalar>());
0243     }
0244 
0245     // polygamma(n = this, x = other)
0246     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0247     const TensorCwiseBinaryOp<internal::scalar_polygamma_op<Scalar>, const Derived, const OtherDerived>
0248     polygamma(const OtherDerived& other) const {
0249       return binaryExpr(other.derived(), internal::scalar_polygamma_op<Scalar>());
0250     }
0251 
0252     EIGEN_DEVICE_FUNC
0253     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_erf_op<Scalar>, const Derived>
0254     erf() const {
0255       return unaryExpr(internal::scalar_erf_op<Scalar>());
0256     }
0257 
0258     EIGEN_DEVICE_FUNC
0259     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_erfc_op<Scalar>, const Derived>
0260     erfc() const {
0261       return unaryExpr(internal::scalar_erfc_op<Scalar>());
0262     }
0263 
0264     EIGEN_DEVICE_FUNC
0265     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_ndtri_op<Scalar>, const Derived>
0266     ndtri() const {
0267       return unaryExpr(internal::scalar_ndtri_op<Scalar>());
0268     }
0269 
0270     EIGEN_DEVICE_FUNC
0271     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_logistic_op<Scalar>, const Derived>
0272     sigmoid() const {
0273       return unaryExpr(internal::scalar_logistic_op<Scalar>());
0274     }
0275 
0276     EIGEN_DEVICE_FUNC
0277     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_exp_op<Scalar>, const Derived>
0278     exp() const {
0279       return unaryExpr(internal::scalar_exp_op<Scalar>());
0280     }
0281 
0282     EIGEN_DEVICE_FUNC
0283     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_expm1_op<Scalar>, const Derived>
0284     expm1() const {
0285       return unaryExpr(internal::scalar_expm1_op<Scalar>());
0286     }
0287 
0288     EIGEN_DEVICE_FUNC
0289     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log_op<Scalar>, const Derived>
0290     log() const {
0291       return unaryExpr(internal::scalar_log_op<Scalar>());
0292     }
0293 
0294     EIGEN_DEVICE_FUNC
0295     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log1p_op<Scalar>, const Derived>
0296     log1p() const {
0297       return unaryExpr(internal::scalar_log1p_op<Scalar>());
0298     }
0299 
0300     EIGEN_DEVICE_FUNC
0301     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log2_op<Scalar>, const Derived>
0302     log2() const {
0303       return unaryExpr(internal::scalar_log2_op<Scalar>());
0304     }
0305 
0306     EIGEN_DEVICE_FUNC
0307     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_abs_op<Scalar>, const Derived>
0308     abs() const {
0309       return unaryExpr(internal::scalar_abs_op<Scalar>());
0310     }
0311 
0312     EIGEN_DEVICE_FUNC
0313     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_clamp_op<Scalar>, const Derived>
0314     clip(Scalar min, Scalar max) const {
0315       return unaryExpr(internal::scalar_clamp_op<Scalar>(min, max));
0316     }
0317 
0318     EIGEN_DEVICE_FUNC
0319     EIGEN_STRONG_INLINE const typename internal::conditional<NumTraits<CoeffReturnType>::IsComplex,
0320                                                              TensorCwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, const Derived>,
0321                                                              Derived>::type
0322     conjugate() const {
0323       return choose(Cond<NumTraits<CoeffReturnType>::IsComplex>(), unaryExpr(internal::scalar_conjugate_op<Scalar>()), derived());
0324     }
0325 
0326     EIGEN_DEVICE_FUNC
0327     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_pow_op<Scalar,Scalar> >, const Derived>
0328     pow(Scalar exponent) const {
0329       return unaryExpr(internal::bind2nd_op<internal::scalar_pow_op<Scalar,Scalar> >(exponent));
0330     }
0331 
0332     EIGEN_DEVICE_FUNC
0333     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_real_op<Scalar>, const Derived>
0334     real() const {
0335       return unaryExpr(internal::scalar_real_op<Scalar>());
0336     }
0337 
0338     EIGEN_DEVICE_FUNC
0339     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_imag_op<Scalar>, const Derived>
0340     imag() const {
0341       return unaryExpr(internal::scalar_imag_op<Scalar>());
0342     }
0343 
0344     EIGEN_DEVICE_FUNC
0345     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_sum_op<Scalar,Scalar> >, const Derived>
0346     operator+ (Scalar rhs) const {
0347       return unaryExpr(internal::bind2nd_op<internal::scalar_sum_op<Scalar,Scalar> >(rhs));
0348     }
0349 
0350     EIGEN_DEVICE_FUNC
0351     EIGEN_STRONG_INLINE friend
0352     const TensorCwiseUnaryOp<internal::bind1st_op<internal::scalar_sum_op<Scalar> >, const Derived>
0353     operator+ (Scalar lhs, const Derived& rhs) {
0354       return rhs.unaryExpr(internal::bind1st_op<internal::scalar_sum_op<Scalar> >(lhs));
0355     }
0356 
0357     EIGEN_DEVICE_FUNC
0358     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_difference_op<Scalar,Scalar> >, const Derived>
0359     operator- (Scalar rhs) const {
0360       EIGEN_STATIC_ASSERT((NumTraits<Scalar>::IsSigned || internal::is_same<Scalar, const std::complex<float> >::value), YOU_MADE_A_PROGRAMMING_MISTAKE);
0361       return unaryExpr(internal::bind2nd_op<internal::scalar_difference_op<Scalar,Scalar> >(rhs));
0362     }
0363 
0364     EIGEN_DEVICE_FUNC
0365     EIGEN_STRONG_INLINE friend
0366     const TensorCwiseUnaryOp<internal::bind1st_op<internal::scalar_difference_op<Scalar> >, const Derived>
0367     operator- (Scalar lhs, const Derived& rhs) {
0368       return rhs.unaryExpr(internal::bind1st_op<internal::scalar_difference_op<Scalar> >(lhs));
0369     }
0370 
0371     EIGEN_DEVICE_FUNC
0372     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_product_op<Scalar,Scalar> >, const Derived>
0373     operator* (Scalar rhs) const {
0374       return unaryExpr(internal::bind2nd_op<internal::scalar_product_op<Scalar,Scalar> >(rhs));
0375     }
0376 
0377     EIGEN_DEVICE_FUNC
0378     EIGEN_STRONG_INLINE friend
0379     const TensorCwiseUnaryOp<internal::bind1st_op<internal::scalar_product_op<Scalar> >, const Derived>
0380     operator* (Scalar lhs, const Derived& rhs) {
0381       return rhs.unaryExpr(internal::bind1st_op<internal::scalar_product_op<Scalar> >(lhs));
0382     }
0383 
0384     EIGEN_DEVICE_FUNC
0385     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_quotient_op<Scalar,Scalar> >, const Derived>
0386     operator/ (Scalar rhs) const {
0387       return unaryExpr(internal::bind2nd_op<internal::scalar_quotient_op<Scalar,Scalar> >(rhs));
0388     }
0389 
0390     EIGEN_DEVICE_FUNC
0391     EIGEN_STRONG_INLINE friend
0392     const TensorCwiseUnaryOp<internal::bind1st_op<internal::scalar_quotient_op<Scalar> >, const Derived>
0393     operator/ (Scalar lhs, const Derived& rhs) {
0394       return rhs.unaryExpr(internal::bind1st_op<internal::scalar_quotient_op<Scalar> >(lhs));
0395     }
0396 
0397     EIGEN_DEVICE_FUNC
0398     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_mod_op<Scalar>, const Derived>
0399     operator% (Scalar rhs) const {
0400       EIGEN_STATIC_ASSERT(NumTraits<Scalar>::IsInteger, YOU_MADE_A_PROGRAMMING_MISTAKE_TRY_MOD);
0401       return unaryExpr(internal::scalar_mod_op<Scalar>(rhs));
0402     }
0403 
0404     template <int NanPropagation=PropagateFast>
0405     EIGEN_DEVICE_FUNC
0406         EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar,NanPropagation>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
0407     cwiseMax(Scalar threshold) const {
0408       return cwiseMax<NanPropagation>(constant(threshold));
0409     }
0410 
0411     template <int NanPropagation=PropagateFast>
0412     EIGEN_DEVICE_FUNC
0413         EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar,NanPropagation>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
0414     cwiseMin(Scalar threshold) const {
0415       return cwiseMin<NanPropagation>(constant(threshold));
0416     }
0417 
0418     template<typename NewType>
0419     EIGEN_DEVICE_FUNC
0420     EIGEN_STRONG_INLINE const typename internal::conditional<internal::is_same<NewType, CoeffReturnType>::value,
0421                                                              Derived,
0422                                                              TensorConversionOp<NewType, const Derived> >::type
0423     cast() const {
0424       return choose(Cond<internal::is_same<NewType, CoeffReturnType>::value>(), derived(), TensorConversionOp<NewType, const Derived>(derived()));
0425     }
0426 
0427     EIGEN_DEVICE_FUNC
0428     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_round_op<Scalar>, const Derived>
0429     round() const {
0430       return unaryExpr(internal::scalar_round_op<Scalar>());
0431     }
0432 
0433     EIGEN_DEVICE_FUNC
0434     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_rint_op<Scalar>, const Derived>
0435     rint() const {
0436       return unaryExpr(internal::scalar_rint_op<Scalar>());
0437     }
0438 
0439     EIGEN_DEVICE_FUNC
0440     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_ceil_op<Scalar>, const Derived>
0441     ceil() const {
0442       return unaryExpr(internal::scalar_ceil_op<Scalar>());
0443     }
0444 
0445     EIGEN_DEVICE_FUNC
0446     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_floor_op<Scalar>, const Derived>
0447     floor() const {
0448       return unaryExpr(internal::scalar_floor_op<Scalar>());
0449     }
0450 
0451     // Generic binary operation support.
0452     template <typename CustomBinaryOp, typename OtherDerived> EIGEN_DEVICE_FUNC
0453     EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>
0454     binaryExpr(const OtherDerived& other, const CustomBinaryOp& func) const {
0455       return TensorCwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>(derived(), other, func);
0456     }
0457 
0458     // Coefficient-wise binary operators.
0459     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0460     const TensorCwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const OtherDerived>
0461     operator+(const OtherDerived& other) const {
0462       return binaryExpr(other.derived(), internal::scalar_sum_op<Scalar>());
0463     }
0464 
0465     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0466     const TensorCwiseBinaryOp<internal::scalar_difference_op<Scalar>, const Derived, const OtherDerived>
0467     operator-(const OtherDerived& other) const {
0468       return binaryExpr(other.derived(), internal::scalar_difference_op<Scalar>());
0469     }
0470 
0471     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0472     const TensorCwiseBinaryOp<internal::scalar_product_op<Scalar>, const Derived, const OtherDerived>
0473     operator*(const OtherDerived& other) const {
0474       return binaryExpr(other.derived(), internal::scalar_product_op<Scalar>());
0475     }
0476 
0477     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0478     const TensorCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, const Derived, const OtherDerived>
0479     operator/(const OtherDerived& other) const {
0480       return binaryExpr(other.derived(), internal::scalar_quotient_op<Scalar>());
0481     }
0482 
0483   template<int NaNPropagation=PropagateFast, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0484       const TensorCwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar, NaNPropagation>, const Derived, const OtherDerived>
0485     cwiseMax(const OtherDerived& other) const {
0486     return binaryExpr(other.derived(), internal::scalar_max_op<Scalar,Scalar, NaNPropagation>());
0487     }
0488 
0489   template<int NaNPropagation=PropagateFast, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0490     const TensorCwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar, NaNPropagation>, const Derived, const OtherDerived>
0491     cwiseMin(const OtherDerived& other) const {
0492       return binaryExpr(other.derived(), internal::scalar_min_op<Scalar,Scalar, NaNPropagation>());
0493     }
0494 
0495     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0496     const TensorCwiseBinaryOp<internal::scalar_boolean_and_op, const Derived, const OtherDerived>
0497     operator&&(const OtherDerived& other) const {
0498       return binaryExpr(other.derived(), internal::scalar_boolean_and_op());
0499     }
0500 
0501     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0502     const TensorCwiseBinaryOp<internal::scalar_boolean_or_op, const Derived, const OtherDerived>
0503     operator||(const OtherDerived& other) const {
0504       return binaryExpr(other.derived(), internal::scalar_boolean_or_op());
0505     }
0506 
0507     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0508     const TensorCwiseBinaryOp<internal::scalar_boolean_xor_op, const Derived, const OtherDerived>
0509     operator^(const OtherDerived& other) const {
0510       return binaryExpr(other.derived(), internal::scalar_boolean_xor_op());
0511     }
0512 
0513     // Comparisons and tests.
0514     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0515     const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LT>, const Derived, const OtherDerived>
0516     operator<(const OtherDerived& other) const {
0517       return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LT>());
0518     }
0519     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0520     const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LE>, const Derived, const OtherDerived>
0521     operator<=(const OtherDerived& other) const {
0522       return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LE>());
0523     }
0524     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0525     const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GT>, const Derived, const OtherDerived>
0526     operator>(const OtherDerived& other) const {
0527       return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GT>());
0528     }
0529     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0530     const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GE>, const Derived, const OtherDerived>
0531     operator>=(const OtherDerived& other) const {
0532       return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GE>());
0533     }
0534 
0535     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0536     const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_EQ>, const Derived, const OtherDerived>
0537     operator==(const OtherDerived& other) const {
0538       return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_EQ>());
0539     }
0540 
0541     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0542     const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_NEQ>, const Derived, const OtherDerived>
0543     operator!=(const OtherDerived& other) const {
0544       return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_NEQ>());
0545     }
0546 
0547     // comparisons and tests for Scalars
0548     EIGEN_DEVICE_FUNC
0549     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> >
0550     operator<(Scalar threshold) const {
0551       return operator<(constant(threshold));
0552     }
0553     EIGEN_DEVICE_FUNC
0554     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> >
0555     operator<=(Scalar threshold) const {
0556       return operator<=(constant(threshold));
0557     }
0558     EIGEN_DEVICE_FUNC
0559     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> >
0560     operator>(Scalar threshold) const {
0561       return operator>(constant(threshold));
0562     }
0563     EIGEN_DEVICE_FUNC
0564     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> >
0565     operator>=(Scalar threshold) const {
0566       return operator>=(constant(threshold));
0567     }
0568     EIGEN_DEVICE_FUNC
0569     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> >
0570     operator==(Scalar threshold) const {
0571       return operator==(constant(threshold));
0572     }
0573     EIGEN_DEVICE_FUNC
0574     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> >
0575     operator!=(Scalar threshold) const {
0576       return operator!=(constant(threshold));
0577     }
0578 
0579     // Checks
0580     EIGEN_DEVICE_FUNC
0581     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_isnan_op<Scalar>, const Derived>
0582     (isnan)() const {
0583       return unaryExpr(internal::scalar_isnan_op<Scalar>());
0584     }
0585     EIGEN_DEVICE_FUNC
0586     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_isinf_op<Scalar>, const Derived>
0587     (isinf)() const {
0588       return unaryExpr(internal::scalar_isinf_op<Scalar>());
0589     }
0590     EIGEN_DEVICE_FUNC
0591     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_isfinite_op<Scalar>, const Derived>
0592     (isfinite)() const {
0593       return unaryExpr(internal::scalar_isfinite_op<Scalar>());
0594     }
0595 
0596     // Coefficient-wise ternary operators.
0597     template<typename ThenDerived, typename ElseDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0598     const TensorSelectOp<const Derived, const ThenDerived, const ElseDerived>
0599     select(const ThenDerived& thenTensor, const ElseDerived& elseTensor) const {
0600       return TensorSelectOp<const Derived, const ThenDerived, const ElseDerived>(derived(), thenTensor.derived(), elseTensor.derived());
0601     }
0602 
0603     // Contractions.
0604     typedef Eigen::IndexPair<Index> DimensionPair;
0605 
0606     template<typename OtherDerived, typename Dimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0607     const TensorContractionOp<const Dimensions, const Derived, const OtherDerived, const NoOpOutputKernel>
0608     contract(const OtherDerived& other, const Dimensions& dims) const {
0609       return TensorContractionOp<const Dimensions, const Derived, const OtherDerived, const NoOpOutputKernel>(derived(), other.derived(), dims);
0610     }
0611 
0612     template<typename OtherDerived, typename Dimensions, typename OutputKernel> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0613     const TensorContractionOp<const Dimensions, const Derived, const OtherDerived, const OutputKernel>
0614     contract(const OtherDerived& other, const Dimensions& dims, const OutputKernel& output_kernel) const {
0615       return TensorContractionOp<const Dimensions, const Derived, const OtherDerived, const OutputKernel>(derived(), other.derived(), dims, output_kernel);
0616     }
0617 
0618     // Convolutions.
0619     template<typename KernelDerived, typename Dimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0620     const TensorConvolutionOp<const Dimensions, const Derived, const KernelDerived>
0621     convolve(const KernelDerived& kernel, const Dimensions& dims) const {
0622       return TensorConvolutionOp<const Dimensions, const Derived, const KernelDerived>(derived(), kernel.derived(), dims);
0623     }
0624 
0625     // Fourier transforms
0626     template <int FFTDataType, int FFTDirection, typename FFT> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0627     const TensorFFTOp<const FFT, const Derived, FFTDataType, FFTDirection>
0628     fft(const FFT& dims) const {
0629       return TensorFFTOp<const FFT, const Derived, FFTDataType, FFTDirection>(derived(), dims);
0630     }
0631 
0632     // Scan.
0633     typedef TensorScanOp<internal::SumReducer<CoeffReturnType>, const Derived> TensorScanSumOp;
0634     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0635     const TensorScanSumOp
0636     cumsum(const Index& axis, bool exclusive = false) const {
0637       return TensorScanSumOp(derived(), axis, exclusive);
0638     }
0639 
0640     typedef TensorScanOp<internal::ProdReducer<CoeffReturnType>, const Derived> TensorScanProdOp;
0641     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0642     const TensorScanProdOp
0643     cumprod(const Index& axis, bool exclusive = false) const {
0644       return TensorScanProdOp(derived(), axis, exclusive);
0645     }
0646 
0647     template <typename Reducer>
0648     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0649     const TensorScanOp<Reducer, const Derived>
0650     scan(const Index& axis, const Reducer& reducer, bool exclusive = false) const {
0651       return TensorScanOp<Reducer, const Derived>(derived(), axis, exclusive, reducer);
0652     }
0653 
0654     // Reductions.
0655     template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0656     const TensorReductionOp<internal::SumReducer<CoeffReturnType>, const Dims, const Derived>
0657     sum(const Dims& dims) const {
0658       return TensorReductionOp<internal::SumReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::SumReducer<CoeffReturnType>());
0659     }
0660 
0661     const TensorReductionOp<internal::SumReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
0662     sum() const {
0663       DimensionList<Index, NumDimensions> in_dims;
0664       return TensorReductionOp<internal::SumReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::SumReducer<CoeffReturnType>());
0665     }
0666 
0667     template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0668     const TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const Dims, const Derived>
0669     mean(const Dims& dims) const {
0670       return TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::MeanReducer<CoeffReturnType>());
0671     }
0672 
0673     const TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
0674     mean() const {
0675       DimensionList<Index, NumDimensions> in_dims;
0676       return TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MeanReducer<CoeffReturnType>());
0677     }
0678 
0679     template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0680     const TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const Dims, const Derived>
0681     prod(const Dims& dims) const {
0682       return TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::ProdReducer<CoeffReturnType>());
0683     }
0684 
0685     const TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
0686     prod() const {
0687       DimensionList<Index, NumDimensions> in_dims;
0688       return TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::ProdReducer<CoeffReturnType>());
0689     }
0690 
0691     template <typename Dims,int NanPropagation=PropagateFast> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0692     const TensorReductionOp<internal::MaxReducer<CoeffReturnType,NanPropagation>, const Dims, const Derived>
0693     maximum(const Dims& dims) const {
0694       return TensorReductionOp<internal::MaxReducer<CoeffReturnType,NanPropagation>, const Dims, const Derived>(derived(), dims, internal::MaxReducer<CoeffReturnType,NanPropagation>());
0695     }
0696 
0697     template <int NanPropagation=PropagateFast>
0698     const TensorReductionOp<internal::MaxReducer<CoeffReturnType,NanPropagation>, const DimensionList<Index, NumDimensions>, const Derived>
0699     maximum() const {
0700       DimensionList<Index, NumDimensions> in_dims;
0701       return TensorReductionOp<internal::MaxReducer<CoeffReturnType,NanPropagation>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MaxReducer<CoeffReturnType,NanPropagation>());
0702     }
0703 
0704     template <typename Dims,int NanPropagation=PropagateFast> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0705     const TensorReductionOp<internal::MinReducer<CoeffReturnType,NanPropagation>, const Dims, const Derived>
0706     minimum(const Dims& dims) const {
0707       return TensorReductionOp<internal::MinReducer<CoeffReturnType,NanPropagation>, const Dims, const Derived>(derived(), dims, internal::MinReducer<CoeffReturnType,NanPropagation>());
0708     }
0709 
0710     template <int NanPropagation=PropagateFast>
0711     const TensorReductionOp<internal::MinReducer<CoeffReturnType,NanPropagation>, const DimensionList<Index, NumDimensions>, const Derived>
0712     minimum() const {
0713       DimensionList<Index, NumDimensions> in_dims;
0714       return TensorReductionOp<internal::MinReducer<CoeffReturnType,NanPropagation>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MinReducer<CoeffReturnType,NanPropagation>());
0715     }
0716 
0717     template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0718     const TensorReductionOp<internal::AndReducer, const Dims, const typename internal::conditional<internal::is_same<bool, CoeffReturnType>::value, Derived, TensorConversionOp<bool, const Derived> >::type >
0719     all(const Dims& dims) const {
0720       return cast<bool>().reduce(dims, internal::AndReducer());
0721     }
0722 
0723     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0724     const TensorReductionOp<internal::AndReducer, const DimensionList<Index, NumDimensions>, const typename internal::conditional<internal::is_same<bool, CoeffReturnType>::value, Derived, TensorConversionOp<bool, const Derived> >::type >
0725     all() const {
0726       DimensionList<Index, NumDimensions> in_dims;
0727       return cast<bool>().reduce(in_dims, internal::AndReducer());
0728     }
0729 
0730     template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0731     const TensorReductionOp<internal::OrReducer, const Dims, const typename internal::conditional<internal::is_same<bool, CoeffReturnType>::value, Derived, TensorConversionOp<bool, const Derived> >::type >
0732     any(const Dims& dims) const {
0733       return cast<bool>().reduce(dims, internal::OrReducer());
0734     }
0735 
0736     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0737     const TensorReductionOp<internal::OrReducer, const DimensionList<Index, NumDimensions>, const typename internal::conditional<internal::is_same<bool, CoeffReturnType>::value, Derived, TensorConversionOp<bool, const Derived> >::type >
0738     any() const {
0739       DimensionList<Index, NumDimensions> in_dims;
0740       return cast<bool>().reduce(in_dims, internal::OrReducer());
0741     }
0742 
0743    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0744     const TensorTupleReducerOp<
0745       internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
0746       const array<Index, NumDimensions>, const Derived>
0747     argmax() const {
0748       array<Index, NumDimensions> in_dims;
0749       for (Index d = 0; d < NumDimensions; ++d) in_dims[d] = d;
0750       return TensorTupleReducerOp<
0751         internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
0752         const array<Index, NumDimensions>,
0753         const Derived>(derived(), internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >(), -1, in_dims);
0754     }
0755 
0756     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0757     const TensorTupleReducerOp<
0758       internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
0759       const array<Index, NumDimensions>, const Derived>
0760     argmin() const {
0761       array<Index, NumDimensions> in_dims;
0762       for (Index d = 0; d < NumDimensions; ++d) in_dims[d] = d;
0763       return TensorTupleReducerOp<
0764         internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
0765         const array<Index, NumDimensions>,
0766         const Derived>(derived(), internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >(), -1, in_dims);
0767     }
0768 
0769     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0770     const TensorTupleReducerOp<
0771       internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
0772       const array<Index, 1>, const Derived>
0773     argmax(const Index return_dim) const {
0774       array<Index, 1> in_dims;
0775       in_dims[0] = return_dim;
0776       return TensorTupleReducerOp<
0777         internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
0778         const array<Index, 1>,
0779         const Derived>(derived(), internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >(), return_dim, in_dims);
0780     }
0781 
0782     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0783     const TensorTupleReducerOp<
0784       internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
0785       const array<Index, 1>, const Derived>
0786     argmin(const Index return_dim) const {
0787       array<Index, 1> in_dims;
0788       in_dims[0] = return_dim;
0789       return TensorTupleReducerOp<
0790         internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
0791         const array<Index, 1>,
0792         const Derived>(derived(), internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >(), return_dim, in_dims);
0793     }
0794 
0795     template <typename Reducer, typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0796     const TensorReductionOp<Reducer, const Dims, const Derived>
0797     reduce(const Dims& dims, const Reducer& reducer) const {
0798       return TensorReductionOp<Reducer, const Dims, const Derived>(derived(), dims, reducer);
0799     }
0800 
0801     template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0802     const TensorTraceOp<const Dims, const Derived>
0803     trace(const Dims& dims) const {
0804       return TensorTraceOp<const Dims, const Derived>(derived(), dims);
0805     }
0806 
0807     const TensorTraceOp<const DimensionList<Index, NumDimensions>, const Derived>
0808     trace() const {
0809       DimensionList<Index, NumDimensions> in_dims;
0810       return TensorTraceOp<const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims);
0811     }
0812 
0813     template <typename Broadcast> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0814     const TensorBroadcastingOp<const Broadcast, const Derived>
0815     broadcast(const Broadcast& bcast) const {
0816       return TensorBroadcastingOp<const Broadcast, const Derived>(derived(), bcast);
0817     }
0818 
0819     template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0820     const TensorConcatenationOp<Axis, const Derived, const OtherDerived>
0821     concatenate(const OtherDerived& other, Axis axis) const {
0822       return TensorConcatenationOp<Axis, const Derived, const OtherDerived>(derived(), other.derived(), axis);
0823     }
0824 
0825     template <typename PatchDims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0826     const TensorPatchOp<const PatchDims, const Derived>
0827     extract_patches(const PatchDims& patch_dims) const {
0828       return TensorPatchOp<const PatchDims, const Derived>(derived(), patch_dims);
0829     }
0830 
0831     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0832     const TensorImagePatchOp<Dynamic, Dynamic, const Derived>
0833     extract_image_patches(const Index patch_rows = 1, const Index patch_cols = 1,
0834                           const Index row_stride = 1, const Index col_stride = 1,
0835                           const Index in_row_stride = 1, const Index in_col_stride = 1,
0836                           const PaddingType padding_type = PADDING_SAME, const Scalar padding_value = Scalar(0)) const {
0837       return TensorImagePatchOp<Dynamic, Dynamic, const Derived>(derived(), patch_rows, patch_cols, row_stride, col_stride,
0838                                                                  in_row_stride, in_col_stride, 1, 1, padding_type, padding_value);
0839     }
0840 
0841     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0842     const TensorImagePatchOp<Dynamic, Dynamic, const Derived>
0843     extract_image_patches(const Index patch_rows, const Index patch_cols,
0844                           const Index row_stride, const Index col_stride,
0845                           const Index in_row_stride, const Index in_col_stride,
0846                           const Index row_inflate_stride, const Index col_inflate_stride,
0847                           const Index padding_top, const Index padding_bottom,
0848                           const Index padding_left,const Index padding_right,
0849                           const Scalar padding_value) const {
0850       return TensorImagePatchOp<Dynamic, Dynamic, const Derived>(derived(), patch_rows, patch_cols, row_stride, col_stride,
0851                                                                  in_row_stride, in_col_stride, row_inflate_stride, col_inflate_stride,
0852                                                                  padding_top, padding_bottom, padding_left, padding_right, padding_value);
0853     }
0854 
0855     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0856     const TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>
0857     extract_volume_patches(const Index patch_planes, const Index patch_rows, const Index patch_cols,
0858                            const Index plane_stride = 1, const Index row_stride = 1, const Index col_stride = 1,
0859                            const PaddingType padding_type = PADDING_SAME, const Scalar padding_value = Scalar(0)) const {
0860       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);
0861     }
0862 
0863 
0864     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0865     const TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>
0866     extract_volume_patches(const Index patch_planes, const Index patch_rows, const Index patch_cols,
0867                            const Index plane_stride, const Index row_stride, const Index col_stride,
0868                            const Index plane_inflate_stride, const Index row_inflate_stride, const Index col_inflate_stride,
0869                            const Index padding_top_z, const Index padding_bottom_z,
0870                            const Index padding_top, const Index padding_bottom,
0871                            const Index padding_left, const Index padding_right, const Scalar padding_value = Scalar(0)) const {
0872       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);
0873     }
0874 
0875     // Morphing operators.
0876     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0877     const TensorLayoutSwapOp<const Derived>
0878     swap_layout() const {
0879       return TensorLayoutSwapOp<const Derived>(derived());
0880     }
0881     template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0882     const TensorReshapingOp<const NewDimensions, const Derived>
0883     reshape(const NewDimensions& newDimensions) const {
0884       return TensorReshapingOp<const NewDimensions, const Derived>(derived(), newDimensions);
0885     }
0886     template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0887     const TensorSlicingOp<const StartIndices, const Sizes, const Derived>
0888     slice(const StartIndices& startIndices, const Sizes& sizes) const {
0889       return TensorSlicingOp<const StartIndices, const Sizes, const Derived>(derived(), startIndices, sizes);
0890     }
0891     template <typename StartIndices, typename StopIndices, typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0892     const TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides, const Derived>
0893     stridedSlice(const StartIndices& startIndices, const StopIndices& stopIndices, const Strides& strides) const {
0894       return TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides,
0895                                 const Derived>(derived(), startIndices, stopIndices, strides);
0896     }
0897     template <Index DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0898     const TensorChippingOp<DimId, const Derived>
0899     chip(const Index offset) const {
0900       return TensorChippingOp<DimId, const Derived>(derived(), offset, DimId);
0901     }
0902     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0903     const TensorChippingOp<Dynamic, const Derived>
0904     chip(const Index offset, const Index dim) const {
0905       return TensorChippingOp<Dynamic, const Derived>(derived(), offset, dim);
0906     }
0907     template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0908     const TensorReverseOp<const ReverseDimensions, const Derived>
0909     reverse(const ReverseDimensions& rev) const {
0910       return TensorReverseOp<const ReverseDimensions, const Derived>(derived(), rev);
0911     }
0912     template <typename PaddingDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0913     const TensorPaddingOp<const PaddingDimensions, const Derived>
0914     pad(const PaddingDimensions& padding) const {
0915       return TensorPaddingOp<const PaddingDimensions, const Derived>(derived(), padding, internal::scalar_cast_op<int, Scalar>()(0));
0916     }
0917     template <typename PaddingDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0918     const TensorPaddingOp<const PaddingDimensions, const Derived>
0919     pad(const PaddingDimensions& padding, const Scalar padding_value) const {
0920       return TensorPaddingOp<const PaddingDimensions, const Derived>(derived(), padding, padding_value);
0921     }
0922     template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0923     const TensorShufflingOp<const Shuffle, const Derived>
0924     shuffle(const Shuffle& shfl) const {
0925       return TensorShufflingOp<const Shuffle, const Derived>(derived(), shfl);
0926     }
0927     template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0928     const TensorStridingOp<const Strides, const Derived>
0929     stride(const Strides& strides) const {
0930       return TensorStridingOp<const Strides, const Derived>(derived(), strides);
0931     }
0932     template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0933     const TensorInflationOp<const Strides, const Derived>
0934     inflate(const Strides& strides) const {
0935       return TensorInflationOp<const Strides, const Derived>(derived(), strides);
0936     }
0937 
0938     // Returns a tensor containing index/value tuples
0939     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0940     const TensorIndexTupleOp<const Derived>
0941     index_tuples() const {
0942       return TensorIndexTupleOp<const Derived>(derived());
0943     }
0944 
0945     // Support for custom unary and binary operations
0946     template <typename CustomUnaryFunc>
0947     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0948     const TensorCustomUnaryOp<const CustomUnaryFunc, const Derived> customOp(const CustomUnaryFunc& op) const {
0949       return TensorCustomUnaryOp<const CustomUnaryFunc, const Derived>(derived(), op);
0950     }
0951     template <typename OtherDerived, typename CustomBinaryFunc>
0952     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0953     const TensorCustomBinaryOp<const CustomBinaryFunc, const Derived, const OtherDerived> customOp(const OtherDerived& other, const CustomBinaryFunc& op) const {
0954       return TensorCustomBinaryOp<const CustomBinaryFunc, const Derived, const OtherDerived>(derived(), other, op);
0955     }
0956 
0957     // Force the evaluation of the expression.
0958     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0959     const TensorForcedEvalOp<const Derived> eval() const {
0960       return TensorForcedEvalOp<const Derived>(derived());
0961     }
0962 
0963   protected:
0964     template <typename Scalar, int NumIndices, int Options, typename IndexType> friend class Tensor;
0965     template <typename Scalar, typename Dimensions, int Option, typename IndexTypes> friend class TensorFixedSize;
0966     // the Eigen:: prefix is required to workaround a compilation issue with nvcc 9.0
0967     template <typename OtherDerived, int AccessLevel> friend class Eigen::TensorBase;
0968     EIGEN_DEVICE_FUNC
0969     EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); }
0970 };
0971 
0972 template<typename Derived, int AccessLevel = internal::accessors_level<Derived>::value>
0973 class TensorBase : public TensorBase<Derived, ReadOnlyAccessors> {
0974  public:
0975     typedef TensorBase<Derived, ReadOnlyAccessors> Base;
0976     typedef internal::traits<Derived> DerivedTraits;
0977     typedef typename DerivedTraits::Scalar Scalar;
0978     typedef typename DerivedTraits::Index Index;
0979     typedef Scalar CoeffReturnType;
0980     static const int NumDimensions = DerivedTraits::NumDimensions;
0981 
0982     template <typename Scalar, int NumIndices, int Options, typename IndexType> friend class Tensor;
0983     template <typename Scalar, typename Dimensions, int Option, typename IndexTypes> friend class TensorFixedSize;
0984     // the Eigen:: prefix is required to workaround a compilation issue with nvcc 9.0
0985     template <typename OtherDerived, int OtherAccessLevel> friend class Eigen::TensorBase;
0986 
0987     EIGEN_DEVICE_FUNC
0988     EIGEN_STRONG_INLINE Derived& setZero() {
0989       return setConstant(Scalar(0));
0990     }
0991     EIGEN_DEVICE_FUNC
0992     EIGEN_STRONG_INLINE Derived& setConstant(const Scalar& val) {
0993       return derived() = this->constant(val);
0994     }
0995     EIGEN_DEVICE_FUNC
0996     EIGEN_STRONG_INLINE Derived& setRandom() {
0997       return derived() = this->random();
0998     }
0999     template <typename RandomGenerator> EIGEN_DEVICE_FUNC
1000     EIGEN_STRONG_INLINE Derived& setRandom() {
1001       return derived() = this->template random<RandomGenerator>();
1002     }
1003 
1004 #if EIGEN_HAS_VARIADIC_TEMPLATES
1005     EIGEN_DEVICE_FUNC
1006     EIGEN_STRONG_INLINE Derived& setValues(
1007         const typename internal::Initializer<Derived, NumDimensions>::InitList& vals) {
1008       TensorEvaluator<Derived, DefaultDevice> eval(derived(), DefaultDevice());
1009       internal::initialize_tensor<Derived, NumDimensions>(eval, vals);
1010       return derived();
1011     }
1012 #endif  // EIGEN_HAS_VARIADIC_TEMPLATES
1013 
1014     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1015     Derived& operator+=(const OtherDerived& other) {
1016       return derived() = derived() + other.derived();
1017     }
1018     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1019     Derived& operator-=(const OtherDerived& other) {
1020       return derived() = derived() - other.derived();
1021     }
1022     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1023     Derived& operator*=(const OtherDerived& other) {
1024       return derived() = derived() * other.derived();
1025     }
1026     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1027     Derived& operator/=(const OtherDerived& other) {
1028       return derived() = derived() / other.derived();
1029     }
1030 
1031     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1032     const TensorLayoutSwapOp<const Derived>
1033     swap_layout() const {
1034       return TensorLayoutSwapOp<const Derived>(derived());
1035     }
1036     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1037     TensorLayoutSwapOp<Derived>
1038     swap_layout() {
1039       return TensorLayoutSwapOp<Derived>(derived());
1040     }
1041 
1042     template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1043     const TensorConcatenationOp<const Axis, const Derived, const OtherDerived>
1044     concatenate(const OtherDerived& other, const Axis& axis) const {
1045       return TensorConcatenationOp<const Axis, const Derived, const OtherDerived>(derived(), other, axis);
1046     }
1047     template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1048     TensorConcatenationOp<const Axis, Derived, OtherDerived>
1049     concatenate(const OtherDerived& other, const Axis& axis) {
1050       return TensorConcatenationOp<const Axis, Derived, OtherDerived>(derived(), other, axis);
1051     }
1052 
1053     template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1054     const TensorReshapingOp<const NewDimensions, const Derived>
1055     reshape(const NewDimensions& newDimensions) const {
1056       return TensorReshapingOp<const NewDimensions, const Derived>(derived(), newDimensions);
1057     }
1058     template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1059     TensorReshapingOp<const NewDimensions, Derived>
1060     reshape(const NewDimensions& newDimensions) {
1061       return TensorReshapingOp<const NewDimensions, Derived>(derived(), newDimensions);
1062     }
1063 
1064     template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1065     const TensorSlicingOp<const StartIndices, const Sizes, const Derived>
1066     slice(const StartIndices& startIndices, const Sizes& sizes) const {
1067       return TensorSlicingOp<const StartIndices, const Sizes, const Derived>(derived(), startIndices, sizes);
1068     }
1069     template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1070     TensorSlicingOp<const StartIndices, const Sizes, Derived>
1071     slice(const StartIndices& startIndices, const Sizes& sizes) {
1072       return TensorSlicingOp<const StartIndices, const Sizes, Derived>(derived(), startIndices, sizes);
1073     }
1074 
1075     template <typename StartIndices, typename StopIndices, typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1076     const TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides, const Derived>
1077     stridedSlice(const StartIndices& startIndices, const StopIndices& stopIndices, const Strides& strides) const {
1078       return TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides,
1079                                 const Derived>(derived(), startIndices, stopIndices, strides);
1080     }
1081     template <typename StartIndices, typename StopIndices, typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1082     TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides, Derived>
1083     stridedSlice(const StartIndices& startIndices, const StopIndices& stopIndices, const Strides& strides) {
1084       return TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides,
1085                                 Derived>(derived(), startIndices, stopIndices, strides);
1086     }
1087 
1088     template <DenseIndex DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1089     const TensorChippingOp<DimId, const Derived>
1090     chip(const Index offset) const {
1091       return TensorChippingOp<DimId, const Derived>(derived(), offset, DimId);
1092     }
1093     template <Index DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1094     TensorChippingOp<DimId, Derived>
1095     chip(const Index offset) {
1096       return TensorChippingOp<DimId, Derived>(derived(), offset, DimId);
1097     }
1098 
1099     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1100     const TensorChippingOp<Dynamic, const Derived>
1101     chip(const Index offset, const Index dim) const {
1102       return TensorChippingOp<Dynamic, const Derived>(derived(), offset, dim);
1103     }
1104     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1105     TensorChippingOp<Dynamic, Derived>
1106     chip(const Index offset, const Index dim) {
1107       return TensorChippingOp<Dynamic, Derived>(derived(), offset, dim);
1108     }
1109 
1110     template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1111     const TensorReverseOp<const ReverseDimensions, const Derived>
1112     reverse(const ReverseDimensions& rev) const {
1113       return TensorReverseOp<const ReverseDimensions, const Derived>(derived(), rev);
1114     }
1115     template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1116     TensorReverseOp<const ReverseDimensions, Derived>
1117     reverse(const ReverseDimensions& rev) {
1118       return TensorReverseOp<const ReverseDimensions, Derived>(derived(), rev);
1119     }
1120 
1121     template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1122     const TensorShufflingOp<const Shuffle, const Derived>
1123     shuffle(const Shuffle& shfl) const {
1124       return TensorShufflingOp<const Shuffle, const Derived>(derived(), shfl);
1125     }
1126     template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1127     TensorShufflingOp<const Shuffle, Derived>
1128     shuffle(const Shuffle& shfl) {
1129       return TensorShufflingOp<const Shuffle, Derived>(derived(), shfl);
1130     }
1131 
1132     template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1133     const TensorStridingOp<const Strides, const Derived>
1134     stride(const Strides& strides) const {
1135       return TensorStridingOp<const Strides, const Derived>(derived(), strides);
1136     }
1137     template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
1138     TensorStridingOp<const Strides, Derived>
1139     stride(const Strides& strides) {
1140       return TensorStridingOp<const Strides, Derived>(derived(), strides);
1141     }
1142 
1143     // Select the device on which to evaluate the expression.
1144     template <typename DeviceType>
1145     TensorDevice<Derived, DeviceType> device(const DeviceType& dev) {
1146       return TensorDevice<Derived, DeviceType>(dev, derived());
1147     }
1148 
1149     // Select the async device on which to evaluate the expression.
1150     template <typename DeviceType, typename DoneCallback>
1151     TensorAsyncDevice<Derived, DeviceType, DoneCallback> device(const DeviceType& dev, DoneCallback done) {
1152       return TensorAsyncDevice<Derived, DeviceType, DoneCallback>(dev, derived(), std::move(done));
1153     }
1154 
1155  protected:
1156     EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(TensorBase)
1157     EIGEN_DEFAULT_COPY_CONSTRUCTOR(TensorBase)
1158 
1159     template<typename OtherDerived> EIGEN_DEVICE_FUNC
1160     EIGEN_STRONG_INLINE Derived& operator=(const OtherDerived& other)
1161     {
1162       typedef TensorAssignOp<Derived, const OtherDerived> Assign;
1163       Assign assign(derived(), other.derived());
1164       internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
1165       return derived();
1166     }
1167 
1168     EIGEN_DEVICE_FUNC
1169     EIGEN_STRONG_INLINE Derived& derived() { return *static_cast<Derived*>(this); }
1170     EIGEN_DEVICE_FUNC
1171     EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); }
1172 };
1173 #endif // EIGEN_PARSED_BY_DOXYGEN
1174 } // end namespace Eigen
1175 
1176 #endif // EIGEN_CXX11_TENSOR_TENSOR_BASE_H