00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef EIGEN_CWISE_BINARY_OP_H
00012 #define EIGEN_CWISE_BINARY_OP_H
00013
00014 namespace Eigen {
00015
00036 namespace internal {
00037 template<typename BinaryOp, typename Lhs, typename Rhs>
00038 struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
00039 {
00040
00041
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
00052
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 CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + functor_traits<BinaryOp>::Cost
00085 };
00086 };
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096 #define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
00097 EIGEN_STATIC_ASSERT((internal::functor_is_product_like<BINOP>::ret \
00098 ? int(internal::scalar_product_traits<LHS, RHS>::Defined) \
00099 : int(internal::is_same<LHS, RHS>::value)), \
00100 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
00101
00102 template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
00103 class CwiseBinaryOpImpl;
00104
00105 template<typename BinaryOp, typename Lhs, typename Rhs>
00106 class CwiseBinaryOp : internal::no_assignment_operator,
00107 public CwiseBinaryOpImpl<
00108 BinaryOp, Lhs, Rhs,
00109 typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
00110 typename internal::traits<Rhs>::StorageKind>::ret>
00111 {
00112 public:
00113
00114 typedef typename CwiseBinaryOpImpl<
00115 BinaryOp, Lhs, Rhs,
00116 typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
00117 typename internal::traits<Rhs>::StorageKind>::ret>::Base Base;
00118 EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp)
00119
00120 typedef typename internal::nested<Lhs>::type LhsNested;
00121 typedef typename internal::nested<Rhs>::type RhsNested;
00122 typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
00123 typedef typename internal::remove_reference<RhsNested>::type _RhsNested;
00124
00125 EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& aLhs, const Rhs& aRhs, const BinaryOp& func = BinaryOp())
00126 : m_lhs(aLhs), m_rhs(aRhs), m_functor(func)
00127 {
00128 EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
00129
00130 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
00131 eigen_assert(aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols());
00132 }
00133
00134 EIGEN_STRONG_INLINE Index rows() const {
00135
00136 if (internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic)
00137 return m_rhs.rows();
00138 else
00139 return m_lhs.rows();
00140 }
00141 EIGEN_STRONG_INLINE Index cols() const {
00142
00143 if (internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic)
00144 return m_rhs.cols();
00145 else
00146 return m_lhs.cols();
00147 }
00148
00150 const _LhsNested& lhs() const { return m_lhs; }
00152 const _RhsNested& rhs() const { return m_rhs; }
00154 const BinaryOp& functor() const { return m_functor; }
00155
00156 protected:
00157 LhsNested m_lhs;
00158 RhsNested m_rhs;
00159 const BinaryOp m_functor;
00160 };
00161
00162 template<typename BinaryOp, typename Lhs, typename Rhs>
00163 class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense>
00164 : public internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
00165 {
00166 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
00167 public:
00168
00169 typedef typename internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base;
00170 EIGEN_DENSE_PUBLIC_INTERFACE( Derived )
00171
00172 EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const
00173 {
00174 return derived().functor()(derived().lhs().coeff(rowId, colId),
00175 derived().rhs().coeff(rowId, colId));
00176 }
00177
00178 template<int LoadMode>
00179 EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
00180 {
00181 return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(rowId, colId),
00182 derived().rhs().template packet<LoadMode>(rowId, colId));
00183 }
00184
00185 EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
00186 {
00187 return derived().functor()(derived().lhs().coeff(index),
00188 derived().rhs().coeff(index));
00189 }
00190
00191 template<int LoadMode>
00192 EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
00193 {
00194 return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(index),
00195 derived().rhs().template packet<LoadMode>(index));
00196 }
00197 };
00198
00203 template<typename Derived>
00204 template<typename OtherDerived>
00205 EIGEN_STRONG_INLINE Derived &
00206 MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other)
00207 {
00208 SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, Derived, OtherDerived> tmp(derived());
00209 tmp = other.derived();
00210 return derived();
00211 }
00212
00217 template<typename Derived>
00218 template<typename OtherDerived>
00219 EIGEN_STRONG_INLINE Derived &
00220 MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
00221 {
00222 SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived());
00223 tmp = other.derived();
00224 return derived();
00225 }
00226
00227 }
00228
00229 #endif // EIGEN_CWISE_BINARY_OP_H