Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
CwiseBinaryOp.h
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008-2009 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 /** \class CwiseBinaryOp 00017 * \ingroup Core_Module 00018 * 00019 * \brief Generic expression where a coefficient-wise binary operator is applied to two expressions 00020 * 00021 * \param BinaryOp template functor implementing the operator 00022 * \param Lhs the type of the left-hand side 00023 * \param Rhs the type of the right-hand side 00024 * 00025 * This class represents an expression where a coefficient-wise binary operator is applied to two expressions. 00026 * It is the return type of binary operators, by which we mean only those binary operators where 00027 * both the left-hand side and the right-hand side are Eigen expressions. 00028 * For example, the return type of matrix1+matrix2 is a CwiseBinaryOp. 00029 * 00030 * Most of the time, this is the only way that it is used, so you typically don't have to name 00031 * CwiseBinaryOp types explicitly. 00032 * 00033 * \sa MatrixBase::binaryExpr(const MatrixBase<OtherDerived> &,const CustomBinaryOp &) const, class CwiseUnaryOp, class CwiseNullaryOp 00034 */ 00035 00036 namespace internal { 00037 template<typename BinaryOp, typename Lhs, typename Rhs> 00038 struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > 00039 { 00040 // we must not inherit from traits<Lhs> since it has 00041 // the potential to cause problems with MSVC 00042 typedef typename remove_all<Lhs>::type Ancestor; 00043 typedef typename traits<Ancestor>::XprKind XprKind; 00044 enum { 00045 RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime, 00046 ColsAtCompileTime = traits<Ancestor>::ColsAtCompileTime, 00047 MaxRowsAtCompileTime = traits<Ancestor>::MaxRowsAtCompileTime, 00048 MaxColsAtCompileTime = traits<Ancestor>::MaxColsAtCompileTime 00049 }; 00050 00051 // even though we require Lhs and Rhs to have the same scalar type (see CwiseBinaryOp constructor), 00052 // we still want to handle the case when the result type is different. 00053 typedef typename result_of< 00054 BinaryOp( 00055 typename Lhs::Scalar, 00056 typename Rhs::Scalar 00057 ) 00058 >::type Scalar; 00059 typedef typename promote_storage_type<typename traits<Lhs>::StorageKind, 00060 typename traits<Rhs>::StorageKind>::ret StorageKind; 00061 typedef typename promote_index_type<typename traits<Lhs>::Index, 00062 typename traits<Rhs>::Index>::type Index; 00063 typedef typename Lhs::Nested LhsNested; 00064 typedef typename Rhs::Nested RhsNested; 00065 typedef typename remove_reference<LhsNested>::type _LhsNested; 00066 typedef typename remove_reference<RhsNested>::type _RhsNested; 00067 enum { 00068 LhsCoeffReadCost = _LhsNested::CoeffReadCost, 00069 RhsCoeffReadCost = _RhsNested::CoeffReadCost, 00070 LhsFlags = _LhsNested::Flags, 00071 RhsFlags = _RhsNested::Flags, 00072 SameType = is_same<typename _LhsNested::Scalar,typename _RhsNested::Scalar>::value, 00073 StorageOrdersAgree = (int(Lhs::Flags)&RowMajorBit)==(int(Rhs::Flags)&RowMajorBit), 00074 Flags0 = (int(LhsFlags) | int(RhsFlags)) & ( 00075 HereditaryBits 00076 | (int(LhsFlags) & int(RhsFlags) & 00077 ( AlignedBit 00078 | (StorageOrdersAgree ? LinearAccessBit : 0) 00079 | (functor_traits<BinaryOp>::PacketAccess && StorageOrdersAgree && SameType ? PacketAccessBit : 0) 00080 ) 00081 ) 00082 ), 00083 Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit), 00084 Cost0 = EIGEN_ADD_COST(LhsCoeffReadCost,RhsCoeffReadCost), 00085 CoeffReadCost = EIGEN_ADD_COST(Cost0,functor_traits<BinaryOp>::Cost) 00086 }; 00087 }; 00088 } // end namespace internal 00089 00090 // we require Lhs and Rhs to have the same scalar type. Currently there is no example of a binary functor 00091 // that would take two operands of different types. If there were such an example, then this check should be 00092 // moved to the BinaryOp functors, on a per-case basis. This would however require a change in the BinaryOp functors, as 00093 // currently they take only one typename Scalar template parameter. 00094 // It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths. 00095 // So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to 00096 // add together a float matrix and a double matrix. 00097 #define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \ 00098 EIGEN_STATIC_ASSERT((internal::functor_is_product_like<BINOP>::ret \ 00099 ? int(internal::scalar_product_traits<LHS, RHS>::Defined) \ 00100 : int(internal::is_same<LHS, RHS>::value)), \ 00101 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) 00102 00103 template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind> 00104 class CwiseBinaryOpImpl; 00105 00106 template<typename BinaryOp, typename Lhs, typename Rhs> 00107 class CwiseBinaryOp : internal::no_assignment_operator, 00108 public CwiseBinaryOpImpl< 00109 BinaryOp, Lhs, Rhs, 00110 typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind, 00111 typename internal::traits<Rhs>::StorageKind>::ret> 00112 { 00113 public: 00114 00115 typedef typename CwiseBinaryOpImpl< 00116 BinaryOp, Lhs, Rhs, 00117 typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind, 00118 typename internal::traits<Rhs>::StorageKind>::ret>::Base Base; 00119 EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp) 00120 00121 typedef typename internal::nested<Lhs>::type LhsNested; 00122 typedef typename internal::nested<Rhs>::type RhsNested; 00123 typedef typename internal::remove_reference<LhsNested>::type _LhsNested; 00124 typedef typename internal::remove_reference<RhsNested>::type _RhsNested; 00125 00126 EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp()) 00127 : m_lhs(aLhs), m_rhs(aRhs), m_functor(func) 00128 { 00129 EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar); 00130 // require the sizes to match 00131 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs) 00132 eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols()); 00133 } 00134 00135 EIGEN_STRONG_INLINE Index rows() const { 00136 // return the fixed size type if available to enable compile time optimizations 00137 if (internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic) 00138 return m_rhs.rows(); 00139 else 00140 return m_lhs.rows(); 00141 } 00142 EIGEN_STRONG_INLINE Index cols() const { 00143 // return the fixed size type if available to enable compile time optimizations 00144 if (internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic) 00145 return m_rhs.cols(); 00146 else 00147 return m_lhs.cols(); 00148 } 00149 00150 /** \returns the left hand side nested expression */ 00151 const _LhsNested& lhs () const { return m_lhs; } 00152 /** \returns the right hand side nested expression */ 00153 const _RhsNested& rhs () const { return m_rhs; } 00154 /** \returns the functor representing the binary operation */ 00155 const BinaryOp& functor () const { return m_functor; } 00156 00157 protected: 00158 LhsNested m_lhs; 00159 RhsNested m_rhs; 00160 const BinaryOp m_functor; 00161 }; 00162 00163 template<typename BinaryOp, typename Lhs, typename Rhs> 00164 class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense> 00165 : public internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type 00166 { 00167 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived; 00168 public: 00169 00170 typedef typename internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base; 00171 EIGEN_DENSE_PUBLIC_INTERFACE( Derived ) 00172 00173 EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const 00174 { 00175 return derived().functor()(derived().lhs().coeff(rowId, colId), 00176 derived().rhs().coeff(rowId, colId)); 00177 } 00178 00179 template<int LoadMode> 00180 EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const 00181 { 00182 return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(rowId, colId), 00183 derived().rhs().template packet<LoadMode>(rowId, colId)); 00184 } 00185 00186 EIGEN_STRONG_INLINE const Scalar coeff(Index index) const 00187 { 00188 return derived().functor()(derived().lhs().coeff(index), 00189 derived().rhs().coeff(index)); 00190 } 00191 00192 template<int LoadMode> 00193 EIGEN_STRONG_INLINE PacketScalar packet(Index index) const 00194 { 00195 return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(index), 00196 derived().rhs().template packet<LoadMode>(index)); 00197 } 00198 }; 00199 00200 /** replaces \c *this by \c *this - \a other. 00201 * 00202 * \returns a reference to \c *this 00203 */ 00204 template<typename Derived> 00205 template<typename OtherDerived> 00206 EIGEN_STRONG_INLINE Derived & 00207 MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other) 00208 { 00209 SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, OtherDerived> tmp(derived()); 00210 tmp = other.derived(); 00211 return derived(); 00212 } 00213 00214 /** replaces \c *this by \c *this + \a other. 00215 * 00216 * \returns a reference to \c *this 00217 */ 00218 template<typename Derived> 00219 template<typename OtherDerived> 00220 EIGEN_STRONG_INLINE Derived & 00221 MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other) 00222 { 00223 SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived()); 00224 tmp = other.derived(); 00225 return derived(); 00226 } 00227 00228 } // end namespace Eigen 00229 00230 #endif // EIGEN_CWISE_BINARY_OP_H
Generated on Thu Nov 17 2022 22:01:28 by
1.7.2