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_PARTIAL_REDUX_H
00027 #define EIGEN_PARTIAL_REDUX_H
00028
00046 template< typename MatrixType, typename MemberOp, int Direction>
00047 class PartialReduxExpr;
00048
00049 template<typename MatrixType, typename MemberOp, int Direction>
00050 struct ei_traits<PartialReduxExpr<MatrixType, MemberOp, Direction> >
00051 {
00052 typedef typename MemberOp::result_type Scalar;
00053 typedef typename MatrixType::Scalar InputScalar;
00054 typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
00055 typedef typename ei_cleantype<MatrixTypeNested>::type _MatrixTypeNested;
00056 enum {
00057 RowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::RowsAtCompileTime,
00058 ColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::ColsAtCompileTime,
00059 MaxRowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::MaxRowsAtCompileTime,
00060 MaxColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::MaxColsAtCompileTime,
00061 Flags = (unsigned int)_MatrixTypeNested::Flags & HereditaryBits,
00062 TraversalSize = Direction==Vertical ? RowsAtCompileTime : ColsAtCompileTime
00063 };
00064 #if EIGEN_GNUC_AT_LEAST(3,4)
00065 typedef typename MemberOp::template Cost<InputScalar,int(TraversalSize)> CostOpType;
00066 #else
00067 typedef typename MemberOp::template Cost<InputScalar,TraversalSize> CostOpType;
00068 #endif
00069 enum {
00070 CoeffReadCost = TraversalSize * ei_traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value)
00071 };
00072 };
00073
00074 template< typename MatrixType, typename MemberOp, int Direction>
00075 class PartialReduxExpr : ei_no_assignment_operator,
00076 public MatrixBase<PartialReduxExpr<MatrixType, MemberOp, Direction> >
00077 {
00078 public:
00079
00080 EIGEN_GENERIC_PUBLIC_INTERFACE(PartialReduxExpr)
00081 typedef typename ei_traits<PartialReduxExpr>::MatrixTypeNested MatrixTypeNested;
00082 typedef typename ei_traits<PartialReduxExpr>::_MatrixTypeNested _MatrixTypeNested;
00083
00084 PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
00085 : m_matrix(mat), m_functor(func) {}
00086
00087 int rows() const { return (Direction==Vertical ? 1 : m_matrix.rows()); }
00088 int cols() const { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
00089
00090 const Scalar coeff(int i, int j) const
00091 {
00092 if (Direction==Vertical)
00093 return m_functor(m_matrix.col(j));
00094 else
00095 return m_functor(m_matrix.row(i));
00096 }
00097
00098 protected:
00099 const MatrixTypeNested m_matrix;
00100 const MemberOp m_functor;
00101 };
00102
00103 #define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \
00104 template <typename ResultType> \
00105 struct ei_member_##MEMBER EIGEN_EMPTY_STRUCT { \
00106 typedef ResultType result_type; \
00107 template<typename Scalar, int Size> struct Cost \
00108 { enum { value = COST }; }; \
00109 template<typename Derived> \
00110 inline ResultType operator()(const MatrixBase<Derived>& mat) const \
00111 { return mat.MEMBER(); } \
00112 }
00113
00114 EIGEN_MEMBER_FUNCTOR(squaredNorm, Size * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
00115 EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
00116 EIGEN_MEMBER_FUNCTOR(sum, (Size-1)*NumTraits<Scalar>::AddCost);
00117 EIGEN_MEMBER_FUNCTOR(minCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
00118 EIGEN_MEMBER_FUNCTOR(maxCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
00119 EIGEN_MEMBER_FUNCTOR(all, (Size-1)*NumTraits<Scalar>::AddCost);
00120 EIGEN_MEMBER_FUNCTOR(any, (Size-1)*NumTraits<Scalar>::AddCost);
00121 EIGEN_MEMBER_FUNCTOR(count, (Size-1)*NumTraits<Scalar>::AddCost);
00122
00124 template <typename BinaryOp, typename Scalar>
00125 struct ei_member_redux {
00126 typedef typename ei_result_of<
00127 BinaryOp(Scalar)
00128 >::type result_type;
00129 template<typename _Scalar, int Size> struct Cost
00130 { enum { value = (Size-1) * ei_functor_traits<BinaryOp>::Cost }; };
00131 ei_member_redux(const BinaryOp func) : m_functor(func) {}
00132 template<typename Derived>
00133 inline result_type operator()(const MatrixBase<Derived>& mat) const
00134 { return mat.redux(m_functor); }
00135 const BinaryOp m_functor;
00136 private:
00137 ei_member_redux& operator=(const ei_member_redux&);
00138 };
00139
00158 template<typename ExpressionType, int Direction> class PartialRedux
00159 {
00160 public:
00161
00162 typedef typename ei_traits<ExpressionType>::Scalar Scalar;
00163 typedef typename NumTraits<Scalar>::Real RealScalar;
00164 typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret,
00165 ExpressionType, const ExpressionType&>::ret ExpressionTypeNested;
00166
00167 template<template<typename _Scalar> class Functor,
00168 typename Scalar = typename ei_traits<ExpressionType>::Scalar> struct ReturnType
00169 {
00170 typedef PartialReduxExpr<ExpressionType,
00171 Functor<Scalar>,
00172 Direction
00173 > Type;
00174 };
00175
00176 template<typename BinaryOp> struct ReduxReturnType
00177 {
00178 typedef PartialReduxExpr<ExpressionType,
00179 ei_member_redux<BinaryOp,typename ei_traits<ExpressionType>::Scalar>,
00180 Direction
00181 > Type;
00182 };
00183
00184 typedef typename ExpressionType::PlainMatrixType CrossReturnType;
00185
00186 inline PartialRedux(const ExpressionType& matrix) : m_matrix(matrix) {}
00187
00189 inline const ExpressionType& _expression() const { return m_matrix; }
00190
00191 template<typename BinaryOp>
00192 const typename ReduxReturnType<BinaryOp>::Type
00193 redux(const BinaryOp& func = BinaryOp()) const;
00194
00202 const typename ReturnType<ei_member_minCoeff>::Type minCoeff() const
00203 { return _expression(); }
00204
00212 const typename ReturnType<ei_member_maxCoeff>::Type maxCoeff() const
00213 { return _expression(); }
00214
00222 const typename ReturnType<ei_member_squaredNorm,RealScalar>::Type squaredNorm() const
00223 { return _expression(); }
00224
00232 const typename ReturnType<ei_member_norm,RealScalar>::Type norm() const
00233 { return _expression(); }
00234
00242 const typename ReturnType<ei_member_sum>::Type sum() const
00243 { return _expression(); }
00244
00249 const typename ReturnType<ei_member_all>::Type all() const
00250 { return _expression(); }
00251
00256 const typename ReturnType<ei_member_any>::Type any() const
00257 { return _expression(); }
00258
00266 const PartialReduxExpr<ExpressionType, ei_member_count<int>, Direction> count() const
00267 { return _expression(); }
00268
00275 template<typename OtherDerived>
00276 const CrossReturnType cross(const MatrixBase<OtherDerived>& other) const
00277 {
00278 EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(CrossReturnType,3,3)
00279 EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,3)
00280 EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
00281 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
00282
00283 if(Direction==Vertical)
00284 return (CrossReturnType()
00285 << _expression().col(0).cross(other),
00286 _expression().col(1).cross(other),
00287 _expression().col(2).cross(other)).finished();
00288 else
00289 return (CrossReturnType()
00290 << _expression().row(0).cross(other),
00291 _expression().row(1).cross(other),
00292 _expression().row(2).cross(other)).finished();
00293 }
00294
00295 protected:
00296 ExpressionTypeNested m_matrix;
00297
00298 private:
00299 PartialRedux& operator=(const PartialRedux&);
00300 };
00301
00311 template<typename Derived>
00312 inline const PartialRedux<Derived,Vertical>
00313 MatrixBase<Derived>::colwise() const
00314 {
00315 return derived();
00316 }
00317
00327 template<typename Derived>
00328 inline const PartialRedux<Derived,Horizontal>
00329 MatrixBase<Derived>::rowwise() const
00330 {
00331 return derived();
00332 }
00333
00341 template<typename ExpressionType, int Direction>
00342 template<typename BinaryOp>
00343 const typename PartialRedux<ExpressionType,Direction>::template ReduxReturnType<BinaryOp>::Type
00344 PartialRedux<ExpressionType,Direction>::redux(const BinaryOp& func) const
00345 {
00346 return typename ReduxReturnType<BinaryOp>::Type(_expression(), func);
00347 }
00348
00349 #endif // EIGEN_PARTIAL_REDUX_H