Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:56:12

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
0005 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
0006 // Copyright (C) 2016 Eugene Brevdo <ebrevdo@gmail.com>
0007 //
0008 // This Source Code Form is subject to the terms of the Mozilla
0009 // Public License v. 2.0. If a copy of the MPL was not distributed
0010 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
0011 
0012 #ifndef EIGEN_CWISE_TERNARY_OP_H
0013 #define EIGEN_CWISE_TERNARY_OP_H
0014 
0015 namespace Eigen {
0016 
0017 namespace internal {
0018 template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3>
0019 struct traits<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> > {
0020   // we must not inherit from traits<Arg1> since it has
0021   // the potential to cause problems with MSVC
0022   typedef typename remove_all<Arg1>::type Ancestor;
0023   typedef typename traits<Ancestor>::XprKind XprKind;
0024   enum {
0025     RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime,
0026     ColsAtCompileTime = traits<Ancestor>::ColsAtCompileTime,
0027     MaxRowsAtCompileTime = traits<Ancestor>::MaxRowsAtCompileTime,
0028     MaxColsAtCompileTime = traits<Ancestor>::MaxColsAtCompileTime
0029   };
0030 
0031   // even though we require Arg1, Arg2, and Arg3 to have the same scalar type
0032   // (see CwiseTernaryOp constructor),
0033   // we still want to handle the case when the result type is different.
0034   typedef typename result_of<TernaryOp(
0035       const typename Arg1::Scalar&, const typename Arg2::Scalar&,
0036       const typename Arg3::Scalar&)>::type Scalar;
0037 
0038   typedef typename internal::traits<Arg1>::StorageKind StorageKind;
0039   typedef typename internal::traits<Arg1>::StorageIndex StorageIndex;
0040 
0041   typedef typename Arg1::Nested Arg1Nested;
0042   typedef typename Arg2::Nested Arg2Nested;
0043   typedef typename Arg3::Nested Arg3Nested;
0044   typedef typename remove_reference<Arg1Nested>::type _Arg1Nested;
0045   typedef typename remove_reference<Arg2Nested>::type _Arg2Nested;
0046   typedef typename remove_reference<Arg3Nested>::type _Arg3Nested;
0047   enum { Flags = _Arg1Nested::Flags & RowMajorBit };
0048 };
0049 }  // end namespace internal
0050 
0051 template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3,
0052           typename StorageKind>
0053 class CwiseTernaryOpImpl;
0054 
0055 /** \class CwiseTernaryOp
0056   * \ingroup Core_Module
0057   *
0058   * \brief Generic expression where a coefficient-wise ternary operator is
0059  * applied to two expressions
0060   *
0061   * \tparam TernaryOp template functor implementing the operator
0062   * \tparam Arg1Type the type of the first argument
0063   * \tparam Arg2Type the type of the second argument
0064   * \tparam Arg3Type the type of the third argument
0065   *
0066   * This class represents an expression where a coefficient-wise ternary
0067  * operator is applied to three expressions.
0068   * It is the return type of ternary operators, by which we mean only those
0069  * ternary operators where
0070   * all three arguments are Eigen expressions.
0071   * For example, the return type of betainc(matrix1, matrix2, matrix3) is a
0072  * CwiseTernaryOp.
0073   *
0074   * Most of the time, this is the only way that it is used, so you typically
0075  * don't have to name
0076   * CwiseTernaryOp types explicitly.
0077   *
0078   * \sa MatrixBase::ternaryExpr(const MatrixBase<Argument2> &, const
0079  * MatrixBase<Argument3> &, const CustomTernaryOp &) const, class CwiseBinaryOp,
0080  * class CwiseUnaryOp, class CwiseNullaryOp
0081   */
0082 template <typename TernaryOp, typename Arg1Type, typename Arg2Type,
0083           typename Arg3Type>
0084 class CwiseTernaryOp : public CwiseTernaryOpImpl<
0085                            TernaryOp, Arg1Type, Arg2Type, Arg3Type,
0086                            typename internal::traits<Arg1Type>::StorageKind>,
0087                        internal::no_assignment_operator
0088 {
0089  public:
0090   typedef typename internal::remove_all<Arg1Type>::type Arg1;
0091   typedef typename internal::remove_all<Arg2Type>::type Arg2;
0092   typedef typename internal::remove_all<Arg3Type>::type Arg3;
0093 
0094   typedef typename CwiseTernaryOpImpl<
0095       TernaryOp, Arg1Type, Arg2Type, Arg3Type,
0096       typename internal::traits<Arg1Type>::StorageKind>::Base Base;
0097   EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseTernaryOp)
0098 
0099   typedef typename internal::ref_selector<Arg1Type>::type Arg1Nested;
0100   typedef typename internal::ref_selector<Arg2Type>::type Arg2Nested;
0101   typedef typename internal::ref_selector<Arg3Type>::type Arg3Nested;
0102   typedef typename internal::remove_reference<Arg1Nested>::type _Arg1Nested;
0103   typedef typename internal::remove_reference<Arg2Nested>::type _Arg2Nested;
0104   typedef typename internal::remove_reference<Arg3Nested>::type _Arg3Nested;
0105 
0106   EIGEN_DEVICE_FUNC
0107   EIGEN_STRONG_INLINE CwiseTernaryOp(const Arg1& a1, const Arg2& a2,
0108                                      const Arg3& a3,
0109                                      const TernaryOp& func = TernaryOp())
0110       : m_arg1(a1), m_arg2(a2), m_arg3(a3), m_functor(func) {
0111     // require the sizes to match
0112     EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg2)
0113     EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg3)
0114 
0115     // The index types should match
0116     EIGEN_STATIC_ASSERT((internal::is_same<
0117                          typename internal::traits<Arg1Type>::StorageKind,
0118                          typename internal::traits<Arg2Type>::StorageKind>::value),
0119                         STORAGE_KIND_MUST_MATCH)
0120     EIGEN_STATIC_ASSERT((internal::is_same<
0121                          typename internal::traits<Arg1Type>::StorageKind,
0122                          typename internal::traits<Arg3Type>::StorageKind>::value),
0123                         STORAGE_KIND_MUST_MATCH)
0124 
0125     eigen_assert(a1.rows() == a2.rows() && a1.cols() == a2.cols() &&
0126                  a1.rows() == a3.rows() && a1.cols() == a3.cols());
0127   }
0128 
0129   EIGEN_DEVICE_FUNC
0130   EIGEN_STRONG_INLINE Index rows() const {
0131     // return the fixed size type if available to enable compile time
0132     // optimizations
0133     if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
0134                 RowsAtCompileTime == Dynamic &&
0135         internal::traits<typename internal::remove_all<Arg2Nested>::type>::
0136                 RowsAtCompileTime == Dynamic)
0137       return m_arg3.rows();
0138     else if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
0139                      RowsAtCompileTime == Dynamic &&
0140              internal::traits<typename internal::remove_all<Arg3Nested>::type>::
0141                      RowsAtCompileTime == Dynamic)
0142       return m_arg2.rows();
0143     else
0144       return m_arg1.rows();
0145   }
0146   EIGEN_DEVICE_FUNC
0147   EIGEN_STRONG_INLINE Index cols() const {
0148     // return the fixed size type if available to enable compile time
0149     // optimizations
0150     if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
0151                 ColsAtCompileTime == Dynamic &&
0152         internal::traits<typename internal::remove_all<Arg2Nested>::type>::
0153                 ColsAtCompileTime == Dynamic)
0154       return m_arg3.cols();
0155     else if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
0156                      ColsAtCompileTime == Dynamic &&
0157              internal::traits<typename internal::remove_all<Arg3Nested>::type>::
0158                      ColsAtCompileTime == Dynamic)
0159       return m_arg2.cols();
0160     else
0161       return m_arg1.cols();
0162   }
0163 
0164   /** \returns the first argument nested expression */
0165   EIGEN_DEVICE_FUNC
0166   const _Arg1Nested& arg1() const { return m_arg1; }
0167   /** \returns the first argument nested expression */
0168   EIGEN_DEVICE_FUNC
0169   const _Arg2Nested& arg2() const { return m_arg2; }
0170   /** \returns the third argument nested expression */
0171   EIGEN_DEVICE_FUNC
0172   const _Arg3Nested& arg3() const { return m_arg3; }
0173   /** \returns the functor representing the ternary operation */
0174   EIGEN_DEVICE_FUNC
0175   const TernaryOp& functor() const { return m_functor; }
0176 
0177  protected:
0178   Arg1Nested m_arg1;
0179   Arg2Nested m_arg2;
0180   Arg3Nested m_arg3;
0181   const TernaryOp m_functor;
0182 };
0183 
0184 // Generic API dispatcher
0185 template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3,
0186           typename StorageKind>
0187 class CwiseTernaryOpImpl
0188     : public internal::generic_xpr_base<
0189           CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >::type {
0190  public:
0191   typedef typename internal::generic_xpr_base<
0192       CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >::type Base;
0193 };
0194 
0195 }  // end namespace Eigen
0196 
0197 #endif  // EIGEN_CWISE_TERNARY_OP_H