Eigen  3.3.3
CwiseTernaryOp.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
00006 // Copyright (C) 2016 Eugene Brevdo <ebrevdo@gmail.com>
00007 //
00008 // This Source Code Form is subject to the terms of the Mozilla
00009 // Public License v. 2.0. If a copy of the MPL was not distributed
00010 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00011 
00012 #ifndef EIGEN_CWISE_TERNARY_OP_H
00013 #define EIGEN_CWISE_TERNARY_OP_H
00014 
00015 namespace Eigen {
00016 
00017 namespace internal {
00018 template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3>
00019 struct traits<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> > {
00020   // we must not inherit from traits<Arg1> since it has
00021   // the potential to cause problems with MSVC
00022   typedef typename remove_all<Arg1>::type Ancestor;
00023   typedef typename traits<Ancestor>::XprKind XprKind;
00024   enum {
00025     RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime,
00026     ColsAtCompileTime = traits<Ancestor>::ColsAtCompileTime,
00027     MaxRowsAtCompileTime = traits<Ancestor>::MaxRowsAtCompileTime,
00028     MaxColsAtCompileTime = traits<Ancestor>::MaxColsAtCompileTime
00029   };
00030 
00031   // even though we require Arg1, Arg2, and Arg3 to have the same scalar type
00032   // (see CwiseTernaryOp constructor),
00033   // we still want to handle the case when the result type is different.
00034   typedef typename result_of<TernaryOp(
00035       const typename Arg1::Scalar&, const typename Arg2::Scalar&,
00036       const typename Arg3::Scalar&)>::type Scalar;
00037 
00038   typedef typename internal::traits<Arg1>::StorageKind StorageKind;
00039   typedef typename internal::traits<Arg1>::StorageIndex StorageIndex;
00040 
00041   typedef typename Arg1::Nested Arg1Nested;
00042   typedef typename Arg2::Nested Arg2Nested;
00043   typedef typename Arg3::Nested Arg3Nested;
00044   typedef typename remove_reference<Arg1Nested>::type _Arg1Nested;
00045   typedef typename remove_reference<Arg2Nested>::type _Arg2Nested;
00046   typedef typename remove_reference<Arg3Nested>::type _Arg3Nested;
00047   enum { Flags = _Arg1Nested::Flags & RowMajorBit };
00048 };
00049 }  // end namespace internal
00050 
00051 template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3,
00052           typename StorageKind>
00053 class CwiseTernaryOpImpl;
00054 
00082 template <typename TernaryOp, typename Arg1Type, typename Arg2Type,
00083           typename Arg3Type>
00084 class CwiseTernaryOp : public CwiseTernaryOpImpl<
00085                            TernaryOp, Arg1Type, Arg2Type, Arg3Type,
00086                            typename internal::traits<Arg1Type>::StorageKind>,
00087                        internal::no_assignment_operator
00088 {
00089  public:
00090   typedef typename internal::remove_all<Arg1Type>::type Arg1;
00091   typedef typename internal::remove_all<Arg2Type>::type Arg2;
00092   typedef typename internal::remove_all<Arg3Type>::type Arg3;
00093 
00094   typedef typename CwiseTernaryOpImpl<
00095       TernaryOp, Arg1Type, Arg2Type, Arg3Type,
00096       typename internal::traits<Arg1Type>::StorageKind>::Base Base;
00097   EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseTernaryOp)
00098 
00099   typedef typename internal::ref_selector<Arg1Type>::type Arg1Nested;
00100   typedef typename internal::ref_selector<Arg2Type>::type Arg2Nested;
00101   typedef typename internal::ref_selector<Arg3Type>::type Arg3Nested;
00102   typedef typename internal::remove_reference<Arg1Nested>::type _Arg1Nested;
00103   typedef typename internal::remove_reference<Arg2Nested>::type _Arg2Nested;
00104   typedef typename internal::remove_reference<Arg3Nested>::type _Arg3Nested;
00105 
00106   EIGEN_DEVICE_FUNC
00107   EIGEN_STRONG_INLINE CwiseTernaryOp(const Arg1& a1, const Arg2& a2,
00108                                      const Arg3& a3,
00109                                      const TernaryOp& func = TernaryOp())
00110       : m_arg1(a1), m_arg2(a2), m_arg3(a3), m_functor(func) {
00111     // require the sizes to match
00112     EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg2)
00113     EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Arg1, Arg3)
00114 
00115     // The index types should match
00116     EIGEN_STATIC_ASSERT((internal::is_same<
00117                          typename internal::traits<Arg1Type>::StorageKind,
00118                          typename internal::traits<Arg2Type>::StorageKind>::value),
00119                         STORAGE_KIND_MUST_MATCH)
00120     EIGEN_STATIC_ASSERT((internal::is_same<
00121                          typename internal::traits<Arg1Type>::StorageKind,
00122                          typename internal::traits<Arg3Type>::StorageKind>::value),
00123                         STORAGE_KIND_MUST_MATCH)
00124 
00125     eigen_assert(a1.rows() == a2.rows() && a1.cols() == a2.cols() &&
00126                  a1.rows() == a3.rows() && a1.cols() == a3.cols());
00127   }
00128 
00129   EIGEN_DEVICE_FUNC
00130   EIGEN_STRONG_INLINE Index rows() const {
00131     // return the fixed size type if available to enable compile time
00132     // optimizations
00133     if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
00134                 RowsAtCompileTime == Dynamic &&
00135         internal::traits<typename internal::remove_all<Arg2Nested>::type>::
00136                 RowsAtCompileTime == Dynamic)
00137       return m_arg3.rows();
00138     else if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
00139                      RowsAtCompileTime == Dynamic &&
00140              internal::traits<typename internal::remove_all<Arg3Nested>::type>::
00141                      RowsAtCompileTime == Dynamic)
00142       return m_arg2.rows();
00143     else
00144       return m_arg1.rows();
00145   }
00146   EIGEN_DEVICE_FUNC
00147   EIGEN_STRONG_INLINE Index cols() const {
00148     // return the fixed size type if available to enable compile time
00149     // optimizations
00150     if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
00151                 ColsAtCompileTime == Dynamic &&
00152         internal::traits<typename internal::remove_all<Arg2Nested>::type>::
00153                 ColsAtCompileTime == Dynamic)
00154       return m_arg3.cols();
00155     else if (internal::traits<typename internal::remove_all<Arg1Nested>::type>::
00156                      ColsAtCompileTime == Dynamic &&
00157              internal::traits<typename internal::remove_all<Arg3Nested>::type>::
00158                      ColsAtCompileTime == Dynamic)
00159       return m_arg2.cols();
00160     else
00161       return m_arg1.cols();
00162   }
00163 
00165   EIGEN_DEVICE_FUNC
00166   const _Arg1Nested& arg1() const { return m_arg1; }
00168   EIGEN_DEVICE_FUNC
00169   const _Arg2Nested& arg2() const { return m_arg2; }
00171   EIGEN_DEVICE_FUNC
00172   const _Arg3Nested& arg3() const { return m_arg3; }
00174   EIGEN_DEVICE_FUNC
00175   const TernaryOp& functor() const { return m_functor; }
00176 
00177  protected:
00178   Arg1Nested m_arg1;
00179   Arg2Nested m_arg2;
00180   Arg3Nested m_arg3;
00181   const TernaryOp m_functor;
00182 };
00183 
00184 // Generic API dispatcher
00185 template <typename TernaryOp, typename Arg1, typename Arg2, typename Arg3,
00186           typename StorageKind>
00187 class CwiseTernaryOpImpl
00188     : public internal::generic_xpr_base<
00189           CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >::type {
00190  public:
00191   typedef typename internal::generic_xpr_base<
00192       CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >::type Base;
00193 };
00194 
00195 }  // end namespace Eigen
00196 
00197 #endif  // EIGEN_CWISE_TERNARY_OP_H
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends