12b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// This file is part of Eigen, a lightweight C++ template library
22b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// for linear algebra.
32b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang//
42b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
52b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang//
62b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// This Source Code Form is subject to the terms of the Mozilla
72b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Public License v. 2.0. If a copy of the MPL was not distributed
82b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
92b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifndef EIGEN_CXX11_TENSOR_TENSOR_EXPR_H
112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#define EIGEN_CXX11_TENSOR_TENSOR_EXPR_H
122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace Eigen {
142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \class TensorExpr
162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \ingroup CXX11_Tensor_Module
172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *
182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \brief Tensor expression classes.
192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *
202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * The TensorCwiseNullaryOp class applies a nullary operators to an expression.
212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * This is typically used to generate constants.
222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *
232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * The TensorCwiseUnaryOp class represents an expression where a unary operator
242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * (e.g. cwiseSqrt) is applied to an expression.
252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *
262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * The TensorCwiseBinaryOp class represents an expression where a binary
272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * operator (e.g. addition) is applied to a lhs and a rhs expression.
282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *
292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  */
302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal {
312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename NullaryOp, typename XprType>
322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct traits<TensorCwiseNullaryOp<NullaryOp, XprType> >
332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    : traits<XprType>
342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef traits<XprType> XprTraits;
362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename XprType::Scalar Scalar;
372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename XprType::Nested XprTypeNested;
382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static const int NumDimensions = XprTraits::NumDimensions;
402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static const int Layout = XprTraits::Layout;
412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum {
432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Flags = 0
442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  };
452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}  // end namespace internal
482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename NullaryOp, typename XprType>
522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangclass TensorCwiseNullaryOp : public TensorBase<TensorCwiseNullaryOp<NullaryOp, XprType>, ReadOnlyAccessors>
532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  public:
552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorCwiseNullaryOp>::Scalar Scalar;
562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename XprType::CoeffReturnType CoeffReturnType;
582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef TensorCwiseNullaryOp<NullaryOp, XprType> Nested;
592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorCwiseNullaryOp>::StorageKind StorageKind;
602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorCwiseNullaryOp>::Index Index;
612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorCwiseNullaryOp(const XprType& xpr, const NullaryOp& func = NullaryOp())
632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        : m_xpr(xpr), m_functor(func) {}
642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const typename internal::remove_all<typename XprType::Nested>::type&
672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    nestedExpression() const { return m_xpr; }
682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const NullaryOp& functor() const { return m_functor; }
712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  protected:
732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typename XprType::Nested m_xpr;
742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const NullaryOp m_functor;
752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal {
802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename UnaryOp, typename XprType>
812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct traits<TensorCwiseUnaryOp<UnaryOp, XprType> >
822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    : traits<XprType>
832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // TODO(phli): Add InputScalar, InputPacket.  Check references to
852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // current Scalar/Packet to see if the intent is Input or Output.
862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename result_of<UnaryOp(typename XprType::Scalar)>::type Scalar;
872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef traits<XprType> XprTraits;
882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename XprType::Nested XprTypeNested;
892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static const int NumDimensions = XprTraits::NumDimensions;
912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static const int Layout = XprTraits::Layout;
922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename UnaryOp, typename XprType>
952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct eval<TensorCwiseUnaryOp<UnaryOp, XprType>, Eigen::Dense>
962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef const TensorCwiseUnaryOp<UnaryOp, XprType>& type;
982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename UnaryOp, typename XprType>
1012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct nested<TensorCwiseUnaryOp<UnaryOp, XprType>, 1, typename eval<TensorCwiseUnaryOp<UnaryOp, XprType> >::type>
1022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef TensorCwiseUnaryOp<UnaryOp, XprType> type;
1042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}  // end namespace internal
1072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename UnaryOp, typename XprType>
1112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangclass TensorCwiseUnaryOp : public TensorBase<TensorCwiseUnaryOp<UnaryOp, XprType>, ReadOnlyAccessors>
1122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  public:
1142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // TODO(phli): Add InputScalar, InputPacket.  Check references to
1152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // current Scalar/Packet to see if the intent is Input or Output.
1162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorCwiseUnaryOp>::Scalar Scalar;
1172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
1182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef Scalar CoeffReturnType;
1192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::nested<TensorCwiseUnaryOp>::type Nested;
1202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorCwiseUnaryOp>::StorageKind StorageKind;
1212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorCwiseUnaryOp>::Index Index;
1222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorCwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
1242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      : m_xpr(xpr), m_functor(func) {}
1252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
1272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const UnaryOp& functor() const { return m_functor; }
1282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    /** \returns the nested expression */
1302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
1312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const typename internal::remove_all<typename XprType::Nested>::type&
1322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    nestedExpression() const { return m_xpr; }
1332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  protected:
1352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typename XprType::Nested m_xpr;
1362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const UnaryOp m_functor;
1372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal {
1412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename BinaryOp, typename LhsXprType, typename RhsXprType>
1422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct traits<TensorCwiseBinaryOp<BinaryOp, LhsXprType, RhsXprType> >
1432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // Type promotion to handle the case where the types of the lhs and the rhs
1452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // are different.
1462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // TODO(phli): Add Lhs/RhsScalar, Lhs/RhsPacket.  Check references to
1472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // current Scalar/Packet to see if the intent is Inputs or Output.
1482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename result_of<
1492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      BinaryOp(typename LhsXprType::Scalar,
1502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang               typename RhsXprType::Scalar)>::type Scalar;
1512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef traits<LhsXprType> XprTraits;
1522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename promote_storage_type<
1532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      typename traits<LhsXprType>::StorageKind,
1542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      typename traits<RhsXprType>::StorageKind>::ret StorageKind;
1552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename promote_index_type<
1562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      typename traits<LhsXprType>::Index,
1572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      typename traits<RhsXprType>::Index>::type Index;
1582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename LhsXprType::Nested LhsNested;
1592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename RhsXprType::Nested RhsNested;
1602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename remove_reference<LhsNested>::type _LhsNested;
1612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename remove_reference<RhsNested>::type _RhsNested;
1622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static const int NumDimensions = XprTraits::NumDimensions;
1632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static const int Layout = XprTraits::Layout;
1642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum {
1662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Flags = 0
1672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  };
1682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename BinaryOp, typename LhsXprType, typename RhsXprType>
1712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct eval<TensorCwiseBinaryOp<BinaryOp, LhsXprType, RhsXprType>, Eigen::Dense>
1722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef const TensorCwiseBinaryOp<BinaryOp, LhsXprType, RhsXprType>& type;
1742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename BinaryOp, typename LhsXprType, typename RhsXprType>
1772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct nested<TensorCwiseBinaryOp<BinaryOp, LhsXprType, RhsXprType>, 1, typename eval<TensorCwiseBinaryOp<BinaryOp, LhsXprType, RhsXprType> >::type>
1782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef TensorCwiseBinaryOp<BinaryOp, LhsXprType, RhsXprType> type;
1802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}  // end namespace internal
1832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename BinaryOp, typename LhsXprType, typename RhsXprType>
1872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangclass TensorCwiseBinaryOp : public TensorBase<TensorCwiseBinaryOp<BinaryOp, LhsXprType, RhsXprType>, ReadOnlyAccessors>
1882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  public:
1902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // TODO(phli): Add Lhs/RhsScalar, Lhs/RhsPacket.  Check references to
1912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // current Scalar/Packet to see if the intent is Inputs or Output.
1922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorCwiseBinaryOp>::Scalar Scalar;
1932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
1942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef Scalar CoeffReturnType;
1952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::nested<TensorCwiseBinaryOp>::type Nested;
1962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorCwiseBinaryOp>::StorageKind StorageKind;
1972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorCwiseBinaryOp>::Index Index;
1982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorCwiseBinaryOp(const LhsXprType& lhs, const RhsXprType& rhs, const BinaryOp& func = BinaryOp())
2002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        : m_lhs_xpr(lhs), m_rhs_xpr(rhs), m_functor(func) {}
2012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
2032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const BinaryOp& functor() const { return m_functor; }
2042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    /** \returns the nested expressions */
2062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
2072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const typename internal::remove_all<typename LhsXprType::Nested>::type&
2082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    lhsExpression() const { return m_lhs_xpr; }
2092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
2112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const typename internal::remove_all<typename RhsXprType::Nested>::type&
2122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    rhsExpression() const { return m_rhs_xpr; }
2132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  protected:
2152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typename LhsXprType::Nested m_lhs_xpr;
2162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typename RhsXprType::Nested m_rhs_xpr;
2172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const BinaryOp m_functor;
2182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
2192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal {
2222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename TernaryOp, typename Arg1XprType, typename Arg2XprType, typename Arg3XprType>
2232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct traits<TensorCwiseTernaryOp<TernaryOp, Arg1XprType, Arg2XprType, Arg3XprType> >
2242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
2252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // Type promotion to handle the case where the types of the args are different.
2262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename result_of<
2272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      TernaryOp(typename Arg1XprType::Scalar,
2282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                typename Arg2XprType::Scalar,
2292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                typename Arg3XprType::Scalar)>::type Scalar;
2302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef traits<Arg1XprType> XprTraits;
2312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename traits<Arg1XprType>::StorageKind StorageKind;
2322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename traits<Arg1XprType>::Index Index;
2332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename Arg1XprType::Nested Arg1Nested;
2342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename Arg2XprType::Nested Arg2Nested;
2352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename Arg3XprType::Nested Arg3Nested;
2362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename remove_reference<Arg1Nested>::type _Arg1Nested;
2372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename remove_reference<Arg2Nested>::type _Arg2Nested;
2382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename remove_reference<Arg3Nested>::type _Arg3Nested;
2392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static const int NumDimensions = XprTraits::NumDimensions;
2402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static const int Layout = XprTraits::Layout;
2412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum {
2432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Flags = 0
2442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  };
2452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
2462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename TernaryOp, typename Arg1XprType, typename Arg2XprType, typename Arg3XprType>
2482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct eval<TensorCwiseTernaryOp<TernaryOp, Arg1XprType, Arg2XprType, Arg3XprType>, Eigen::Dense>
2492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
2502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef const TensorCwiseTernaryOp<TernaryOp, Arg1XprType, Arg2XprType, Arg3XprType>& type;
2512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
2522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename TernaryOp, typename Arg1XprType, typename Arg2XprType, typename Arg3XprType>
2542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct nested<TensorCwiseTernaryOp<TernaryOp, Arg1XprType, Arg2XprType, Arg3XprType>, 1, typename eval<TensorCwiseTernaryOp<TernaryOp, Arg1XprType, Arg2XprType, Arg3XprType> >::type>
2552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
2562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef TensorCwiseTernaryOp<TernaryOp, Arg1XprType, Arg2XprType, Arg3XprType> type;
2572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
2582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}  // end namespace internal
2602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename TernaryOp, typename Arg1XprType, typename Arg2XprType, typename Arg3XprType>
2642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangclass TensorCwiseTernaryOp : public TensorBase<TensorCwiseTernaryOp<TernaryOp, Arg1XprType, Arg2XprType, Arg3XprType>, ReadOnlyAccessors>
2652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
2662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  public:
2672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorCwiseTernaryOp>::Scalar Scalar;
2682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
2692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef Scalar CoeffReturnType;
2702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::nested<TensorCwiseTernaryOp>::type Nested;
2712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorCwiseTernaryOp>::StorageKind StorageKind;
2722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorCwiseTernaryOp>::Index Index;
2732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TensorCwiseTernaryOp(const Arg1XprType& arg1, const Arg2XprType& arg2, const Arg3XprType& arg3, const TernaryOp& func = TernaryOp())
2752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang        : m_arg1_xpr(arg1), m_arg2_xpr(arg2), m_arg3_xpr(arg3), m_functor(func) {}
2762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
2782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const TernaryOp& functor() const { return m_functor; }
2792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    /** \returns the nested expressions */
2812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
2822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const typename internal::remove_all<typename Arg1XprType::Nested>::type&
2832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    arg1Expression() const { return m_arg1_xpr; }
2842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
2862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const typename internal::remove_all<typename Arg2XprType::Nested>::type&
2872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    arg2Expression() const { return m_arg2_xpr; }
2882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
2902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const typename internal::remove_all<typename Arg3XprType::Nested>::type&
2912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    arg3Expression() const { return m_arg3_xpr; }
2922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  protected:
2942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typename Arg1XprType::Nested m_arg1_xpr;
2952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typename Arg2XprType::Nested m_arg2_xpr;
2962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typename Arg3XprType::Nested m_arg3_xpr;
2972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const TernaryOp m_functor;
2982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
2992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal {
3022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename IfXprType, typename ThenXprType, typename ElseXprType>
3032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct traits<TensorSelectOp<IfXprType, ThenXprType, ElseXprType> >
3042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    : traits<ThenXprType>
3052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
3062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename traits<ThenXprType>::Scalar Scalar;
3072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef traits<ThenXprType> XprTraits;
3082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename promote_storage_type<typename traits<ThenXprType>::StorageKind,
3092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                                        typename traits<ElseXprType>::StorageKind>::ret StorageKind;
3102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename promote_index_type<typename traits<ElseXprType>::Index,
3112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                                      typename traits<ThenXprType>::Index>::type Index;
3122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename IfXprType::Nested IfNested;
3132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename ThenXprType::Nested ThenNested;
3142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename ElseXprType::Nested ElseNested;
3152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static const int NumDimensions = XprTraits::NumDimensions;
3162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  static const int Layout = XprTraits::Layout;
3172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
3182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename IfXprType, typename ThenXprType, typename ElseXprType>
3202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct eval<TensorSelectOp<IfXprType, ThenXprType, ElseXprType>, Eigen::Dense>
3212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
3222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef const TensorSelectOp<IfXprType, ThenXprType, ElseXprType>& type;
3232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
3242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename IfXprType, typename ThenXprType, typename ElseXprType>
3262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct nested<TensorSelectOp<IfXprType, ThenXprType, ElseXprType>, 1, typename eval<TensorSelectOp<IfXprType, ThenXprType, ElseXprType> >::type>
3272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
3282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef TensorSelectOp<IfXprType, ThenXprType, ElseXprType> type;
3292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
3302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}  // end namespace internal
3322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename IfXprType, typename ThenXprType, typename ElseXprType>
3352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangclass TensorSelectOp : public TensorBase<TensorSelectOp<IfXprType, ThenXprType, ElseXprType>, ReadOnlyAccessors>
3362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
3372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  public:
3382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorSelectOp>::Scalar Scalar;
3392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::NumTraits<Scalar>::Real RealScalar;
3402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename internal::promote_storage_type<typename ThenXprType::CoeffReturnType,
3412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                                                    typename ElseXprType::CoeffReturnType>::ret CoeffReturnType;
3422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::nested<TensorSelectOp>::type Nested;
3432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorSelectOp>::StorageKind StorageKind;
3442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typedef typename Eigen::internal::traits<TensorSelectOp>::Index Index;
3452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
3472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    TensorSelectOp(const IfXprType& a_condition,
3482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                   const ThenXprType& a_then,
3492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                   const ElseXprType& a_else)
3502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang      : m_condition(a_condition), m_then(a_then), m_else(a_else)
3512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    { }
3522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
3542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const IfXprType& ifExpression() const { return m_condition; }
3552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
3572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const ThenXprType& thenExpression() const { return m_then; }
3582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC
3602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    const ElseXprType& elseExpression() const { return m_else; }
3612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  protected:
3632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typename IfXprType::Nested m_condition;
3642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typename ThenXprType::Nested m_then;
3652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    typename ElseXprType::Nested m_else;
3662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
3672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace Eigen
3702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif // EIGEN_CXX11_TENSOR_TENSOR_EXPR_H
372