![]() |
Eigen
3.3.3
|
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