![]() |
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 // 00007 // This Source Code Form is subject to the terms of the Mozilla 00008 // Public License v. 2.0. If a copy of the MPL was not distributed 00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00010 00011 #ifndef EIGEN_CWISE_BINARY_OP_H 00012 #define EIGEN_CWISE_BINARY_OP_H 00013 00014 namespace Eigen { 00015 00016 namespace internal { 00017 template<typename BinaryOp, typename Lhs, typename Rhs> 00018 struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > 00019 { 00020 // we must not inherit from traits<Lhs> since it has 00021 // the potential to cause problems with MSVC 00022 typedef typename remove_all<Lhs>::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 Lhs and Rhs to have the same scalar type (see CwiseBinaryOp constructor), 00032 // we still want to handle the case when the result type is different. 00033 typedef typename result_of< 00034 BinaryOp( 00035 const typename Lhs::Scalar&, 00036 const typename Rhs::Scalar& 00037 ) 00038 >::type Scalar; 00039 typedef typename cwise_promote_storage_type<typename traits<Lhs>::StorageKind, 00040 typename traits<Rhs>::StorageKind, 00041 BinaryOp>::ret StorageKind; 00042 typedef typename promote_index_type<typename traits<Lhs>::StorageIndex, 00043 typename traits<Rhs>::StorageIndex>::type StorageIndex; 00044 typedef typename Lhs::Nested LhsNested; 00045 typedef typename Rhs::Nested RhsNested; 00046 typedef typename remove_reference<LhsNested>::type _LhsNested; 00047 typedef typename remove_reference<RhsNested>::type _RhsNested; 00048 enum { 00049 Flags = cwise_promote_storage_order<typename traits<Lhs>::StorageKind,typename traits<Rhs>::StorageKind,_LhsNested::Flags & RowMajorBit,_RhsNested::Flags & RowMajorBit>::value 00050 }; 00051 }; 00052 } // end namespace internal 00053 00054 template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind> 00055 class CwiseBinaryOpImpl; 00056 00076 template<typename BinaryOp, typename LhsType, typename RhsType> 00077 class CwiseBinaryOp : 00078 public CwiseBinaryOpImpl< 00079 BinaryOp, LhsType, RhsType, 00080 typename internal::cwise_promote_storage_type<typename internal::traits<LhsType>::StorageKind, 00081 typename internal::traits<RhsType>::StorageKind, 00082 BinaryOp>::ret>, 00083 internal::no_assignment_operator 00084 { 00085 public: 00086 00087 typedef typename internal::remove_all<BinaryOp>::type Functor; 00088 typedef typename internal::remove_all<LhsType>::type Lhs; 00089 typedef typename internal::remove_all<RhsType>::type Rhs; 00090 00091 typedef typename CwiseBinaryOpImpl< 00092 BinaryOp, LhsType, RhsType, 00093 typename internal::cwise_promote_storage_type<typename internal::traits<LhsType>::StorageKind, 00094 typename internal::traits<Rhs>::StorageKind, 00095 BinaryOp>::ret>::Base Base; 00096 EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp) 00097 00098 typedef typename internal::ref_selector<LhsType>::type LhsNested; 00099 typedef typename internal::ref_selector<RhsType>::type RhsNested; 00100 typedef typename internal::remove_reference<LhsNested>::type _LhsNested; 00101 typedef typename internal::remove_reference<RhsNested>::type _RhsNested; 00102 00103 EIGEN_DEVICE_FUNC 00104 EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp()) 00105 : m_lhs(aLhs), m_rhs(aRhs), m_functor(func) 00106 { 00107 EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar); 00108 // require the sizes to match 00109 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs) 00110 eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols()); 00111 } 00112 00113 EIGEN_DEVICE_FUNC 00114 EIGEN_STRONG_INLINE Index rows() const { 00115 // return the fixed size type if available to enable compile time optimizations 00116 if (internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic) 00117 return m_rhs.rows(); 00118 else 00119 return m_lhs.rows(); 00120 } 00121 EIGEN_DEVICE_FUNC 00122 EIGEN_STRONG_INLINE Index cols() const { 00123 // return the fixed size type if available to enable compile time optimizations 00124 if (internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic) 00125 return m_rhs.cols(); 00126 else 00127 return m_lhs.cols(); 00128 } 00129 00131 EIGEN_DEVICE_FUNC 00132 const _LhsNested& lhs() const { return m_lhs; } 00134 EIGEN_DEVICE_FUNC 00135 const _RhsNested& rhs() const { return m_rhs; } 00137 EIGEN_DEVICE_FUNC 00138 const BinaryOp& functor() const { return m_functor; } 00139 00140 protected: 00141 LhsNested m_lhs; 00142 RhsNested m_rhs; 00143 const BinaryOp m_functor; 00144 }; 00145 00146 // Generic API dispatcher 00147 template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind> 00148 class CwiseBinaryOpImpl 00149 : public internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type 00150 { 00151 public: 00152 typedef typename internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base; 00153 }; 00154 00159 template<typename Derived> 00160 template<typename OtherDerived> 00161 EIGEN_STRONG_INLINE Derived & 00162 MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other) 00163 { 00164 call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>()); 00165 return derived(); 00166 } 00167 00172 template<typename Derived> 00173 template<typename OtherDerived> 00174 EIGEN_STRONG_INLINE Derived & 00175 MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other) 00176 { 00177 call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>()); 00178 return derived(); 00179 } 00180 00181 } // end namespace Eigen 00182 00183 #endif // EIGEN_CWISE_BINARY_OP_H 00184