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
00046 template<typename BinaryOp, typename Lhs, typename Rhs>
00047 struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
00048 {
00049
00050
00051 typedef typename ei_result_of<
00052 BinaryOp(
00053 typename Lhs::Scalar,
00054 typename Rhs::Scalar
00055 )
00056 >::type Scalar;
00057 typedef typename Lhs::Nested LhsNested;
00058 typedef typename Rhs::Nested RhsNested;
00059 typedef typename ei_unref<LhsNested>::type _LhsNested;
00060 typedef typename ei_unref<RhsNested>::type _RhsNested;
00061 enum {
00062 LhsCoeffReadCost = _LhsNested::CoeffReadCost,
00063 RhsCoeffReadCost = _RhsNested::CoeffReadCost,
00064 LhsFlags = _LhsNested::Flags,
00065 RhsFlags = _RhsNested::Flags,
00066 RowsAtCompileTime = Lhs::RowsAtCompileTime,
00067 ColsAtCompileTime = Lhs::ColsAtCompileTime,
00068 MaxRowsAtCompileTime = Lhs::MaxRowsAtCompileTime,
00069 MaxColsAtCompileTime = Lhs::MaxColsAtCompileTime,
00070 Flags = (int(LhsFlags) | int(RhsFlags)) & (
00071 HereditaryBits
00072 | (int(LhsFlags) & int(RhsFlags) & (LinearAccessBit | AlignedBit))
00073 | (ei_functor_traits<BinaryOp>::PacketAccess && ((int(LhsFlags) & RowMajorBit)==(int(RhsFlags) & RowMajorBit))
00074 ? (int(LhsFlags) & int(RhsFlags) & PacketAccessBit) : 0)),
00075 CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + ei_functor_traits<BinaryOp>::Cost
00076 };
00077 };
00078
00079 template<typename BinaryOp, typename Lhs, typename Rhs>
00080 class CwiseBinaryOp : ei_no_assignment_operator,
00081 public MatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
00082 {
00083 public:
00084
00085 EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp)
00086 typedef typename ei_traits<CwiseBinaryOp>::LhsNested LhsNested;
00087 typedef typename ei_traits<CwiseBinaryOp>::RhsNested RhsNested;
00088
00089 EIGEN_STRONG_INLINE CwiseBinaryOp(const Lhs& lhs, const Rhs& rhs, const BinaryOp& func = BinaryOp())
00090 : m_lhs(lhs), m_rhs(rhs), m_functor(func)
00091 {
00092
00093
00094
00095
00096
00097
00098
00099 EIGEN_STATIC_ASSERT((ei_functor_allows_mixing_real_and_complex<BinaryOp>::ret
00100 ? int(ei_is_same_type<typename Lhs::RealScalar, typename Rhs::RealScalar>::ret)
00101 : int(ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret)),
00102 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
00103
00104 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs)
00105 ei_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols());
00106 }
00107
00108 EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); }
00109 EIGEN_STRONG_INLINE int cols() const { return m_lhs.cols(); }
00110
00111 EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const
00112 {
00113 return m_functor(m_lhs.coeff(row, col), m_rhs.coeff(row, col));
00114 }
00115
00116 template<int LoadMode>
00117 EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const
00118 {
00119 return m_functor.packetOp(m_lhs.template packet<LoadMode>(row, col), m_rhs.template packet<LoadMode>(row, col));
00120 }
00121
00122 EIGEN_STRONG_INLINE const Scalar coeff(int index) const
00123 {
00124 return m_functor(m_lhs.coeff(index), m_rhs.coeff(index));
00125 }
00126
00127 template<int LoadMode>
00128 EIGEN_STRONG_INLINE PacketScalar packet(int index) const
00129 {
00130 return m_functor.packetOp(m_lhs.template packet<LoadMode>(index), m_rhs.template packet<LoadMode>(index));
00131 }
00132
00133 protected:
00134 const LhsNested m_lhs;
00135 const RhsNested m_rhs;
00136 const BinaryOp m_functor;
00137 };
00138
00145 template<typename Derived>
00146 template<typename OtherDerived>
00147 EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>,
00148 Derived, OtherDerived>
00149 MatrixBase<Derived>::operator-(const MatrixBase<OtherDerived> &other) const
00150 {
00151 return CwiseBinaryOp<ei_scalar_difference_op<Scalar>,
00152 Derived, OtherDerived>(derived(), other.derived());
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 return *this = *this - other;
00165 }
00166
00175 template<typename Derived>
00176 template<typename OtherDerived>
00177 EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived>
00178 MatrixBase<Derived>::operator+(const MatrixBase<OtherDerived> &other) const
00179 {
00180 return CwiseBinaryOp<ei_scalar_sum_op<Scalar>, Derived, OtherDerived>(derived(), other.derived());
00181 }
00182
00187 template<typename Derived>
00188 template<typename OtherDerived>
00189 EIGEN_STRONG_INLINE Derived &
00190 MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other)
00191 {
00192 return *this = *this + other;
00193 }
00194
00202 template<typename ExpressionType>
00203 template<typename OtherDerived>
00204 EIGEN_STRONG_INLINE const EIGEN_CWISE_PRODUCT_RETURN_TYPE
00205 Cwise<ExpressionType>::operator*(const MatrixBase<OtherDerived> &other) const
00206 {
00207 return EIGEN_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived());
00208 }
00209
00217 template<typename ExpressionType>
00218 template<typename OtherDerived>
00219 EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)
00220 Cwise<ExpressionType>::operator/(const MatrixBase<OtherDerived> &other) const
00221 {
00222 return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)(_expression(), other.derived());
00223 }
00224
00232 template<typename ExpressionType>
00233 template<typename OtherDerived>
00234 inline ExpressionType& Cwise<ExpressionType>::operator*=(const MatrixBase<OtherDerived> &other)
00235 {
00236 return m_matrix.const_cast_derived() = *this * other;
00237 }
00238
00246 template<typename ExpressionType>
00247 template<typename OtherDerived>
00248 inline ExpressionType& Cwise<ExpressionType>::operator/=(const MatrixBase<OtherDerived> &other)
00249 {
00250 return m_matrix.const_cast_derived() = *this / other;
00251 }
00252
00260 template<typename ExpressionType>
00261 template<typename OtherDerived>
00262 EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)
00263 Cwise<ExpressionType>::min(const MatrixBase<OtherDerived> &other) const
00264 {
00265 return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)(_expression(), other.derived());
00266 }
00267
00275 template<typename ExpressionType>
00276 template<typename OtherDerived>
00277 EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)
00278 Cwise<ExpressionType>::max(const MatrixBase<OtherDerived> &other) const
00279 {
00280 return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)(_expression(), other.derived());
00281 }
00282
00296 template<typename Derived>
00297 template<typename CustomBinaryOp, typename OtherDerived>
00298 EIGEN_STRONG_INLINE const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>
00299 MatrixBase<Derived>::binaryExpr(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func) const
00300 {
00301 return CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>(derived(), other.derived(), func);
00302 }
00303
00304 #endif // EIGEN_CWISE_BINARY_OP_H