// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_CXX11_TENSOR_TENSOR_BASE_H
#define EIGEN_CXX11_TENSOR_TENSOR_BASE_H

// clang-format off

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

/** \class TensorBase
  * \ingroup CXX11_Tensor_Module
  *
  * \brief The tensor base class.
  *
  * This class is the common parent of the Tensor and TensorMap class, thus
  * making it possible to use either class interchangeably in expressions.
  */
#ifndef EIGEN_PARSED_BY_DOXYGEN
// FIXME Doxygen does not like the inheritance with different template parameters
// Since there is no doxygen documentation inside, we disable it for now
template<typename Derived>
class TensorBase<Derived, ReadOnlyAccessors>
{
  public:
    typedef internal::traits<Derived> DerivedTraits;
    typedef typename DerivedTraits::Scalar Scalar;
    typedef typename DerivedTraits::Index Index;
    typedef std::remove_const_t<Scalar> CoeffReturnType;
    static constexpr int NumDimensions = DerivedTraits::NumDimensions;

    // Generic nullary operation support.
    template <typename CustomNullaryOp> EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<CustomNullaryOp, const Derived>
    nullaryExpr(const CustomNullaryOp& func) const {
      return TensorCwiseNullaryOp<CustomNullaryOp, const Derived>(derived(), func);
    }

    // Coefficient-wise nullary operators
    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived>
    constant(const Scalar& value) const {
      return nullaryExpr(internal::scalar_constant_op<Scalar>(value));
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<internal::UniformRandomGenerator<Scalar>, const Derived>
    random() const {
      return nullaryExpr(internal::UniformRandomGenerator<Scalar>());
    }
    template <typename RandomGenerator> EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseNullaryOp<RandomGenerator, const Derived>
    random(const RandomGenerator& gen = RandomGenerator()) const {
      return nullaryExpr(gen);
    }

    // Tensor generation
    template <typename Generator> EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorGeneratorOp<Generator, const Derived>
    generate(const Generator& generator) const {
      return TensorGeneratorOp<Generator, const Derived>(derived(), generator);
    }

    // Generic unary operation support.
    template <typename CustomUnaryOp> EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<CustomUnaryOp, const Derived>
    unaryExpr(const CustomUnaryOp& func) const {
      return TensorCwiseUnaryOp<CustomUnaryOp, const Derived>(derived(), func);
    }

    // Coefficient-wise unary operators
    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const Derived>
    operator-() const {
      return unaryExpr(internal::scalar_opposite_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sqrt_op<Scalar>, const Derived>
    sqrt() const {
      return unaryExpr(internal::scalar_sqrt_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_sign_op<Scalar>, const Derived>
    sign() const {
      return unaryExpr(internal::scalar_sign_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_rsqrt_op<Scalar>, const Derived>
    rsqrt() const {
      return unaryExpr(internal::scalar_rsqrt_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_square_op<Scalar>, const Derived>
    square() const {
      return unaryExpr(internal::scalar_square_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_cube_op<Scalar>, const Derived>
    cube() const {
      return unaryExpr(internal::scalar_cube_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const Derived>
    inverse() const {
      return unaryExpr(internal::scalar_inverse_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_tanh_op<Scalar>, const Derived>
    tanh() const {
      return unaryExpr(internal::scalar_tanh_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_lgamma_op<Scalar>, const Derived>
    lgamma() const {
      return unaryExpr(internal::scalar_lgamma_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_digamma_op<Scalar>, const Derived>
    digamma() const {
      return unaryExpr(internal::scalar_digamma_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_i0_op<Scalar>, const Derived>
    bessel_i0() const {
      return unaryExpr(internal::scalar_bessel_i0_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_i0e_op<Scalar>, const Derived>
    bessel_i0e() const {
      return unaryExpr(internal::scalar_bessel_i0e_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_i1_op<Scalar>, const Derived>
    bessel_i1() const {
      return unaryExpr(internal::scalar_bessel_i1_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_i1e_op<Scalar>, const Derived>
    bessel_i1e() const {
      return unaryExpr(internal::scalar_bessel_i1e_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_j0_op<Scalar>, const Derived>
    bessel_j0() const {
      return unaryExpr(internal::scalar_bessel_j0_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_y0_op<Scalar>, const Derived>
    bessel_y0() const {
      return unaryExpr(internal::scalar_bessel_y0_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_j1_op<Scalar>, const Derived>
    bessel_j1() const {
      return unaryExpr(internal::scalar_bessel_j1_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_y1_op<Scalar>, const Derived>
    bessel_y1() const {
      return unaryExpr(internal::scalar_bessel_y1_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_k0_op<Scalar>, const Derived>
    bessel_k0() const {
      return unaryExpr(internal::scalar_bessel_k0_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_k0e_op<Scalar>, const Derived>
    bessel_k0e() const {
      return unaryExpr(internal::scalar_bessel_k0e_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_k1_op<Scalar>, const Derived>
    bessel_k1() const {
      return unaryExpr(internal::scalar_bessel_k1_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_bessel_k1e_op<Scalar>, const Derived>
    bessel_k1e() const {
      return unaryExpr(internal::scalar_bessel_k1e_op<Scalar>());
    }

    // igamma(a = this, x = other)
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_igamma_op<Scalar>, const Derived, const OtherDerived>
    igamma(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_igamma_op<Scalar>());
    }

    // igamma_der_a(a = this, x = other)
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_igamma_der_a_op<Scalar>, const Derived, const OtherDerived>
    igamma_der_a(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_igamma_der_a_op<Scalar>());
    }

    // gamma_sample_der_alpha(alpha = this, sample = other)
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_gamma_sample_der_alpha_op<Scalar>, const Derived, const OtherDerived>
    gamma_sample_der_alpha(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_gamma_sample_der_alpha_op<Scalar>());
    }

    // igammac(a = this, x = other)
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_igammac_op<Scalar>, const Derived, const OtherDerived>
    igammac(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_igammac_op<Scalar>());
    }

    // zeta(x = this, q = other)
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_zeta_op<Scalar>, const Derived, const OtherDerived>
    zeta(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_zeta_op<Scalar>());
    }

    // polygamma(n = this, x = other)
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_polygamma_op<Scalar>, const Derived, const OtherDerived>
    polygamma(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_polygamma_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_erf_op<Scalar>, const Derived>
    erf() const {
      return unaryExpr(internal::scalar_erf_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_erfc_op<Scalar>, const Derived>
    erfc() const {
      return unaryExpr(internal::scalar_erfc_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_ndtri_op<Scalar>, const Derived>
    ndtri() const {
      return unaryExpr(internal::scalar_ndtri_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_logistic_op<Scalar>, const Derived>
    sigmoid() const {
      return unaryExpr(internal::scalar_logistic_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_exp_op<Scalar>, const Derived>
    exp() const {
      return unaryExpr(internal::scalar_exp_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_expm1_op<Scalar>, const Derived>
    expm1() const {
      return unaryExpr(internal::scalar_expm1_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log_op<Scalar>, const Derived>
    log() const {
      return unaryExpr(internal::scalar_log_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log1p_op<Scalar>, const Derived>
    log1p() const {
      return unaryExpr(internal::scalar_log1p_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_log2_op<Scalar>, const Derived>
    log2() const {
      return unaryExpr(internal::scalar_log2_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_abs_op<Scalar>, const Derived>
    abs() const {
      return unaryExpr(internal::scalar_abs_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_arg_op<Scalar>, const Derived>
    arg() const {
      return unaryExpr(internal::scalar_arg_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_clamp_op<Scalar>, const Derived>
    clip(Scalar min, Scalar max) const {
      return unaryExpr(internal::scalar_clamp_op<Scalar>(min, max));
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const std::conditional_t<NumTraits<CoeffReturnType>::IsComplex,
                                                      TensorCwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, const Derived>,
                                                      Derived>
    conjugate() const {
      return choose(Cond<NumTraits<CoeffReturnType>::IsComplex>(), unaryExpr(internal::scalar_conjugate_op<Scalar>()), derived());
    }

    template<typename ScalarExponent>
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const std::enable_if_t<internal::is_arithmetic<typename NumTraits<ScalarExponent>::Real>::value,
        TensorCwiseUnaryOp<internal::scalar_unary_pow_op<Scalar, ScalarExponent>, const Derived>>
        pow(ScalarExponent exponent) const
    {
        return unaryExpr(internal::scalar_unary_pow_op<Scalar, ScalarExponent>(exponent));
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_real_op<Scalar>, const Derived>
    real() const {
      return unaryExpr(internal::scalar_real_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_imag_op<Scalar>, const Derived>
    imag() const {
      return unaryExpr(internal::scalar_imag_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_sum_op<Scalar,Scalar> >, const Derived>
    operator+ (Scalar rhs) const {
      return unaryExpr(internal::bind2nd_op<internal::scalar_sum_op<Scalar,Scalar> >(rhs));
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE friend
    const TensorCwiseUnaryOp<internal::bind1st_op<internal::scalar_sum_op<Scalar> >, const Derived>
    operator+ (Scalar lhs, const Derived& rhs) {
      return rhs.unaryExpr(internal::bind1st_op<internal::scalar_sum_op<Scalar> >(lhs));
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_difference_op<Scalar,Scalar> >, const Derived>
    operator- (Scalar rhs) const {
      EIGEN_STATIC_ASSERT((NumTraits<Scalar>::IsSigned || internal::is_same<Scalar, const std::complex<float> >::value), YOU_MADE_A_PROGRAMMING_MISTAKE);
      return unaryExpr(internal::bind2nd_op<internal::scalar_difference_op<Scalar,Scalar> >(rhs));
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE friend
    const TensorCwiseUnaryOp<internal::bind1st_op<internal::scalar_difference_op<Scalar> >, const Derived>
    operator- (Scalar lhs, const Derived& rhs) {
      return rhs.unaryExpr(internal::bind1st_op<internal::scalar_difference_op<Scalar> >(lhs));
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_product_op<Scalar,Scalar> >, const Derived>
    operator* (Scalar rhs) const {
      return unaryExpr(internal::bind2nd_op<internal::scalar_product_op<Scalar,Scalar> >(rhs));
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE friend
    const TensorCwiseUnaryOp<internal::bind1st_op<internal::scalar_product_op<Scalar> >, const Derived>
    operator* (Scalar lhs, const Derived& rhs) {
      return rhs.unaryExpr(internal::bind1st_op<internal::scalar_product_op<Scalar> >(lhs));
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::bind2nd_op<internal::scalar_quotient_op<Scalar,Scalar> >, const Derived>
    operator/ (Scalar rhs) const {
      return unaryExpr(internal::bind2nd_op<internal::scalar_quotient_op<Scalar,Scalar> >(rhs));
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE friend
    const TensorCwiseUnaryOp<internal::bind1st_op<internal::scalar_quotient_op<Scalar> >, const Derived>
    operator/ (Scalar lhs, const Derived& rhs) {
      return rhs.unaryExpr(internal::bind1st_op<internal::scalar_quotient_op<Scalar> >(lhs));
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_mod_op<Scalar>, const Derived>
    operator% (Scalar rhs) const {
      EIGEN_STATIC_ASSERT(NumTraits<Scalar>::IsInteger, YOU_MADE_A_PROGRAMMING_MISTAKE_TRY_MOD);
      return unaryExpr(internal::scalar_mod_op<Scalar>(rhs));
    }

    template <int NanPropagation=PropagateFast>
    EIGEN_DEVICE_FUNC
        EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar,NanPropagation>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
    cwiseMax(Scalar threshold) const {
      return cwiseMax<NanPropagation>(constant(threshold));
    }

    template <int NanPropagation=PropagateFast>
    EIGEN_DEVICE_FUNC
        EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar,NanPropagation>, const Derived, const TensorCwiseNullaryOp<internal::scalar_constant_op<Scalar>, const Derived> >
    cwiseMin(Scalar threshold) const {
      return cwiseMin<NanPropagation>(constant(threshold));
    }

    template<typename NewType>
    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const std::conditional_t<internal::is_same<NewType, CoeffReturnType>::value,
                                                      Derived,
                                                      TensorConversionOp<NewType, const Derived> >
    cast() const {
      return choose(Cond<internal::is_same<NewType, CoeffReturnType>::value>(), derived(), TensorConversionOp<NewType, const Derived>(derived()));
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_round_op<Scalar>, const Derived>
    round() const {
      return unaryExpr(internal::scalar_round_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_rint_op<Scalar>, const Derived>
    rint() const {
      return unaryExpr(internal::scalar_rint_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_ceil_op<Scalar>, const Derived>
    ceil() const {
      return unaryExpr(internal::scalar_ceil_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_floor_op<Scalar>, const Derived>
    floor() const {
      return unaryExpr(internal::scalar_floor_op<Scalar>());
    }

    // Generic binary operation support.
    template <typename CustomBinaryOp, typename OtherDerived> EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>
    binaryExpr(const OtherDerived& other, const CustomBinaryOp& func) const {
      return TensorCwiseBinaryOp<CustomBinaryOp, const Derived, const OtherDerived>(derived(), other, func);
    }

    // Coefficient-wise binary operators.
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Derived, const OtherDerived>
    operator+(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_sum_op<Scalar>());
    }

    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_difference_op<Scalar>, const Derived, const OtherDerived>
    operator-(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_difference_op<Scalar>());
    }

    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_product_op<Scalar>, const Derived, const OtherDerived>
    operator*(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_product_op<Scalar>());
    }

    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, const Derived, const OtherDerived>
    operator/(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_quotient_op<Scalar>());
    }

    template<int NaNPropagation=PropagateFast, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar, NaNPropagation>, const Derived, const OtherDerived>
    cwiseMax(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_max_op<Scalar,Scalar, NaNPropagation>());
    }

    template<int NaNPropagation=PropagateFast, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar, NaNPropagation>, const Derived, const OtherDerived>
    cwiseMin(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_min_op<Scalar,Scalar, NaNPropagation>());
    }

    // logical operators
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_boolean_and_op<Scalar>, const Derived, const OtherDerived>
    operator&&(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_boolean_and_op<Scalar>());
    }

    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_boolean_or_op<Scalar>, const Derived, const OtherDerived>
    operator||(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_boolean_or_op<Scalar>());
    }

    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_bitwise_and_op<Scalar>, const Derived, const OtherDerived>
    operator&(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_bitwise_and_op<Scalar>());
    }

    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_bitwise_or_op<Scalar>, const Derived, const OtherDerived>
    operator|(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_bitwise_or_op<Scalar>());
    }

    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_bitwise_xor_op<Scalar>, const Derived, const OtherDerived>
    operator^(const OtherDerived& other) const {
      return binaryExpr(other.derived(), internal::scalar_bitwise_xor_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseUnaryOp<internal::scalar_boolean_not_op<Scalar>, const Derived>
    operator!() const {
      return unaryExpr(internal::scalar_boolean_not_op<Scalar>());
    }

    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseUnaryOp<internal::scalar_bitwise_not_op<Scalar>, const Derived>
    operator~() const {
      return unaryExpr(internal::scalar_bitwise_not_op<Scalar>());
    }

    // Comparisons and tests.
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LT>, const Derived, const OtherDerived>
    operator<(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
      return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LT>());
    }
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LE>, const Derived, const OtherDerived>
    operator<=(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
      return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LE>());
    }
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GT>, const Derived, const OtherDerived>
    operator>(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
      return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GT>());
    }
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GE>, const Derived, const OtherDerived>
    operator>=(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
      return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GE>());
    }

    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_EQ>, const Derived, const OtherDerived>
    operator==(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
      return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_EQ>());
    }

    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_NEQ>, const Derived, const OtherDerived>
    operator!=(const TensorBase<OtherDerived, ReadOnlyAccessors>& other) const {
      return binaryExpr(other.derived(), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_NEQ>());
    }

    // comparisons and tests for Scalars
    EIGEN_DEVICE_FUNC
    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> >
    operator<(Scalar threshold) const {
      return operator<(constant(threshold));
    }
    EIGEN_DEVICE_FUNC
    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> >
    operator<=(Scalar threshold) const {
      return operator<=(constant(threshold));
    }
    EIGEN_DEVICE_FUNC
    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> >
    operator>(Scalar threshold) const {
      return operator>(constant(threshold));
    }
    EIGEN_DEVICE_FUNC
    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> >
    operator>=(Scalar threshold) const {
      return operator>=(constant(threshold));
    }
    EIGEN_DEVICE_FUNC
    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> >
    operator==(Scalar threshold) const {
      return operator==(constant(threshold));
    }
    EIGEN_DEVICE_FUNC
    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> >
    operator!=(Scalar threshold) const {
      return operator!=(constant(threshold));
    }

    // Predicates.
    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorConversionOp<bool, const TensorCwiseUnaryOp<internal::scalar_isnan_op<Scalar, true>, const Derived>>
    (isnan)() const {
      return unaryExpr(internal::scalar_isnan_op<Scalar, true>()).template cast<bool>();
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_isinf_op<Scalar>, const Derived>
    (isinf)() const {
      return unaryExpr(internal::scalar_isinf_op<Scalar>());
    }
    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const TensorCwiseUnaryOp<internal::scalar_isfinite_op<Scalar>, const Derived>
    (isfinite)() const {
      return unaryExpr(internal::scalar_isfinite_op<Scalar>());
    }

    // Coefficient-wise ternary operators.
    template<typename ThenDerived, typename ElseDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorSelectOp<const Derived, const ThenDerived, const ElseDerived>
    select(const ThenDerived& thenTensor, const ElseDerived& elseTensor) const {
      return TensorSelectOp<const Derived, const ThenDerived, const ElseDerived>(derived(), thenTensor.derived(), elseTensor.derived());
    }

    // Contractions.
    typedef Eigen::IndexPair<Index> DimensionPair;

    template<typename OtherDerived, typename Dimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorContractionOp<const Dimensions, const Derived, const OtherDerived, const NoOpOutputKernel>
    contract(const OtherDerived& other, const Dimensions& dims) const {
      return TensorContractionOp<const Dimensions, const Derived, const OtherDerived, const NoOpOutputKernel>(derived(), other.derived(), dims);
    }

    template<typename OtherDerived, typename Dimensions, typename OutputKernel> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorContractionOp<const Dimensions, const Derived, const OtherDerived, const OutputKernel>
    contract(const OtherDerived& other, const Dimensions& dims, const OutputKernel& output_kernel) const {
      return TensorContractionOp<const Dimensions, const Derived, const OtherDerived, const OutputKernel>(derived(), other.derived(), dims, output_kernel);
    }

    // Convolutions.
    template<typename KernelDerived, typename Dimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorConvolutionOp<const Dimensions, const Derived, const KernelDerived>
    convolve(const KernelDerived& kernel, const Dimensions& dims) const {
      return TensorConvolutionOp<const Dimensions, const Derived, const KernelDerived>(derived(), kernel.derived(), dims);
    }

    // Fourier transforms
    template <int FFTDataType, int FFTDirection, typename FFT> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorFFTOp<const FFT, const Derived, FFTDataType, FFTDirection>
    fft(const FFT& dims) const {
      return TensorFFTOp<const FFT, const Derived, FFTDataType, FFTDirection>(derived(), dims);
    }

    // Scan.
    typedef TensorScanOp<internal::SumReducer<CoeffReturnType>, const Derived> TensorScanSumOp;
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorScanSumOp
    cumsum(const Index& axis, bool exclusive = false) const {
      return TensorScanSumOp(derived(), axis, exclusive);
    }

    typedef TensorScanOp<internal::ProdReducer<CoeffReturnType>, const Derived> TensorScanProdOp;
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorScanProdOp
    cumprod(const Index& axis, bool exclusive = false) const {
      return TensorScanProdOp(derived(), axis, exclusive);
    }

    template <typename Reducer>
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorScanOp<Reducer, const Derived>
    scan(const Index& axis, const Reducer& reducer, bool exclusive = false) const {
      return TensorScanOp<Reducer, const Derived>(derived(), axis, exclusive, reducer);
    }

    // Reductions.
    template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReductionOp<internal::SumReducer<CoeffReturnType>, const Dims, const Derived>
    sum(const Dims& dims) const {
      return TensorReductionOp<internal::SumReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::SumReducer<CoeffReturnType>());
    }

    const TensorReductionOp<internal::SumReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
    sum() const {
      DimensionList<Index, NumDimensions> in_dims;
      return TensorReductionOp<internal::SumReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::SumReducer<CoeffReturnType>());
    }

    template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const Dims, const Derived>
    mean(const Dims& dims) const {
      return TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::MeanReducer<CoeffReturnType>());
    }

    const TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
    mean() const {
      DimensionList<Index, NumDimensions> in_dims;
      return TensorReductionOp<internal::MeanReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MeanReducer<CoeffReturnType>());
    }

    template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const Dims, const Derived>
    prod(const Dims& dims) const {
      return TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const Dims, const Derived>(derived(), dims, internal::ProdReducer<CoeffReturnType>());
    }

    const TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>
    prod() const {
      DimensionList<Index, NumDimensions> in_dims;
      return TensorReductionOp<internal::ProdReducer<CoeffReturnType>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::ProdReducer<CoeffReturnType>());
    }

    template <typename Dims,int NanPropagation=PropagateFast> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReductionOp<internal::MaxReducer<CoeffReturnType,NanPropagation>, const Dims, const Derived>
    maximum(const Dims& dims) const {
      return TensorReductionOp<internal::MaxReducer<CoeffReturnType,NanPropagation>, const Dims, const Derived>(derived(), dims, internal::MaxReducer<CoeffReturnType,NanPropagation>());
    }

    template <int NanPropagation=PropagateFast>
    const TensorReductionOp<internal::MaxReducer<CoeffReturnType,NanPropagation>, const DimensionList<Index, NumDimensions>, const Derived>
    maximum() const {
      DimensionList<Index, NumDimensions> in_dims;
      return TensorReductionOp<internal::MaxReducer<CoeffReturnType,NanPropagation>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MaxReducer<CoeffReturnType,NanPropagation>());
    }

    template <typename Dims,int NanPropagation=PropagateFast> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReductionOp<internal::MinReducer<CoeffReturnType,NanPropagation>, const Dims, const Derived>
    minimum(const Dims& dims) const {
      return TensorReductionOp<internal::MinReducer<CoeffReturnType,NanPropagation>, const Dims, const Derived>(derived(), dims, internal::MinReducer<CoeffReturnType,NanPropagation>());
    }

    template <int NanPropagation=PropagateFast>
    const TensorReductionOp<internal::MinReducer<CoeffReturnType,NanPropagation>, const DimensionList<Index, NumDimensions>, const Derived>
    minimum() const {
      DimensionList<Index, NumDimensions> in_dims;
      return TensorReductionOp<internal::MinReducer<CoeffReturnType,NanPropagation>, const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims, internal::MinReducer<CoeffReturnType,NanPropagation>());
    }

    template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReductionOp<internal::AndReducer, const Dims, const std::conditional_t<internal::is_same<bool, CoeffReturnType>::value, Derived, TensorConversionOp<bool, const Derived> > >
    all(const Dims& dims) const {
      return cast<bool>().reduce(dims, internal::AndReducer());
    }

    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReductionOp<internal::AndReducer, const DimensionList<Index, NumDimensions>, const std::conditional_t<internal::is_same<bool, CoeffReturnType>::value, Derived, TensorConversionOp<bool, const Derived> > >
    all() const {
      DimensionList<Index, NumDimensions> in_dims;
      return cast<bool>().reduce(in_dims, internal::AndReducer());
    }

    template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReductionOp<internal::OrReducer, const Dims, const std::conditional_t<internal::is_same<bool, CoeffReturnType>::value, Derived, TensorConversionOp<bool, const Derived> > >
    any(const Dims& dims) const {
      return cast<bool>().reduce(dims, internal::OrReducer());
    }

    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReductionOp<internal::OrReducer, const DimensionList<Index, NumDimensions>, const std::conditional_t<internal::is_same<bool, CoeffReturnType>::value, Derived, TensorConversionOp<bool, const Derived> > >
    any() const {
      DimensionList<Index, NumDimensions> in_dims;
      return cast<bool>().reduce(in_dims, internal::OrReducer());
    }

   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorPairReducerOp<
      internal::ArgMaxPairReducer<Pair<Index, CoeffReturnType> >,
      const array<Index, NumDimensions>, const Derived>
    argmax() const {
      array<Index, NumDimensions> in_dims;
      for (Index d = 0; d < NumDimensions; ++d) in_dims[d] = d;
      return TensorPairReducerOp<
        internal::ArgMaxPairReducer<Pair<Index, CoeffReturnType> >,
        const array<Index, NumDimensions>,
        const Derived>(derived(), internal::ArgMaxPairReducer<Pair<Index, CoeffReturnType> >(), -1, in_dims);
    }

    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorPairReducerOp<
      internal::ArgMinPairReducer<Pair<Index, CoeffReturnType> >,
      const array<Index, NumDimensions>, const Derived>
    argmin() const {
      array<Index, NumDimensions> in_dims;
      for (Index d = 0; d < NumDimensions; ++d) in_dims[d] = d;
      return TensorPairReducerOp<
        internal::ArgMinPairReducer<Pair<Index, CoeffReturnType> >,
        const array<Index, NumDimensions>,
        const Derived>(derived(), internal::ArgMinPairReducer<Pair<Index, CoeffReturnType> >(), -1, in_dims);
    }

    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorPairReducerOp<
      internal::ArgMaxPairReducer<Pair<Index, CoeffReturnType> >,
      const array<Index, 1>, const Derived>
    argmax(const Index return_dim) const {
      array<Index, 1> in_dims;
      in_dims[0] = return_dim;
      return TensorPairReducerOp<
        internal::ArgMaxPairReducer<Pair<Index, CoeffReturnType> >,
        const array<Index, 1>,
        const Derived>(derived(), internal::ArgMaxPairReducer<Pair<Index, CoeffReturnType> >(), return_dim, in_dims);
    }

    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorPairReducerOp<
      internal::ArgMinPairReducer<Pair<Index, CoeffReturnType> >,
      const array<Index, 1>, const Derived>
    argmin(const Index return_dim) const {
      array<Index, 1> in_dims;
      in_dims[0] = return_dim;
      return TensorPairReducerOp<
        internal::ArgMinPairReducer<Pair<Index, CoeffReturnType> >,
        const array<Index, 1>,
        const Derived>(derived(), internal::ArgMinPairReducer<Pair<Index, CoeffReturnType> >(), return_dim, in_dims);
    }

    template <typename Reducer, typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReductionOp<Reducer, const Dims, const Derived>
    reduce(const Dims& dims, const Reducer& reducer) const {
      return TensorReductionOp<Reducer, const Dims, const Derived>(derived(), dims, reducer);
    }

    template <typename Dims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorTraceOp<const Dims, const Derived>
    trace(const Dims& dims) const {
      return TensorTraceOp<const Dims, const Derived>(derived(), dims);
    }

    const TensorTraceOp<const DimensionList<Index, NumDimensions>, const Derived>
    trace() const {
      DimensionList<Index, NumDimensions> in_dims;
      return TensorTraceOp<const DimensionList<Index, NumDimensions>, const Derived>(derived(), in_dims);
    }

    template <typename Broadcast> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorBroadcastingOp<const Broadcast, const Derived>
    broadcast(const Broadcast& bcast) const {
      return TensorBroadcastingOp<const Broadcast, const Derived>(derived(), bcast);
    }

    template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorConcatenationOp<Axis, const Derived, const OtherDerived>
    concatenate(const OtherDerived& other, Axis axis) const {
      return TensorConcatenationOp<Axis, const Derived, const OtherDerived>(derived(), other.derived(), axis);
    }

    template <typename PatchDims> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorPatchOp<const PatchDims, const Derived>
    extract_patches(const PatchDims& patch_dims) const {
      return TensorPatchOp<const PatchDims, const Derived>(derived(), patch_dims);
    }

    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorImagePatchOp<Dynamic, Dynamic, const Derived>
    extract_image_patches(const Index patch_rows = 1, const Index patch_cols = 1,
                          const Index row_stride = 1, const Index col_stride = 1,
                          const Index in_row_stride = 1, const Index in_col_stride = 1,
                          const PaddingType padding_type = PADDING_SAME, const Scalar padding_value = Scalar(0)) const {
      return TensorImagePatchOp<Dynamic, Dynamic, const Derived>(derived(), patch_rows, patch_cols, row_stride, col_stride,
                                                                 in_row_stride, in_col_stride, 1, 1, padding_type, padding_value);
    }

    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorImagePatchOp<Dynamic, Dynamic, const Derived>
    extract_image_patches(const Index patch_rows, const Index patch_cols,
                          const Index row_stride, const Index col_stride,
                          const Index in_row_stride, const Index in_col_stride,
                          const Index row_inflate_stride, const Index col_inflate_stride,
                          const Index padding_top, const Index padding_bottom,
                          const Index padding_left,const Index padding_right,
                          const Scalar padding_value) const {
      return TensorImagePatchOp<Dynamic, Dynamic, const Derived>(derived(), patch_rows, patch_cols, row_stride, col_stride,
                                                                 in_row_stride, in_col_stride, row_inflate_stride, col_inflate_stride,
                                                                 padding_top, padding_bottom, padding_left, padding_right, padding_value);
    }

    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>
    extract_volume_patches(const Index patch_planes, const Index patch_rows, const Index patch_cols,
                           const Index plane_stride = 1, const Index row_stride = 1, const Index col_stride = 1,
                           const PaddingType padding_type = PADDING_SAME, const Scalar padding_value = Scalar(0)) const {
      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);
    }


    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorVolumePatchOp<Dynamic, Dynamic, Dynamic, const Derived>
    extract_volume_patches(const Index patch_planes, const Index patch_rows, const Index patch_cols,
                           const Index plane_stride, const Index row_stride, const Index col_stride,
                           const Index plane_inflate_stride, const Index row_inflate_stride, const Index col_inflate_stride,
                           const Index padding_top_z, const Index padding_bottom_z,
                           const Index padding_top, const Index padding_bottom,
                           const Index padding_left, const Index padding_right, const Scalar padding_value = Scalar(0)) const {
      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);
    }

    // Morphing operators.
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorLayoutSwapOp<const Derived>
    swap_layout() const {
      return TensorLayoutSwapOp<const Derived>(derived());
    }
    template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReshapingOp<const NewDimensions, const Derived>
    reshape(const NewDimensions& newDimensions) const {
      return TensorReshapingOp<const NewDimensions, const Derived>(derived(), newDimensions);
    }
    template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorSlicingOp<const StartIndices, const Sizes, const Derived>
    slice(const StartIndices& startIndices, const Sizes& sizes) const {
      return TensorSlicingOp<const StartIndices, const Sizes, const Derived>(derived(), startIndices, sizes);
    }
    template <typename StartIndices, typename StopIndices, typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides, const Derived>
    stridedSlice(const StartIndices& startIndices, const StopIndices& stopIndices, const Strides& strides) const {
      return TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides,
                                const Derived>(derived(), startIndices, stopIndices, strides);
    }
    template <Index DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorChippingOp<DimId, const Derived>
    chip(const Index offset) const {
      EIGEN_STATIC_ASSERT(DimId < Derived::NumDimensions && DimId >= 0, Chip_Dim_out_of_range)
      return TensorChippingOp<DimId, const Derived>(derived(), offset, DimId);
    }
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorChippingOp<Dynamic, const Derived>
    chip(const Index offset, const Index dim) const {
      return TensorChippingOp<Dynamic, const Derived>(derived(), offset, dim);
    }
    template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReverseOp<const ReverseDimensions, const Derived>
    reverse(const ReverseDimensions& rev) const {
      return TensorReverseOp<const ReverseDimensions, const Derived>(derived(), rev);
    }
    template <typename PaddingDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorPaddingOp<const PaddingDimensions, const Derived>
    pad(const PaddingDimensions& padding) const {
      return TensorPaddingOp<const PaddingDimensions, const Derived>(derived(), padding, internal::scalar_cast_op<int, Scalar>()(0));
    }
    template <typename PaddingDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorPaddingOp<const PaddingDimensions, const Derived>
    pad(const PaddingDimensions& padding, const Scalar padding_value) const {
      return TensorPaddingOp<const PaddingDimensions, const Derived>(derived(), padding, padding_value);
    }
    template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorShufflingOp<const Shuffle, const Derived>
    shuffle(const Shuffle& shfl) const {
      return TensorShufflingOp<const Shuffle, const Derived>(derived(), shfl);
    }
    template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorStridingOp<const Strides, const Derived>
    stride(const Strides& strides) const {
      return TensorStridingOp<const Strides, const Derived>(derived(), strides);
    }
    template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorInflationOp<const Strides, const Derived>
    inflate(const Strides& strides) const {
      return TensorInflationOp<const Strides, const Derived>(derived(), strides);
    }

    // Returns a tensor containing index/value pairs
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorIndexPairOp<const Derived>
    index_pairs() const {
      return TensorIndexPairOp<const Derived>(derived());
    }

    // Support for custom unary and binary operations
    template <typename CustomUnaryFunc>
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCustomUnaryOp<const CustomUnaryFunc, const Derived> customOp(const CustomUnaryFunc& op) const {
      return TensorCustomUnaryOp<const CustomUnaryFunc, const Derived>(derived(), op);
    }
    template <typename OtherDerived, typename CustomBinaryFunc>
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorCustomBinaryOp<const CustomBinaryFunc, const Derived, const OtherDerived> customOp(const OtherDerived& other, const CustomBinaryFunc& op) const {
      return TensorCustomBinaryOp<const CustomBinaryFunc, const Derived, const OtherDerived>(derived(), other, op);
    }

    // Force the evaluation of the expression.
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorForcedEvalOp<const Derived> eval() const {
      return TensorForcedEvalOp<const Derived>(derived());
    }

    // Returns a formatted tensor ready for printing to a stream
    template<typename Format>
    inline const TensorWithFormat<Derived,DerivedTraits::Layout,DerivedTraits::NumDimensions, Format> format(const Format& fmt) const {
      return TensorWithFormat<Derived,DerivedTraits::Layout,DerivedTraits::NumDimensions, Format>(derived(), fmt);
    }

    #ifdef EIGEN_READONLY_TENSORBASE_PLUGIN
    #include EIGEN_READONLY_TENSORBASE_PLUGIN
    #endif

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); }

  protected:
    template <typename Scalar, int NumIndices, int Options, typename IndexType> friend class Tensor;
    template <typename Scalar, typename Dimensions, int Option, typename IndexTypes> friend class TensorFixedSize;
    // the Eigen:: prefix is required to workaround a compilation issue with nvcc 9.0
    template <typename OtherDerived, int AccessLevel> friend class Eigen::TensorBase;
};

template<typename Derived, int AccessLevel = internal::accessors_level<Derived>::value>
class TensorBase : public TensorBase<Derived, ReadOnlyAccessors> {
 public:
    typedef TensorBase<Derived, ReadOnlyAccessors> Base;
    typedef internal::traits<Derived> DerivedTraits;
    typedef typename DerivedTraits::Scalar Scalar;
    typedef typename DerivedTraits::Index Index;
    typedef Scalar CoeffReturnType;
    static constexpr int NumDimensions = DerivedTraits::NumDimensions;

    template <typename Scalar, int NumIndices, int Options, typename IndexType> friend class Tensor;
    template <typename Scalar, typename Dimensions, int Option, typename IndexTypes> friend class TensorFixedSize;
    // the Eigen:: prefix is required to workaround a compilation issue with nvcc 9.0
    template <typename OtherDerived, int OtherAccessLevel> friend class Eigen::TensorBase;

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE Derived& setZero() {
      return setConstant(Scalar(0));
    }
    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE Derived& setConstant(const Scalar& val) {
      return derived() = this->constant(val);
    }
    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE Derived& setRandom() {
      return derived() = this->random();
    }
    template <typename RandomGenerator> EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE Derived& setRandom() {
      return derived() = this->template random<RandomGenerator>();
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE Derived& setValues(
        const typename internal::Initializer<Derived, NumDimensions>::InitList& vals) {
      TensorEvaluator<Derived, DefaultDevice> eval(derived(), DefaultDevice());
      internal::initialize_tensor<Derived, NumDimensions>(eval, vals);
      return derived();
    }

    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    Derived& operator+=(const OtherDerived& other) {
      return derived() = derived() + other.derived();
    }
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    Derived& operator-=(const OtherDerived& other) {
      return derived() = derived() - other.derived();
    }
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    Derived& operator*=(const OtherDerived& other) {
      return derived() = derived() * other.derived();
    }
    template<typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    Derived& operator/=(const OtherDerived& other) {
      return derived() = derived() / other.derived();
    }

    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorLayoutSwapOp<const Derived>
    swap_layout() const {
      return TensorLayoutSwapOp<const Derived>(derived());
    }
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    TensorLayoutSwapOp<Derived>
    swap_layout() {
      return TensorLayoutSwapOp<Derived>(derived());
    }

    template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorConcatenationOp<const Axis, const Derived, const OtherDerived>
    concatenate(const OtherDerived& other, const Axis& axis) const {
      return TensorConcatenationOp<const Axis, const Derived, const OtherDerived>(derived(), other, axis);
    }
    template <typename Axis, typename OtherDerived> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    TensorConcatenationOp<const Axis, Derived, OtherDerived>
    concatenate(const OtherDerived& other, const Axis& axis) {
      return TensorConcatenationOp<const Axis, Derived, OtherDerived>(derived(), other, axis);
    }

    template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReshapingOp<const NewDimensions, const Derived>
    reshape(const NewDimensions& newDimensions) const {
      return TensorReshapingOp<const NewDimensions, const Derived>(derived(), newDimensions);
    }
    template <typename NewDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    TensorReshapingOp<const NewDimensions, Derived>
    reshape(const NewDimensions& newDimensions) {
      return TensorReshapingOp<const NewDimensions, Derived>(derived(), newDimensions);
    }

    template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorSlicingOp<const StartIndices, const Sizes, const Derived>
    slice(const StartIndices& startIndices, const Sizes& sizes) const {
      return TensorSlicingOp<const StartIndices, const Sizes, const Derived>(derived(), startIndices, sizes);
    }
    template <typename StartIndices, typename Sizes> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    TensorSlicingOp<const StartIndices, const Sizes, Derived>
    slice(const StartIndices& startIndices, const Sizes& sizes) {
      return TensorSlicingOp<const StartIndices, const Sizes, Derived>(derived(), startIndices, sizes);
    }

    template <typename StartIndices, typename StopIndices, typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides, const Derived>
    stridedSlice(const StartIndices& startIndices, const StopIndices& stopIndices, const Strides& strides) const {
      return TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides,
                                const Derived>(derived(), startIndices, stopIndices, strides);
    }
    template <typename StartIndices, typename StopIndices, typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides, Derived>
    stridedSlice(const StartIndices& startIndices, const StopIndices& stopIndices, const Strides& strides) {
      return TensorStridingSlicingOp<const StartIndices, const StopIndices, const Strides,
                                Derived>(derived(), startIndices, stopIndices, strides);
    }

    template <DenseIndex DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorChippingOp<DimId, const Derived>
    chip(const Index offset) const {
      EIGEN_STATIC_ASSERT(DimId < Derived::NumDimensions && DimId >= 0, Chip_Dim_out_of_range)
      return TensorChippingOp<DimId, const Derived>(derived(), offset, DimId);
    }
    template <Index DimId> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    TensorChippingOp<DimId, Derived>
    chip(const Index offset) {
      EIGEN_STATIC_ASSERT(DimId < Derived::NumDimensions && DimId >= 0, Chip_Dim_out_of_range)
      return TensorChippingOp<DimId, Derived>(derived(), offset, DimId);
    }

    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorChippingOp<Dynamic, const Derived>
    chip(const Index offset, const Index dim) const {
      return TensorChippingOp<Dynamic, const Derived>(derived(), offset, dim);
    }
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    TensorChippingOp<Dynamic, Derived>
    chip(const Index offset, const Index dim) {
      return TensorChippingOp<Dynamic, Derived>(derived(), offset, dim);
    }

    template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorReverseOp<const ReverseDimensions, const Derived>
    reverse(const ReverseDimensions& rev) const {
      return TensorReverseOp<const ReverseDimensions, const Derived>(derived(), rev);
    }
    template <typename ReverseDimensions> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    TensorReverseOp<const ReverseDimensions, Derived>
    reverse(const ReverseDimensions& rev) {
      return TensorReverseOp<const ReverseDimensions, Derived>(derived(), rev);
    }

    template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorShufflingOp<const Shuffle, const Derived>
    shuffle(const Shuffle& shfl) const {
      return TensorShufflingOp<const Shuffle, const Derived>(derived(), shfl);
    }
    template <typename Shuffle> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    TensorShufflingOp<const Shuffle, Derived>
    shuffle(const Shuffle& shfl) {
      return TensorShufflingOp<const Shuffle, Derived>(derived(), shfl);
    }

    template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    const TensorStridingOp<const Strides, const Derived>
    stride(const Strides& strides) const {
      return TensorStridingOp<const Strides, const Derived>(derived(), strides);
    }
    template <typename Strides> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    TensorStridingOp<const Strides, Derived>
    stride(const Strides& strides) {
      return TensorStridingOp<const Strides, Derived>(derived(), strides);
    }

    // Select the device on which to evaluate the expression.
    template <typename DeviceType>
    TensorDevice<Derived, DeviceType> device(const DeviceType& dev) {
      return TensorDevice<Derived, DeviceType>(dev, derived());
    }

    // Select the async device on which to evaluate the expression.
    template <typename DeviceType, typename DoneCallback>
    TensorAsyncDevice<Derived, DeviceType, DoneCallback> device(const DeviceType& dev, DoneCallback done) {
      return TensorAsyncDevice<Derived, DeviceType, DoneCallback>(dev, derived(), std::move(done));
    }

    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE Derived& derived() { return *static_cast<Derived*>(this); }
    EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE const Derived& derived() const { return *static_cast<const Derived*>(this); }

    #ifdef EIGEN_TENSORBASE_PLUGIN
    #include EIGEN_TENSORBASE_PLUGIN
    #endif

 protected:
    EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(TensorBase)
    EIGEN_DEFAULT_COPY_CONSTRUCTOR(TensorBase)

    template<typename OtherDerived> EIGEN_DEVICE_FUNC
    EIGEN_STRONG_INLINE Derived& operator=(const OtherDerived& other)
    {
      typedef TensorAssignOp<Derived, const OtherDerived> Assign;
      Assign assign(derived(), other.derived());
      internal::TensorExecutor<const Assign, DefaultDevice>::run(assign, DefaultDevice());
      return derived();
    }
};
#endif // EIGEN_PARSED_BY_DOXYGEN
} // end namespace Eigen

#endif // EIGEN_CXX11_TENSOR_TENSOR_BASE_H
