00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef EIGEN_CWISE_BINARY_OP_H
00027 #define EIGEN_CWISE_BINARY_OP_H
00028
00029 namespace Eigen {
00030
00051 namespace internal {
00052 template<typename BinaryOp, typename Lhs, typename Rhs>
00053 struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
00054 {
00055
00056
00057 typedef typename remove_all<Lhs>::type Ancestor;
00058 typedef typename traits<Ancestor>::XprKind XprKind;
00059 enum {
00060 RowsAtCompileTime = traits<Ancestor>::RowsAtCompileTime,
00061 ColsAtCompileTime = traits<Ancestor>::ColsAtCompileTime,
00062 MaxRowsAtCompileTime = traits<Ancestor>::MaxRowsAtCompileTime,
00063 MaxColsAtCompileTime = traits<Ancestor>::MaxColsAtCompileTime
00064 };
00065
00066
00067
00068 typedef typename result_of<
00069 BinaryOp(
00070 typename Lhs::Scalar,
00071 typename Rhs::Scalar
00072 )
00073 >::type Scalar;
00074 typedef typename promote_storage_type<typename traits<Lhs>::StorageKind,
00075 typename traits<Rhs>::StorageKind>::ret StorageKind;
00076 typedef typename promote_index_type<typename traits<Lhs>::Index,
00077 typename traits<Rhs>::Index>::type Index;
00078 typedef typename Lhs::Nested LhsNested;
00079 typedef typename Rhs::Nested RhsNested;
00080 typedef typename remove_reference<LhsNested>::type _LhsNested;
00081 typedef typename remove_reference<RhsNested>::type _RhsNested;
00082 enum {
00083 LhsCoeffReadCost = _LhsNested::CoeffReadCost,
00084 RhsCoeffReadCost = _RhsNested::CoeffReadCost,
00085 LhsFlags = _LhsNested::Flags,
00086 RhsFlags = _RhsNested::Flags,
00087 SameType = is_same<typename _LhsNested::Scalar,typename _RhsNested::Scalar>::value,
00088 StorageOrdersAgree = (int(Lhs::Flags)&RowMajorBit)==(int(Rhs::Flags)&RowMajorBit),
00089 Flags0 = (int(LhsFlags) | int(RhsFlags)) & (
00090 HereditaryBits
00091 | (int(LhsFlags) & int(RhsFlags) &
00092 ( AlignedBit
00093 | (StorageOrdersAgree ? LinearAccessBit : 0)
00094 | (functor_traits<BinaryOp>::PacketAccess && StorageOrdersAgree && SameType ? PacketAccessBit : 0)
00095 )
00096 )
00097 ),
00098 Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit),
00099 CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + functor_traits<BinaryOp>::Cost
00100 };
00101 };
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111 #define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
00112 EIGEN_STATIC_ASSERT((internal::functor_allows_mixing_real_and_complex<BINOP>::ret \
00113 ? int(internal::is_same<typename NumTraits<LHS>::Real, typename NumTraits<RHS>::Real>::value) \
00114 : int(internal::is_same<LHS, RHS>::value)), \
00115 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
00116
00117 template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
00118 class CwiseBinaryOpImpl;
00119
00120 template<typename BinaryOp, typename Lhs, typename Rhs>
00121 class CwiseBinaryOp : internal::no_assignment_operator,
00122 public CwiseBinaryOpImpl<
00123 BinaryOp, Lhs, Rhs,
00124 typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
00125 typename internal::traits<Rhs>::StorageKind>::ret>
00126 {
00127 public:
00128
00129 typedef typename CwiseBinaryOpImpl<
00130 BinaryOp, Lhs, Rhs,
00131 typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
00132 typename internal::traits<Rhs>::StorageKind>::ret>::Base Base;
00133 EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp)
00134
00135 typedef typename internal::nested<Lhs>::type LhsNested;
00136 typedef typename internal::nested<Rhs>::type RhsNested;
00137 typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
00138 typedef typename internal::remove_reference<RhsNested>::type _RhsNested;
00139
00140 EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& lhs, const Rhs& rhs, const BinaryOp& func = BinaryOp())
00141 : m_lhs(lhs), m_rhs(rhs), m_functor(func)
00142 {
00143 EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
00144
00145 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
00146 eigen_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
00147 }
00148
00149 EIGEN_STRONG_INLINE Index rows() const {
00150
00151 if (internal::traits<typename internal::remove_all<LhsNested>::type>::RowsAtCompileTime==Dynamic)
00152 return m_rhs.rows();
00153 else
00154 return m_lhs.rows();
00155 }
00156 EIGEN_STRONG_INLINE Index cols() const {
00157
00158 if (internal::traits<typename internal::remove_all<LhsNested>::type>::ColsAtCompileTime==Dynamic)
00159 return m_rhs.cols();
00160 else
00161 return m_lhs.cols();
00162 }
00163
00165 const _LhsNested& lhs() const { return m_lhs; }
00167 const _RhsNested& rhs() const { return m_rhs; }
00169 const BinaryOp& functor() const { return m_functor; }
00170
00171 protected:
00172 LhsNested m_lhs;
00173 RhsNested m_rhs;
00174 const BinaryOp m_functor;
00175 };
00176
00177 template<typename BinaryOp, typename Lhs, typename Rhs>
00178 class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense>
00179 : public internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
00180 {
00181 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
00182 public:
00183
00184 typedef typename internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base;
00185 EIGEN_DENSE_PUBLIC_INTERFACE( Derived )
00186
00187 EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
00188 {
00189 return derived().functor()(derived().lhs().coeff(row, col),
00190 derived().rhs().coeff(row, col));
00191 }
00192
00193 template<int LoadMode>
00194 EIGEN_STRONG_INLINE PacketScalar packet(Index row, Index col) const
00195 {
00196 return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(row, col),
00197 derived().rhs().template packet<LoadMode>(row, col));
00198 }
00199
00200 EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
00201 {
00202 return derived().functor()(derived().lhs().coeff(index),
00203 derived().rhs().coeff(index));
00204 }
00205
00206 template<int LoadMode>
00207 EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
00208 {
00209 return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(index),
00210 derived().rhs().template packet<LoadMode>(index));
00211 }
00212 };
00213
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_difference_op<Scalar>, Derived, OtherDerived> tmp(derived());
00224 tmp = other.derived();
00225 return derived();
00226 }
00227
00232 template<typename Derived>
00233 template<typename OtherDerived>
00234 EIGEN_STRONG_INLINE Derived &
00235 MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
00236 {
00237 SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, Derived, OtherDerived> tmp(derived());
00238 tmp = other.derived();
00239 return derived();
00240 }
00241
00242 }
00243
00244 #endif // EIGEN_CWISE_BINARY_OP_H