TensorBase.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
00005 //
00006 // This Source Code Form is subject to the terms of the Mozilla
00007 // Public License v. 2.0. If a copy of the MPL was not distributed
00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00009 
00010 #ifndef EIGEN_CXX11_TENSOR_TENSOR_BASE_H
00011 #define EIGEN_CXX11_TENSOR_TENSOR_BASE_H
00012 
00013 // clang-format off
00014 
00015 namespace Eigen {
00016 
00026 template<typename Derived>
00027 class TensorBase<Derived, ReadOnlyAccessors>
00028 {
00029   public:
00030     typedef internal::traits<Derived> DerivedTraits;
00031     typedef typename DerivedTraits::Scalar Scalar;
00032     typedef typename DerivedTraits::Index Index;
00033     typedef typename internal::remove_const<Scalar>::type CoeffReturnType;
00034     static const int NumDimensions = DerivedTraits::NumDimensions;
00035 
00036     // Generic nullary operation support.
00037     template <typename CustomNullaryOp> EIGEN_DEVICE_FUNC
00038     EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<CustomNullaryOp, const Derived>
00039     nullaryExpr(const CustomNullaryOp& func) const {
00040       return TensorCwiseNullaryOp<CustomNullaryOp, const Derived>(derived(), func);
00041     }
00042 
00043     // Coefficient-wise nullary operators
00044     EIGEN_DEVICE_FUNC
00045     EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived>
00046     constant(const Scalar& value) const {
00047       return nullaryExpr(internal::scalar_constant_op<Scalar>(value));
00048     }
00049 
00050     EIGEN_DEVICE_FUNC
00051     EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<internal::UniformRandomGenerator<Scalar>, const Derived>
00052     random() const {
00053       return nullaryExpr(internal::UniformRandomGenerator<Scalar>());
00054     }
00055     template <typename RandomGenerator> EIGEN_DEVICE_FUNC
00056     EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<RandomGenerator, const Derived>
00057     random(const RandomGenerator& gen = RandomGenerator()) const {
00058       return nullaryExpr(gen);
00059     }
00060 
00061     // Tensor generation
00062     template <typename Generator> EIGEN_DEVICE_FUNC
00063     EIGEN_STRONG_INLINE const TensorGeneratorOp<Generator, const Derived>
00064     generate(const Generator& generator) const {
00065       return TensorGeneratorOp<Generator, const Derived>(derived(), generator);
00066     }
00067 
00068     // Generic unary operation support.
00069     template <typename CustomUnaryOp> EIGEN_DEVICE_FUNC
00070     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<CustomUnaryOp, const Derived>
00071     unaryExpr(const CustomUnaryOp& func) const {
00072       return TensorCwiseUnaryOp<CustomUnaryOp, const Derived>(derived(), func);
00073     }
00074 
00075     // Coefficient-wise unary operators
00076     EIGEN_DEVICE_FUNC
00077     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const Derived>
00078     operator-() const {
00079       return unaryExpr(internal::scalar_opposite_op<Scalar>());
00080     }
00081 
00082     EIGEN_DEVICE_FUNC
00083     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sqrt_op<Scalar>, const Derived>
00084     sqrt() const {
00085       return unaryExpr(internal::scalar_sqrt_op<Scalar>());
00086     }
00087 
00088     EIGEN_DEVICE_FUNC
00089     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sign_op<Scalar>, const Derived>
00090     sign() const {
00091       return unaryExpr(internal::scalar_sign_op<Scalar>());
00092     }
00093 
00094     EIGEN_DEVICE_FUNC
00095     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_rsqrt_op<Scalar>, const Derived>
00096     rsqrt() const {
00097       return unaryExpr(internal::scalar_rsqrt_op<Scalar>());
00098     }
00099 
00100     EIGEN_DEVICE_FUNC
00101     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_square_op<Scalar>, const Derived>
00102     square() const {
00103       return unaryExpr(internal::scalar_square_op<Scalar>());
00104     }
00105 
00106     EIGEN_DEVICE_FUNC
00107     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_cube_op<Scalar>, const Derived>
00108     cube() const {
00109       return unaryExpr(internal::scalar_cube_op<Scalar>());
00110     }
00111 
00112     EIGEN_DEVICE_FUNC
00113     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const Derived>
00114     inverse() const {
00115       return unaryExpr(internal::scalar_inverse_op<Scalar>());
00116     }
00117 
00118     EIGEN_DEVICE_FUNC
00119     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_tanh_op<Scalar>, const Derived>
00120     tanh() const {
00121       return unaryExpr(internal::scalar_tanh_op<Scalar>());
00122     }
00123 
00124     EIGEN_DEVICE_FUNC
00125     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_lgamma_op<Scalar>, const Derived>
00126     lgamma() const {
00127       return unaryExpr(internal::scalar_lgamma_op<Scalar>());
00128     }
00129 
00130     EIGEN_DEVICE_FUNC
00131     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_digamma_op<Scalar>, const Derived>
00132     digamma() const {
00133       return unaryExpr(internal::scalar_digamma_op<Scalar>());
00134     }
00135 
00136     // igamma(a = this, x = other)
00137     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00138     const TensorCwiseBinaryOp<internal::scalar_igamma_op<Scalar>, const Derived, const OtherDerived>
00139     igamma(const OtherDerived& other) const {
00140       return binaryExpr(other.derived(), internal::scalar_igamma_op<Scalar>());
00141     }
00142 
00143     // igammac(a = this, x = other)
00144     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00145     const TensorCwiseBinaryOp<internal::scalar_igammac_op<Scalar>, const Derived, const OtherDerived>
00146     igammac(const OtherDerived& other) const {
00147       return binaryExpr(other.derived(), internal::scalar_igammac_op<Scalar>());
00148     }
00149 
00150     // zeta(x = this, q = other)
00151     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00152     const TensorCwiseBinaryOp<internal::scalar_zeta_op<Scalar>, const Derived, const OtherDerived>
00153     zeta(const OtherDerived& other) const {
00154       return binaryExpr(other.derived(), internal::scalar_zeta_op<Scalar>());
00155     }
00156 
00157     // polygamma(n = this, x = other)
00158     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00159     const TensorCwiseBinaryOp<internal::scalar_polygamma_op<Scalar>, const Derived, const OtherDerived>
00160     polygamma(const OtherDerived& other) const {
00161       return binaryExpr(other.derived(), internal::scalar_polygamma_op<Scalar>());
00162     }
00163 
00164     EIGEN_DEVICE_FUNC
00165     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_erf_op<Scalar>, const Derived>
00166     erf() const {
00167       return unaryExpr(internal::scalar_erf_op<Scalar>());
00168     }
00169 
00170     EIGEN_DEVICE_FUNC
00171     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_erfc_op<Scalar>, const Derived>
00172     erfc() const {
00173       return unaryExpr(internal::scalar_erfc_op<Scalar>());
00174     }
00175 
00176     EIGEN_DEVICE_FUNC
00177     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sigmoid_op<Scalar>, const Derived>
00178     sigmoid() const {
00179       return unaryExpr(internal::scalar_sigmoid_op<Scalar>());
00180     }
00181 
00182     EIGEN_DEVICE_FUNC
00183     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_exp_op<Scalar>, const Derived>
00184     exp() const {
00185       return unaryExpr(internal::scalar_exp_op<Scalar>());
00186     }
00187 
00188     EIGEN_DEVICE_FUNC
00189     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log_op<Scalar>, const Derived>
00190     log() const {
00191       return unaryExpr(internal::scalar_log_op<Scalar>());
00192     }
00193 
00194     EIGEN_DEVICE_FUNC
00195     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log1p_op<Scalar>, const Derived>
00196     log1p() const {
00197       return unaryExpr(internal::scalar_log1p_op<Scalar>());
00198     }
00199 
00200     EIGEN_DEVICE_FUNC
00201     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_abs_op<Scalar>, const Derived>
00202     abs() const {
00203       return unaryExpr(internal::scalar_abs_op<Scalar>());
00204     }
00205 
00206     EIGEN_DEVICE_FUNC
00207     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, const Derived>
00208     conjugate() const {
00209       return unaryExpr(internal::scalar_conjugate_op<Scalar>());
00210     }
00211 
00212     EIGEN_DEVICE_FUNC
00213     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_pow_op<Scalar,Scalar> >, const Derived>
00214     pow(Scalar exponent) const {
00215       return unaryExpr(internal::bind2nd_op<internal::scalar_pow_op<Scalar,Scalar> >(exponent));
00216     }
00217 
00218     EIGEN_DEVICE_FUNC
00219     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_real_op<Scalar>, const Derived>
00220     real() const {
00221       return unaryExpr(internal::scalar_real_op<Scalar>());
00222     }
00223 
00224     EIGEN_DEVICE_FUNC
00225     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_imag_op<Scalar>, const Derived>
00226     imag() const {
00227       return unaryExpr(internal::scalar_imag_op<Scalar>());
00228     }
00229 
00230     EIGEN_DEVICE_FUNC
00231     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_sum_op<Scalar,Scalar> >, const Derived>
00232     operator+ (Scalar rhs) const {
00233       return unaryExpr(internal::bind2nd_op<internal::scalar_sum_op<Scalar,Scalar> >(rhs));
00234     }
00235 
00236     EIGEN_DEVICE_FUNC
00237     EIGEN_STRONG_INLINE friend
00238     const TensorCwiseUnaryOp<internal::bind1st_op<internal::scalar_sum_op<Scalar> >, const Derived>
00239     operator+ (Scalar lhs, const Derived& rhs) {
00240       return rhs.unaryExpr(internal::bind1st_op<internal::scalar_sum_op<Scalar> >(lhs));
00241     }
00242 
00243     EIGEN_DEVICE_FUNC
00244     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_difference_op<Scalar,Scalar> >, const Derived>
00245     operator- (Scalar rhs) const {
00246       EIGEN_STATIC_ASSERT((NumTraits<Scalar>::IsSigned || internal::is_same<Scalar, const std::complex<float> >::value), YOU_MADE_A_PROGRAMMING_MISTAKE);
00247       return unaryExpr(internal::bind2nd_op<internal::scalar_difference_op<Scalar,Scalar> >(rhs));
00248     }
00249 
00250     EIGEN_DEVICE_FUNC
00251     EIGEN_STRONG_INLINE friend
00252     const TensorCwiseUnaryOp<internal::bind1st_op<internal::scalar_difference_op<Scalar> >, const Derived>
00253     operator- (Scalar lhs, const Derived& rhs) {
00254       return rhs.unaryExpr(internal::bind1st_op<internal::scalar_difference_op<Scalar> >(lhs));
00255     }
00256 
00257     EIGEN_DEVICE_FUNC
00258     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_product_op<Scalar,Scalar> >, const Derived>
00259     operator* (Scalar rhs) const {
00260       return unaryExpr(internal::bind2nd_op<internal::scalar_product_op<Scalar,Scalar> >(rhs));
00261     }
00262 
00263     EIGEN_DEVICE_FUNC
00264     EIGEN_STRONG_INLINE friend
00265     const TensorCwiseUnaryOp<internal::bind1st_op<internal::scalar_product_op<Scalar> >, const Derived>
00266     operator* (Scalar lhs, const Derived& rhs) {
00267       return rhs.unaryExpr(internal::bind1st_op<internal::scalar_product_op<Scalar> >(lhs));
00268     }
00269 
00270     EIGEN_DEVICE_FUNC
00271     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_quotient_op<Scalar,Scalar> >, const Derived>
00272     operator/ (Scalar rhs) const {
00273       return unaryExpr(internal::bind2nd_op<internal::scalar_quotient_op<Scalar,Scalar> >(rhs));
00274     }
00275 
00276     EIGEN_DEVICE_FUNC
00277     EIGEN_STRONG_INLINE friend
00278     const TensorCwiseUnaryOp<internal::bind1st_op<internal::scalar_quotient_op<Scalar> >, const Derived>
00279     operator/ (Scalar lhs, const Derived& rhs) {
00280       return rhs.unaryExpr(internal::bind1st_op<internal::scalar_quotient_op<Scalar> >(lhs));
00281     }
00282 
00283     EIGEN_DEVICE_FUNC
00284     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_mod_op<Scalar>, const Derived>
00285     operator% (Scalar rhs) const {
00286       EIGEN_STATIC_ASSERT(NumTraits<Scalar>::IsInteger, YOU_MADE_A_PROGRAMMING_MISTAKE_TRY_MOD);
00287       return unaryExpr(internal::scalar_mod_op<Scalar>(rhs));
00288     }
00289 
00290     EIGEN_DEVICE_FUNC
00291     EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
00292     cwiseMax(Scalar threshold) const {
00293       return cwiseMax(constant(threshold));
00294     }
00295 
00296     EIGEN_DEVICE_FUNC
00297     EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
00298     cwiseMin(Scalar threshold) const {
00299       return cwiseMin(constant(threshold));
00300     }
00301 
00302     template <typename NewType> EIGEN_DEVICE_FUNC
00303     EIGEN_STRONG_INLINE const TensorConversionOp<NewType, const Derived>
00304     cast() const {
00305       return TensorConversionOp<NewType, const Derived>(derived());
00306     }
00307 
00308     EIGEN_DEVICE_FUNC
00309     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_round_op<Scalar>, const Derived>
00310     round() const {
00311       return unaryExpr(internal::scalar_round_op<Scalar>());
00312     }
00313 
00314     EIGEN_DEVICE_FUNC
00315     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_ceil_op<Scalar>, const Derived>
00316     ceil() const {
00317       return unaryExpr(internal::scalar_ceil_op<Scalar>());
00318     }
00319 
00320     EIGEN_DEVICE_FUNC
00321     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_floor_op<Scalar>, const Derived>
00322     floor() const {
00323       return unaryExpr(internal::scalar_floor_op<Scalar>());
00324     }
00325 
00326     // Generic binary operation support.
00327     template <typename CustomBinaryOp, typename OtherDerived> EIGEN_DEVICE_FUNC
00328     EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>
00329     binaryExpr(const OtherDerived& other, const CustomBinaryOp& func) const {
00330       return TensorCwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>(derived(), other, func);
00331     }
00332 
00333     // Coefficient-wise binary operators.
00334     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00335     const TensorCwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const OtherDerived>
00336     operator+(const OtherDerived& other) const {
00337       return binaryExpr(other.derived(), internal::scalar_sum_op<Scalar>());
00338     }
00339 
00340     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00341     const TensorCwiseBinaryOp<internal::scalar_difference_op<Scalar>, const Derived, const OtherDerived>
00342     operator-(const OtherDerived& other) const {
00343       return binaryExpr(other.derived(), internal::scalar_difference_op<Scalar>());
00344     }
00345 
00346     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00347     const TensorCwiseBinaryOp<internal::scalar_product_op<Scalar>, const Derived, const OtherDerived>
00348     operator*(const OtherDerived& other) const {
00349       return binaryExpr(other.derived(), internal::scalar_product_op<Scalar>());
00350     }
00351 
00352     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00353     const TensorCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, const Derived, const OtherDerived>
00354     operator/(const OtherDerived& other) const {
00355       return binaryExpr(other.derived(), internal::scalar_quotient_op<Scalar>());
00356     }
00357 
00358     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00359     const TensorCwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const OtherDerived>
00360     cwiseMax(const OtherDerived& other) const {
00361       return binaryExpr(other.derived(), internal::scalar_max_op<Scalar>());
00362     }
00363 
00364     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00365     const TensorCwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const OtherDerived>
00366     cwiseMin(const OtherDerived& other) const {
00367       return binaryExpr(other.derived(), internal::scalar_min_op<Scalar>());
00368     }
00369 
00370     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00371     const TensorCwiseBinaryOp<internal::scalar_boolean_and_op, const Derived, const OtherDerived>
00372     operator&&(const OtherDerived& other) const {
00373       return binaryExpr(other.derived(), internal::scalar_boolean_and_op());
00374     }
00375 
00376     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00377     const TensorCwiseBinaryOp<internal::scalar_boolean_or_op, const Derived, const OtherDerived>
00378     operator||(const OtherDerived& other) const {
00379       return binaryExpr(other.derived(), internal::scalar_boolean_or_op());
00380     }
00381 
00382     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00383     const TensorCwiseBinaryOp<internal::scalar_boolean_xor_op, const Derived, const OtherDerived>
00384     operator^(const OtherDerived& other) const {
00385       return binaryExpr(other.derived(), internal::scalar_boolean_xor_op());
00386     }
00387 
00388     // Comparisons and tests.
00389     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00390     const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LT>, const Derived, const OtherDerived>
00391     operator<(const OtherDerived& other) const {
00392       return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LT>());
00393     }
00394     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00395     const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LE>, const Derived, const OtherDerived>
00396     operator<=(const OtherDerived& other) const {
00397       return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LE>());
00398     }
00399     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00400     const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GT>, const Derived, const OtherDerived>
00401     operator>(const OtherDerived& other) const {
00402       return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GT>());
00403     }
00404     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00405     const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GE>, const Derived, const OtherDerived>
00406     operator>=(const OtherDerived& other) const {
00407       return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GE>());
00408     }
00409 
00410     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00411     const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_EQ>, const Derived, const OtherDerived>
00412     operator==(const OtherDerived& other) const {
00413       return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_EQ>());
00414     }
00415 
00416     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00417     const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_NEQ>, const Derived, const OtherDerived>
00418     operator!=(const OtherDerived& other) const {
00419       return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_NEQ>());
00420     }
00421 
00422     // comparisons and tests for Scalars
00423     EIGEN_DEVICE_FUNC
00424     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> >
00425     operator<(Scalar threshold) const {
00426       return operator<(constant(threshold));
00427     }
00428     EIGEN_DEVICE_FUNC
00429     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> >
00430     operator<=(Scalar threshold) const {
00431       return operator<=(constant(threshold));
00432     }
00433     EIGEN_DEVICE_FUNC
00434     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> >
00435     operator>(Scalar threshold) const {
00436       return operator>(constant(threshold));
00437     }
00438     EIGEN_DEVICE_FUNC
00439     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> >
00440     operator>=(Scalar threshold) const {
00441       return operator>=(constant(threshold));
00442     }
00443     EIGEN_DEVICE_FUNC
00444     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> >
00445     operator==(Scalar threshold) const {
00446       return operator==(constant(threshold));
00447     }
00448     EIGEN_DEVICE_FUNC
00449     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> >
00450     operator!=(Scalar threshold) const {
00451       return operator!=(constant(threshold));
00452     }
00453 
00454     // Checks
00455     EIGEN_DEVICE_FUNC
00456     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_isnan_op<Scalar>, const Derived>
00457     (isnan)() const {
00458       return unaryExpr(internal::scalar_isnan_op<Scalar>());
00459     }
00460     EIGEN_DEVICE_FUNC
00461     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_isinf_op<Scalar>, const Derived>
00462     (isinf)() const {
00463       return unaryExpr(internal::scalar_isinf_op<Scalar>());
00464     }
00465     EIGEN_DEVICE_FUNC
00466     EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_isfinite_op<Scalar>, const Derived>
00467     (isfinite)() const {
00468       return unaryExpr(internal::scalar_isfinite_op<Scalar>());
00469     }
00470 
00471     // Coefficient-wise ternary operators.
00472     template<typename ThenDerived, typename ElseDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00473     const TensorSelectOp<const Derived, const ThenDerived, const ElseDerived>
00474     select(const ThenDerived& thenTensor, const ElseDerived& elseTensor) const {
00475       return TensorSelectOp<const Derived, const ThenDerived, const ElseDerived>(derived(), thenTensor.derived(), elseTensor.derived());
00476     }
00477 
00478     // Contractions.
00479     typedef Eigen::IndexPair<Index> DimensionPair;
00480 
00481     template<typename OtherDerived, typename Dimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00482     const TensorContractionOp<const Dimensions, const Derived, const OtherDerived>
00483     contract(const OtherDerived& other, const Dimensions& dims) const {
00484       return TensorContractionOp<const Dimensions, const Derived, const OtherDerived>(derived(), other.derived(), dims);
00485     }
00486 
00487     // Convolutions.
00488     template<typename KernelDerived, typename Dimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00489     const TensorConvolutionOp<const Dimensions, const Derived, const KernelDerived>
00490     convolve(const KernelDerived& kernel, const Dimensions& dims) const {
00491       return TensorConvolutionOp<const Dimensions, const Derived, const KernelDerived>(derived(), kernel.derived(), dims);
00492     }
00493 
00494     // Fourier transforms
00495     template <int FFTDataType, int FFTDirection, typename FFT> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00496     const TensorFFTOp<const FFT, const Derived, FFTDataType, FFTDirection>
00497     fft(const FFT& fft) const {
00498       return TensorFFTOp<const FFT, const Derived, FFTDataType, FFTDirection>(derived(), fft);
00499     }
00500 
00501     // Scan.
00502     typedef TensorScanOp<internal::SumReducer<CoeffReturnType>, const Derived> TensorScanSumOp;
00503     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00504     const TensorScanSumOp
00505     cumsum(const Index& axis, bool exclusive = false) const {
00506       return TensorScanSumOp(derived(), axis, exclusive);
00507     }
00508 
00509     typedef TensorScanOp<internal::ProdReducer<CoeffReturnType>, const Derived> TensorScanProdOp;
00510     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00511     const TensorScanProdOp
00512     cumprod(const Index& axis, bool exclusive = false) const {
00513       return TensorScanProdOp(derived(), axis, exclusive);
00514     }
00515 
00516     template <typename Reducer>
00517     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00518     const TensorScanOp<Reducer, const Derived>
00519     scan(const Index& axis, const Reducer& reducer, bool exclusive = false) const {
00520       return TensorScanOp<Reducer, const Derived>(derived(), axis, exclusive, reducer);
00521     }
00522 
00523     // Reductions.
00524     template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00525     const TensorReductionOp<internal::SumReducer<CoeffReturnType>, const Dims, const Derived>
00526     sum(const Dims& dims) const {
00527       return TensorReductionOp<internal::SumReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::SumReducer<CoeffReturnType>());
00528     }
00529 
00530     const TensorReductionOp<internal::SumReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
00531     sum() const {
00532       DimensionList<Index, NumDimensions> in_dims;
00533       return TensorReductionOp<internal::SumReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::SumReducer<CoeffReturnType>());
00534     }
00535 
00536     template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00537     const TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const Dims, const Derived>
00538     mean(const Dims& dims) const {
00539       return TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::MeanReducer<CoeffReturnType>());
00540     }
00541 
00542     const TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
00543     mean() const {
00544       DimensionList<Index, NumDimensions> in_dims;
00545       return TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MeanReducer<CoeffReturnType>());
00546     }
00547 
00548     template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00549     const TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const Dims, const Derived>
00550     prod(const Dims& dims) const {
00551       return TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::ProdReducer<CoeffReturnType>());
00552     }
00553 
00554     const TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
00555     prod() const {
00556       DimensionList<Index, NumDimensions> in_dims;
00557       return TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::ProdReducer<CoeffReturnType>());
00558     }
00559 
00560     template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00561     const TensorReductionOp<internal::MaxReducer<CoeffReturnType>, const Dims, const Derived>
00562     maximum(const Dims& dims) const {
00563       return TensorReductionOp<internal::MaxReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::MaxReducer<CoeffReturnType>());
00564     }
00565 
00566     const TensorReductionOp<internal::MaxReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
00567     maximum() const {
00568       DimensionList<Index, NumDimensions> in_dims;
00569       return TensorReductionOp<internal::MaxReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MaxReducer<CoeffReturnType>());
00570     }
00571 
00572     template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00573     const TensorReductionOp<internal::MinReducer<CoeffReturnType>, const Dims, const Derived>
00574     minimum(const Dims& dims) const {
00575       return TensorReductionOp<internal::MinReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::MinReducer<CoeffReturnType>());
00576     }
00577 
00578     const TensorReductionOp<internal::MinReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
00579     minimum() const {
00580       DimensionList<Index, NumDimensions> in_dims;
00581       return TensorReductionOp<internal::MinReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MinReducer<CoeffReturnType>());
00582     }
00583 
00584     template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00585     const TensorReductionOp<internal::AndReducer, const Dims, const TensorConversionOp<bool, const Derived> >
00586     all(const Dims& dims) const {
00587       return cast<bool>().reduce(dims, internal::AndReducer());
00588     }
00589 
00590     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00591     const TensorReductionOp<internal::AndReducer, const DimensionList<Index, NumDimensions>, const TensorConversionOp<bool, const Derived> >
00592     all() const {
00593       DimensionList<Index, NumDimensions> in_dims;
00594       return cast<bool>().reduce(in_dims, internal::AndReducer());
00595     }
00596 
00597     template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00598     const TensorReductionOp<internal::OrReducer, const Dims, const TensorConversionOp<bool, const Derived> >
00599     any(const Dims& dims) const {
00600       return cast<bool>().reduce(dims, internal::OrReducer());
00601     }
00602 
00603     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00604     const TensorReductionOp<internal::OrReducer, const DimensionList<Index, NumDimensions>, const TensorConversionOp<bool, const Derived> >
00605     any() const {
00606       DimensionList<Index, NumDimensions> in_dims;
00607       return cast<bool>().reduce(in_dims, internal::OrReducer());
00608     }
00609 
00610    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00611     const TensorTupleReducerOp<
00612       internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
00613       const array<Index, NumDimensions>, const Derived>
00614     argmax() const {
00615       array<Index, NumDimensions> in_dims;
00616       for (int d = 0; d < NumDimensions; ++d) in_dims[d] = d;
00617       return TensorTupleReducerOp<
00618         internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
00619         const array<Index, NumDimensions>,
00620         const Derived>(derived(), internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >(), -1, in_dims);
00621     }
00622 
00623     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00624     const TensorTupleReducerOp<
00625       internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
00626       const array<Index, NumDimensions>, const Derived>
00627     argmin() const {
00628       array<Index, NumDimensions> in_dims;
00629       for (int d = 0; d < NumDimensions; ++d) in_dims[d] = d;
00630       return TensorTupleReducerOp<
00631         internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
00632         const array<Index, NumDimensions>,
00633         const Derived>(derived(), internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >(), -1, in_dims);
00634     }
00635 
00636     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00637     const TensorTupleReducerOp<
00638       internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
00639       const array<Index, 1>, const Derived>
00640     argmax(const int return_dim) const {
00641       array<Index, 1> in_dims;
00642       in_dims[0] = return_dim;
00643       return TensorTupleReducerOp<
00644         internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >,
00645         const array<Index, 1>,
00646         const Derived>(derived(), internal::ArgMaxTupleReducer<Tuple<Index, CoeffReturnType> >(), return_dim, in_dims);
00647     }
00648 
00649     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00650     const TensorTupleReducerOp<
00651       internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
00652       const array<Index, 1>, const Derived>
00653     argmin(const int return_dim) const {
00654       array<Index, 1> in_dims;
00655       in_dims[0] = return_dim;
00656       return TensorTupleReducerOp<
00657         internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >,
00658         const array<Index, 1>,
00659         const Derived>(derived(), internal::ArgMinTupleReducer<Tuple<Index, CoeffReturnType> >(), return_dim, in_dims);
00660     }
00661 
00662     template <typename Reducer, typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00663     const TensorReductionOp<Reducer, const Dims, const Derived>
00664     reduce(const Dims& dims, const Reducer& reducer) const {
00665       return TensorReductionOp<Reducer, const Dims, const Derived>(derived(), dims, reducer);
00666     }
00667 
00668     template <typename Broadcast> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00669     const TensorBroadcastingOp<const Broadcast, const Derived>
00670     broadcast(const Broadcast& broadcast) const {
00671       return TensorBroadcastingOp<const Broadcast, const Derived>(derived(), broadcast);
00672     }
00673 
00674     template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00675     const TensorConcatenationOp<Axis, const Derived, const OtherDerived>
00676     concatenate(const OtherDerived& other, Axis axis) const {
00677       return TensorConcatenationOp<Axis, const Derived, const OtherDerived>(derived(), other.derived(), axis);
00678     }
00679 
00680     template <typename PatchDims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00681     const TensorPatchOp<const PatchDims, const Derived>
00682     extract_patches(const PatchDims& patch_dims) const {
00683       return TensorPatchOp<const PatchDims, const Derived>(derived(), patch_dims);
00684     }
00685 
00686     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00687     const TensorImagePatchOp<Dynamic, Dynamic, const Derived>
00688     extract_image_patches(const Index patch_rows = 1, const Index patch_cols = 1,
00689                           const Index row_stride = 1, const Index col_stride = 1,
00690                           const Index in_row_stride = 1, const Index in_col_stride = 1,
00691                           const PaddingType padding_type = PADDING_SAME, const Scalar padding_value = Scalar(0)) const {
00692       return TensorImagePatchOp<Dynamic, Dynamic, const Derived>(derived(), patch_rows, patch_cols, row_stride, col_stride,
00693                                                                  in_row_stride, in_col_stride, 1, 1, padding_type, padding_value);
00694     }
00695 
00696     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00697     const TensorImagePatchOp<Dynamic, Dynamic, const Derived>
00698     extract_image_patches(const Index patch_rows, const Index patch_cols,
00699                           const Index row_stride, const Index col_stride,
00700                           const Index in_row_stride, const Index in_col_stride,
00701                           const Index row_inflate_stride, const Index col_inflate_stride,
00702                           const Index padding_top, const Index padding_bottom,
00703                           const Index padding_left,const Index padding_right,
00704                           const Scalar padding_value) const {
00705       return TensorImagePatchOp<Dynamic, Dynamic, const Derived>(derived(), patch_rows, patch_cols, row_stride, col_stride,
00706                                                                  in_row_stride, in_col_stride, row_inflate_stride, col_inflate_stride,
00707                                                                  padding_top, padding_bottom, padding_left, padding_right, padding_value);
00708     }
00709 
00710     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00711     const TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>
00712     extract_volume_patches(const Index patch_planes, const Index patch_rows, const Index patch_cols,
00713                            const Index plane_stride = 1, const Index row_stride = 1, const Index col_stride = 1,
00714                            const PaddingType padding_type = PADDING_SAME, const Scalar padding_value = Scalar(0)) const {
00715       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);
00716     }
00717 
00718 
00719     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00720     const TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>
00721     extract_volume_patches(const Index patch_planes, const Index patch_rows, const Index patch_cols,
00722                            const Index plane_stride, const Index row_stride, const Index col_stride,
00723                            const Index plane_inflate_stride, const Index row_inflate_stride, const Index col_inflate_stride,
00724                            const Index padding_top_z, const Index padding_bottom_z,
00725                            const Index padding_top, const Index padding_bottom,
00726                            const Index padding_left, const Index padding_right, const Scalar padding_value = Scalar(0)) const {
00727       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);
00728     }
00729 
00730     // Morphing operators.
00731     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00732     const TensorLayoutSwapOp<const Derived>
00733     swap_layout() const {
00734       return TensorLayoutSwapOp<const Derived>(derived());
00735     }
00736     template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00737     const TensorReshapingOp<const NewDimensions, const Derived>
00738     reshape(const NewDimensions& newDimensions) const {
00739       return TensorReshapingOp<const NewDimensions, const Derived>(derived(), newDimensions);
00740     }
00741     template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00742     const TensorSlicingOp<const StartIndices, const Sizes, const Derived>
00743     slice(const StartIndices& startIndices, const Sizes& sizes) const {
00744       return TensorSlicingOp<const StartIndices, const Sizes, const Derived>(derived(), startIndices, sizes);
00745     }
00746     template <typename StartIndices, typename StopIndices, typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00747     const TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides, const Derived>
00748     stridedSlice(const StartIndices& startIndices, const StopIndices& stopIndices, const Strides& strides) const {
00749       return TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides,
00750                                 const Derived>(derived(), startIndices, stopIndices, strides);
00751     }
00752     template <Index DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00753     const TensorChippingOp<DimId, const Derived>
00754     chip(const Index offset) const {
00755       return TensorChippingOp<DimId, const Derived>(derived(), offset, DimId);
00756     }
00757     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00758     const TensorChippingOp<Dynamic, const Derived>
00759     chip(const Index offset, const Index dim) const {
00760       return TensorChippingOp<Dynamic, const Derived>(derived(), offset, dim);
00761     }
00762     template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00763     const TensorReverseOp<const ReverseDimensions, const Derived>
00764     reverse(const ReverseDimensions& rev) const {
00765       return TensorReverseOp<const ReverseDimensions, const Derived>(derived(), rev);
00766     }
00767     template <typename PaddingDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00768     const TensorPaddingOp<const PaddingDimensions, const Derived>
00769     pad(const PaddingDimensions& padding) const {
00770       return TensorPaddingOp<const PaddingDimensions, const Derived>(derived(), padding, internal::scalar_cast_op<int, Scalar>()(0));
00771     }
00772     template <typename PaddingDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00773     const TensorPaddingOp<const PaddingDimensions, const Derived>
00774     pad(const PaddingDimensions& padding, const Scalar padding_value) const {
00775       return TensorPaddingOp<const PaddingDimensions, const Derived>(derived(), padding, padding_value);
00776     }
00777     template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00778     const TensorShufflingOp<const Shuffle, const Derived>
00779     shuffle(const Shuffle& shuffle) const {
00780       return TensorShufflingOp<const Shuffle, const Derived>(derived(), shuffle);
00781     }
00782     template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00783     const TensorStridingOp<const Strides, const Derived>
00784     stride(const Strides& strides) const {
00785       return TensorStridingOp<const Strides, const Derived>(derived(), strides);
00786     }
00787     template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00788     const TensorInflationOp<const Strides, const Derived>
00789     inflate(const Strides& strides) const {
00790       return TensorInflationOp<const Strides, const Derived>(derived(), strides);
00791     }
00792 
00793     // Returns a tensor containing index/value tuples
00794     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00795     const TensorIndexTupleOp<const Derived>
00796     index_tuples() const {
00797       return TensorIndexTupleOp<const Derived>(derived());
00798     }
00799 
00800     // Support for custom unary and binary operations
00801     template <typename CustomUnaryFunc>
00802     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00803     const TensorCustomUnaryOp<const CustomUnaryFunc, const Derived> customOp(const CustomUnaryFunc& op) const {
00804       return TensorCustomUnaryOp<const CustomUnaryFunc, const Derived>(derived(), op);
00805     }
00806     template <typename OtherDerived, typename CustomBinaryFunc>
00807     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00808     const TensorCustomBinaryOp<const CustomBinaryFunc, const Derived, const OtherDerived> customOp(const OtherDerived& other, const CustomBinaryFunc& op) const {
00809       return TensorCustomBinaryOp<const CustomBinaryFunc, const Derived, const OtherDerived>(derived(), other, op);
00810     }
00811 
00812     // Force the evaluation of the expression.
00813     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00814     const TensorForcedEvalOp<const Derived> eval() const {
00815       return TensorForcedEvalOp<const Derived>(derived());
00816     }
00817 
00818   protected:
00819     template <typename Scalar, int NumIndices, int Options, typename IndexType> friend class Tensor;
00820     template <typename Scalar, typename Dimensions, int Option, typename IndexTypes> friend class TensorFixedSize;
00821     template <typename OtherDerived, int AccessLevel> friend class TensorBase;
00822     EIGEN_DEVICE_FUNC
00823     EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); }
00824 };
00825 
00826 template<typename Derived, int AccessLevel = internal::accessors_level<Derived>::value>
00827 class TensorBase : public TensorBase<Derived, ReadOnlyAccessors> {
00828  public:
00829     typedef internal::traits<Derived> DerivedTraits;
00830     typedef typename DerivedTraits::Scalar Scalar;
00831     typedef typename DerivedTraits::Index Index;
00832     typedef Scalar CoeffReturnType;
00833     static const int NumDimensions = DerivedTraits::NumDimensions;
00834 
00835     template <typename Scalar, int NumIndices, int Options, typename IndexType> friend class Tensor;
00836     template <typename Scalar, typename Dimensions, int Option, typename IndexTypes> friend class TensorFixedSize;
00837     template <typename OtherDerived, int OtherAccessLevel> friend class TensorBase;
00838 
00839     EIGEN_DEVICE_FUNC
00840     EIGEN_STRONG_INLINE Derived& setZero() {
00841       return setConstant(Scalar(0));
00842     }
00843     EIGEN_DEVICE_FUNC
00844     EIGEN_STRONG_INLINE Derived& setConstant(const Scalar& val) {
00845       return derived() = this->constant(val);
00846     }
00847     EIGEN_DEVICE_FUNC
00848     EIGEN_STRONG_INLINE Derived& setRandom() {
00849       return derived() = this->random();
00850     }
00851     template <typename RandomGenerator> EIGEN_DEVICE_FUNC
00852     EIGEN_STRONG_INLINE Derived& setRandom() {
00853       return derived() = this->template random<RandomGenerator>();
00854     }
00855 
00856 #if EIGEN_HAS_VARIADIC_TEMPLATES
00857     EIGEN_DEVICE_FUNC
00858     EIGEN_STRONG_INLINE Derived& setValues(
00859         const typename internal::Initializer<Derived, NumDimensions>::InitList& vals) {
00860       TensorEvaluator<Derived, DefaultDevice> eval(derived(), DefaultDevice());
00861       internal::initialize_tensor<Derived, NumDimensions>(eval, vals);
00862       return derived();
00863     }
00864 #endif  // EIGEN_HAS_VARIADIC_TEMPLATES
00865 
00866     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00867     Derived& operator+=(const OtherDerived& other) {
00868       return derived() = derived() + other.derived();
00869     }
00870     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00871     Derived& operator-=(const OtherDerived& other) {
00872       return derived() = derived() - other.derived();
00873     }
00874     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00875     Derived& operator*=(const OtherDerived& other) {
00876       return derived() = derived() * other.derived();
00877     }
00878     template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00879     Derived& operator/=(const OtherDerived& other) {
00880       return derived() = derived() / other.derived();
00881     }
00882 
00883     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00884     const TensorLayoutSwapOp<const Derived>
00885     swap_layout() const {
00886       return TensorLayoutSwapOp<const Derived>(derived());
00887     }
00888     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00889     TensorLayoutSwapOp<Derived>
00890     swap_layout() {
00891       return TensorLayoutSwapOp<Derived>(derived());
00892     }
00893 
00894     template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00895     const TensorConcatenationOp<const Axis, const Derived, const OtherDerived>
00896     concatenate(const OtherDerived& other, const Axis& axis) const {
00897       return TensorConcatenationOp<const Axis, const Derived, const OtherDerived>(derived(), other, axis);
00898     }
00899     template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00900     TensorConcatenationOp<const Axis, Derived, OtherDerived>
00901     concatenate(const OtherDerived& other, const Axis& axis) {
00902       return TensorConcatenationOp<const Axis, Derived, OtherDerived>(derived(), other, axis);
00903     }
00904 
00905     template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00906     const TensorReshapingOp<const NewDimensions, const Derived>
00907     reshape(const NewDimensions& newDimensions) const {
00908       return TensorReshapingOp<const NewDimensions, const Derived>(derived(), newDimensions);
00909     }
00910     template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00911     TensorReshapingOp<const NewDimensions, Derived>
00912     reshape(const NewDimensions& newDimensions) {
00913       return TensorReshapingOp<const NewDimensions, Derived>(derived(), newDimensions);
00914     }
00915 
00916     template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00917     const TensorSlicingOp<const StartIndices, const Sizes, const Derived>
00918     slice(const StartIndices& startIndices, const Sizes& sizes) const {
00919       return TensorSlicingOp<const StartIndices, const Sizes, const Derived>(derived(), startIndices, sizes);
00920     }
00921     template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00922     TensorSlicingOp<const StartIndices, const Sizes, Derived>
00923     slice(const StartIndices& startIndices, const Sizes& sizes) {
00924       return TensorSlicingOp<const StartIndices, const Sizes, Derived>(derived(), startIndices, sizes);
00925     }
00926 
00927     template <typename StartIndices, typename StopIndices, typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00928     const TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides, const Derived>
00929     stridedSlice(const StartIndices& startIndices, const StopIndices& stopIndices, const Strides& strides) const {
00930       return TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides,
00931                                 const Derived>(derived(), startIndices, stopIndices, strides);
00932     }
00933     template <typename StartIndices, typename StopIndices, typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00934     TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides, Derived>
00935     stridedSlice(const StartIndices& startIndices, const StopIndices& stopIndices, const Strides& strides) {
00936       return TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides,
00937                                 Derived>(derived(), startIndices, stopIndices, strides);
00938     }
00939 
00940     template <DenseIndex DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00941     const TensorChippingOp<DimId, const Derived>
00942     chip(const Index offset) const {
00943       return TensorChippingOp<DimId, const Derived>(derived(), offset, DimId);
00944     }
00945     template <Index DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00946     TensorChippingOp<DimId, Derived>
00947     chip(const Index offset) {
00948       return TensorChippingOp<DimId, Derived>(derived(), offset, DimId);
00949     }
00950 
00951     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00952     const TensorChippingOp<Dynamic, const Derived>
00953     chip(const Index offset, const Index dim) const {
00954       return TensorChippingOp<Dynamic, const Derived>(derived(), offset, dim);
00955     }
00956     EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00957     TensorChippingOp<Dynamic, Derived>
00958     chip(const Index offset, const Index dim) {
00959       return TensorChippingOp<Dynamic, Derived>(derived(), offset, dim);
00960     }
00961 
00962     template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00963     const TensorReverseOp<const ReverseDimensions, const Derived>
00964     reverse(const ReverseDimensions& rev) const {
00965       return TensorReverseOp<const ReverseDimensions, const Derived>(derived(), rev);
00966     }
00967     template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00968     TensorReverseOp<const ReverseDimensions, Derived>
00969     reverse(const ReverseDimensions& rev) {
00970       return TensorReverseOp<const ReverseDimensions, Derived>(derived(), rev);
00971     }
00972 
00973     template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00974     const TensorShufflingOp<const Shuffle, const Derived>
00975     shuffle(const Shuffle& shuffle) const {
00976       return TensorShufflingOp<const Shuffle, const Derived>(derived(), shuffle);
00977     }
00978     template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00979     TensorShufflingOp<const Shuffle, Derived>
00980     shuffle(const Shuffle& shuffle) {
00981       return TensorShufflingOp<const Shuffle, Derived>(derived(), shuffle);
00982     }
00983 
00984     template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00985     const TensorStridingOp<const Strides, const Derived>
00986     stride(const Strides& strides) const {
00987       return TensorStridingOp<const Strides, const Derived>(derived(), strides);
00988     }
00989     template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
00990     TensorStridingOp<const Strides, Derived>
00991     stride(const Strides& strides) {
00992       return TensorStridingOp<const Strides, Derived>(derived(), strides);
00993     }
00994 
00995     // Select the device on which to evaluate the expression.
00996     template <typename DeviceType>
00997     TensorDevice<Derived, DeviceType> device(const DeviceType& device) {
00998       return TensorDevice<Derived, DeviceType>(device, derived());
00999     }
01000 
01001  protected:
01002     EIGEN_DEVICE_FUNC
01003     EIGEN_STRONG_INLINE Derived& derived() { return *static_cast<Derived*>(this); }
01004     EIGEN_DEVICE_FUNC
01005     EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); }
01006 };
01007 
01008 } // end namespace Eigen
01009 
01010 #endif // EIGEN_CXX11_TENSOR_TENSOR_BASE_H
 All Classes Functions Variables Typedefs Enumerator