00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef EIGEN_PARTIAL_REDUX_H
00012 #define EIGEN_PARTIAL_REDUX_H
00013
00014 namespace Eigen {
00015
00032 template< typename MatrixType, typename MemberOp, int Direction>
00033 class PartialReduxExpr;
00034
00035 namespace internal {
00036 template<typename MatrixType, typename MemberOp, int Direction>
00037 struct traits<PartialReduxExpr<MatrixType, MemberOp, Direction> >
00038 : traits<MatrixType>
00039 {
00040 typedef typename MemberOp::result_type Scalar;
00041 typedef typename traits<MatrixType>::StorageKind StorageKind;
00042 typedef typename traits<MatrixType>::XprKind XprKind;
00043 typedef typename MatrixType::Scalar InputScalar;
00044 typedef typename nested<MatrixType>::type MatrixTypeNested;
00045 typedef typename remove_all<MatrixTypeNested>::type _MatrixTypeNested;
00046 enum {
00047 RowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::RowsAtCompileTime,
00048 ColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::ColsAtCompileTime,
00049 MaxRowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::MaxRowsAtCompileTime,
00050 MaxColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::MaxColsAtCompileTime,
00051 Flags0 = (unsigned int)_MatrixTypeNested::Flags & HereditaryBits,
00052 Flags = (Flags0 & ~RowMajorBit) | (RowsAtCompileTime == 1 ? RowMajorBit : 0),
00053 TraversalSize = Direction==Vertical ? MatrixType::RowsAtCompileTime : MatrixType::ColsAtCompileTime
00054 };
00055 #if EIGEN_GNUC_AT_LEAST(3,4)
00056 typedef typename MemberOp::template Cost<InputScalar,int(TraversalSize)> CostOpType;
00057 #else
00058 typedef typename MemberOp::template Cost<InputScalar,TraversalSize> CostOpType;
00059 #endif
00060 enum {
00061 CoeffReadCost = TraversalSize==Dynamic ? Dynamic
00062 : TraversalSize * traits<_MatrixTypeNested>::CoeffReadCost + int(CostOpType::value)
00063 };
00064 };
00065 }
00066
00067 template< typename MatrixType, typename MemberOp, int Direction>
00068 class PartialReduxExpr : internal::no_assignment_operator,
00069 public internal::dense_xpr_base< PartialReduxExpr<MatrixType, MemberOp, Direction> >::type
00070 {
00071 public:
00072
00073 typedef typename internal::dense_xpr_base<PartialReduxExpr>::type Base;
00074 EIGEN_DENSE_PUBLIC_INTERFACE(PartialReduxExpr)
00075 typedef typename internal::traits<PartialReduxExpr>::MatrixTypeNested MatrixTypeNested;
00076 typedef typename internal::traits<PartialReduxExpr>::_MatrixTypeNested _MatrixTypeNested;
00077
00078 PartialReduxExpr(const MatrixType& mat, const MemberOp& func = MemberOp())
00079 : m_matrix(mat), m_functor(func) {}
00080
00081 Index rows() const { return (Direction==Vertical ? 1 : m_matrix.rows()); }
00082 Index cols() const { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
00083
00084 EIGEN_STRONG_INLINE const Scalar coeff(Index i, Index j) const
00085 {
00086 if (Direction==Vertical)
00087 return m_functor(m_matrix.col(j));
00088 else
00089 return m_functor(m_matrix.row(i));
00090 }
00091
00092 const Scalar coeff(Index index) const
00093 {
00094 if (Direction==Vertical)
00095 return m_functor(m_matrix.col(index));
00096 else
00097 return m_functor(m_matrix.row(index));
00098 }
00099
00100 protected:
00101 MatrixTypeNested m_matrix;
00102 const MemberOp m_functor;
00103 };
00104
00105 #define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \
00106 template <typename ResultType> \
00107 struct member_##MEMBER { \
00108 EIGEN_EMPTY_STRUCT_CTOR(member_##MEMBER) \
00109 typedef ResultType result_type; \
00110 template<typename Scalar, int Size> struct Cost \
00111 { enum { value = COST }; }; \
00112 template<typename XprType> \
00113 EIGEN_STRONG_INLINE ResultType operator()(const XprType& mat) const \
00114 { return mat.MEMBER(); } \
00115 }
00116
00117 namespace internal {
00118
00119 EIGEN_MEMBER_FUNCTOR(squaredNorm, Size * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
00120 EIGEN_MEMBER_FUNCTOR(norm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
00121 EIGEN_MEMBER_FUNCTOR(stableNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
00122 EIGEN_MEMBER_FUNCTOR(blueNorm, (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost);
00123 EIGEN_MEMBER_FUNCTOR(hypotNorm, (Size-1) * functor_traits<scalar_hypot_op<Scalar> >::Cost );
00124 EIGEN_MEMBER_FUNCTOR(sum, (Size-1)*NumTraits<Scalar>::AddCost);
00125 EIGEN_MEMBER_FUNCTOR(mean, (Size-1)*NumTraits<Scalar>::AddCost + NumTraits<Scalar>::MulCost);
00126 EIGEN_MEMBER_FUNCTOR(minCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
00127 EIGEN_MEMBER_FUNCTOR(maxCoeff, (Size-1)*NumTraits<Scalar>::AddCost);
00128 EIGEN_MEMBER_FUNCTOR(all, (Size-1)*NumTraits<Scalar>::AddCost);
00129 EIGEN_MEMBER_FUNCTOR(any, (Size-1)*NumTraits<Scalar>::AddCost);
00130 EIGEN_MEMBER_FUNCTOR(count, (Size-1)*NumTraits<Scalar>::AddCost);
00131 EIGEN_MEMBER_FUNCTOR(prod, (Size-1)*NumTraits<Scalar>::MulCost);
00132
00133
00134 template <typename BinaryOp, typename Scalar>
00135 struct member_redux {
00136 typedef typename result_of<
00137 BinaryOp(Scalar)
00138 >::type result_type;
00139 template<typename _Scalar, int Size> struct Cost
00140 { enum { value = (Size-1) * functor_traits<BinaryOp>::Cost }; };
00141 member_redux(const BinaryOp func) : m_functor(func) {}
00142 template<typename Derived>
00143 inline result_type operator()(const DenseBase<Derived>& mat) const
00144 { return mat.redux(m_functor); }
00145 const BinaryOp m_functor;
00146 };
00147 }
00148
00166 template<typename ExpressionType, int Direction> class VectorwiseOp
00167 {
00168 public:
00169
00170 typedef typename ExpressionType::Scalar Scalar;
00171 typedef typename ExpressionType::RealScalar RealScalar;
00172 typedef typename ExpressionType::Index Index;
00173 typedef typename internal::conditional<internal::must_nest_by_value<ExpressionType>::ret,
00174 ExpressionType, ExpressionType&>::type ExpressionTypeNested;
00175 typedef typename internal::remove_all<ExpressionTypeNested>::type ExpressionTypeNestedCleaned;
00176
00177 template<template<typename _Scalar> class Functor,
00178 typename Scalar=typename internal::traits<ExpressionType>::Scalar> struct ReturnType
00179 {
00180 typedef PartialReduxExpr<ExpressionType,
00181 Functor<Scalar>,
00182 Direction
00183 > Type;
00184 };
00185
00186 template<typename BinaryOp> struct ReduxReturnType
00187 {
00188 typedef PartialReduxExpr<ExpressionType,
00189 internal::member_redux<BinaryOp,typename internal::traits<ExpressionType>::Scalar>,
00190 Direction
00191 > Type;
00192 };
00193
00194 enum {
00195 IsVertical = (Direction==Vertical) ? 1 : 0,
00196 IsHorizontal = (Direction==Horizontal) ? 1 : 0
00197 };
00198
00199 protected:
00200
00203 typedef typename internal::conditional<Direction==Vertical,
00204 typename ExpressionType::ColXpr,
00205 typename ExpressionType::RowXpr>::type SubVector;
00206 SubVector subVector(Index i)
00207 {
00208 return SubVector(m_matrix.derived(),i);
00209 }
00210
00213 Index subVectors() const
00214 { return Direction==Vertical?m_matrix.cols():m_matrix.rows(); }
00215
00216 template<typename OtherDerived> struct ExtendedType {
00217 typedef Replicate<OtherDerived,
00218 Direction==Vertical ? 1 : ExpressionType::RowsAtCompileTime,
00219 Direction==Horizontal ? 1 : ExpressionType::ColsAtCompileTime> Type;
00220 };
00221
00224 template<typename OtherDerived>
00225 typename ExtendedType<OtherDerived>::Type
00226 extendedTo(const DenseBase<OtherDerived>& other) const
00227 {
00228 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Vertical, OtherDerived::MaxColsAtCompileTime==1),
00229 YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED)
00230 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Horizontal, OtherDerived::MaxRowsAtCompileTime==1),
00231 YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED)
00232 return typename ExtendedType<OtherDerived>::Type
00233 (other.derived(),
00234 Direction==Vertical ? 1 : m_matrix.rows(),
00235 Direction==Horizontal ? 1 : m_matrix.cols());
00236 }
00237
00238 template<typename OtherDerived> struct OppositeExtendedType {
00239 typedef Replicate<OtherDerived,
00240 Direction==Horizontal ? 1 : ExpressionType::RowsAtCompileTime,
00241 Direction==Vertical ? 1 : ExpressionType::ColsAtCompileTime> Type;
00242 };
00243
00246 template<typename OtherDerived>
00247 typename OppositeExtendedType<OtherDerived>::Type
00248 extendedToOpposite(const DenseBase<OtherDerived>& other) const
00249 {
00250 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Horizontal, OtherDerived::MaxColsAtCompileTime==1),
00251 YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED)
00252 EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(Direction==Vertical, OtherDerived::MaxRowsAtCompileTime==1),
00253 YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED)
00254 return typename OppositeExtendedType<OtherDerived>::Type
00255 (other.derived(),
00256 Direction==Horizontal ? 1 : m_matrix.rows(),
00257 Direction==Vertical ? 1 : m_matrix.cols());
00258 }
00259
00260 public:
00261
00262 inline VectorwiseOp(ExpressionType& matrix) : m_matrix(matrix) {}
00263
00265 inline const ExpressionType& _expression() const { return m_matrix; }
00266
00274 template<typename BinaryOp>
00275 const typename ReduxReturnType<BinaryOp>::Type
00276 redux(const BinaryOp& func = BinaryOp()) const
00277 { return typename ReduxReturnType<BinaryOp>::Type(_expression(), func); }
00278
00288 const typename ReturnType<internal::member_minCoeff>::Type minCoeff() const
00289 { return _expression(); }
00290
00300 const typename ReturnType<internal::member_maxCoeff>::Type maxCoeff() const
00301 { return _expression(); }
00302
00310 const typename ReturnType<internal::member_squaredNorm,RealScalar>::Type squaredNorm() const
00311 { return _expression(); }
00312
00320 const typename ReturnType<internal::member_norm,RealScalar>::Type norm() const
00321 { return _expression(); }
00322
00323
00329 const typename ReturnType<internal::member_blueNorm,RealScalar>::Type blueNorm() const
00330 { return _expression(); }
00331
00332
00338 const typename ReturnType<internal::member_stableNorm,RealScalar>::Type stableNorm() const
00339 { return _expression(); }
00340
00341
00347 const typename ReturnType<internal::member_hypotNorm,RealScalar>::Type hypotNorm() const
00348 { return _expression(); }
00349
00357 const typename ReturnType<internal::member_sum>::Type sum() const
00358 { return _expression(); }
00359
00364 const typename ReturnType<internal::member_mean>::Type mean() const
00365 { return _expression(); }
00366
00371 const typename ReturnType<internal::member_all>::Type all() const
00372 { return _expression(); }
00373
00378 const typename ReturnType<internal::member_any>::Type any() const
00379 { return _expression(); }
00380
00388 const PartialReduxExpr<ExpressionType, internal::member_count<Index>, Direction> count() const
00389 { return _expression(); }
00390
00398 const typename ReturnType<internal::member_prod>::Type prod() const
00399 { return _expression(); }
00400
00401
00409 const Reverse<ExpressionType, Direction> reverse() const
00410 { return Reverse<ExpressionType, Direction>( _expression() ); }
00411
00412 typedef Replicate<ExpressionType,Direction==Vertical?Dynamic:1,Direction==Horizontal?Dynamic:1> ReplicateReturnType;
00413 const ReplicateReturnType replicate(Index factor) const;
00414
00423
00424 template<int Factor> const Replicate<ExpressionType,(IsVertical?Factor:1),(IsHorizontal?Factor:1)>
00425 replicate(Index factor = Factor) const
00426 {
00427 return Replicate<ExpressionType,Direction==Vertical?Factor:1,Direction==Horizontal?Factor:1>
00428 (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1);
00429 }
00430
00432
00434 template<typename OtherDerived>
00435 ExpressionType& operator=(const DenseBase<OtherDerived>& other)
00436 {
00437 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
00438 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
00439
00440 return const_cast<ExpressionType&>(m_matrix = extendedTo(other.derived()));
00441 }
00442
00444 template<typename OtherDerived>
00445 ExpressionType& operator+=(const DenseBase<OtherDerived>& other)
00446 {
00447 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
00448 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
00449 return const_cast<ExpressionType&>(m_matrix += extendedTo(other.derived()));
00450 }
00451
00453 template<typename OtherDerived>
00454 ExpressionType& operator-=(const DenseBase<OtherDerived>& other)
00455 {
00456 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
00457 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
00458 return const_cast<ExpressionType&>(m_matrix -= extendedTo(other.derived()));
00459 }
00460
00462 template<typename OtherDerived>
00463 ExpressionType& operator*=(const DenseBase<OtherDerived>& other)
00464 {
00465 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
00466 EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
00467 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
00468 m_matrix *= extendedTo(other.derived());
00469 return const_cast<ExpressionType&>(m_matrix);
00470 }
00471
00473 template<typename OtherDerived>
00474 ExpressionType& operator/=(const DenseBase<OtherDerived>& other)
00475 {
00476 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
00477 EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
00478 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
00479 m_matrix /= extendedTo(other.derived());
00480 return const_cast<ExpressionType&>(m_matrix);
00481 }
00482
00484 template<typename OtherDerived> EIGEN_STRONG_INLINE
00485 CwiseBinaryOp<internal::scalar_sum_op<Scalar>,
00486 const ExpressionTypeNestedCleaned,
00487 const typename ExtendedType<OtherDerived>::Type>
00488 operator+(const DenseBase<OtherDerived>& other) const
00489 {
00490 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
00491 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
00492 return m_matrix + extendedTo(other.derived());
00493 }
00494
00496 template<typename OtherDerived>
00497 CwiseBinaryOp<internal::scalar_difference_op<Scalar>,
00498 const ExpressionTypeNestedCleaned,
00499 const typename ExtendedType<OtherDerived>::Type>
00500 operator-(const DenseBase<OtherDerived>& other) const
00501 {
00502 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
00503 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
00504 return m_matrix - extendedTo(other.derived());
00505 }
00506
00509 template<typename OtherDerived> EIGEN_STRONG_INLINE
00510 CwiseBinaryOp<internal::scalar_product_op<Scalar>,
00511 const ExpressionTypeNestedCleaned,
00512 const typename ExtendedType<OtherDerived>::Type>
00513 operator*(const DenseBase<OtherDerived>& other) const
00514 {
00515 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
00516 EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
00517 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
00518 return m_matrix * extendedTo(other.derived());
00519 }
00520
00523 template<typename OtherDerived>
00524 CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
00525 const ExpressionTypeNestedCleaned,
00526 const typename ExtendedType<OtherDerived>::Type>
00527 operator/(const DenseBase<OtherDerived>& other) const
00528 {
00529 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
00530 EIGEN_STATIC_ASSERT_ARRAYXPR(ExpressionType)
00531 EIGEN_STATIC_ASSERT_SAME_XPR_KIND(ExpressionType, OtherDerived)
00532 return m_matrix / extendedTo(other.derived());
00533 }
00534
00539 CwiseBinaryOp<internal::scalar_quotient_op<Scalar>,
00540 const ExpressionTypeNestedCleaned,
00541 const typename OppositeExtendedType<typename ReturnType<internal::member_norm,RealScalar>::Type>::Type>
00542 normalized() const { return m_matrix.cwiseQuotient(extendedToOpposite(this->norm())); }
00543
00544
00548 void normalize() {
00549 m_matrix = this->normalized();
00550 }
00551
00553
00554 #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
00555 Homogeneous<ExpressionType,Direction> homogeneous() const;
00556 #endif
00557
00558 typedef typename ExpressionType::PlainObject CrossReturnType;
00559 template<typename OtherDerived>
00560 const CrossReturnType cross(const MatrixBase<OtherDerived>& other) const;
00561
00562 enum {
00563 HNormalized_Size = Direction==Vertical ? internal::traits<ExpressionType>::RowsAtCompileTime
00564 : internal::traits<ExpressionType>::ColsAtCompileTime,
00565 HNormalized_SizeMinusOne = HNormalized_Size==Dynamic ? Dynamic : HNormalized_Size-1
00566 };
00567 typedef Block<const ExpressionType,
00568 Direction==Vertical ? int(HNormalized_SizeMinusOne)
00569 : int(internal::traits<ExpressionType>::RowsAtCompileTime),
00570 Direction==Horizontal ? int(HNormalized_SizeMinusOne)
00571 : int(internal::traits<ExpressionType>::ColsAtCompileTime)>
00572 HNormalized_Block;
00573 typedef Block<const ExpressionType,
00574 Direction==Vertical ? 1 : int(internal::traits<ExpressionType>::RowsAtCompileTime),
00575 Direction==Horizontal ? 1 : int(internal::traits<ExpressionType>::ColsAtCompileTime)>
00576 HNormalized_Factors;
00577 typedef CwiseBinaryOp<internal::scalar_quotient_op<typename internal::traits<ExpressionType>::Scalar>,
00578 const HNormalized_Block,
00579 const Replicate<HNormalized_Factors,
00580 Direction==Vertical ? HNormalized_SizeMinusOne : 1,
00581 Direction==Horizontal ? HNormalized_SizeMinusOne : 1> >
00582 HNormalizedReturnType;
00583
00584 const HNormalizedReturnType hnormalized() const;
00585
00586 protected:
00587 ExpressionTypeNested m_matrix;
00588 };
00589
00597 template<typename Derived>
00598 inline const typename DenseBase<Derived>::ConstColwiseReturnType
00599 DenseBase<Derived>::colwise() const
00600 {
00601 return derived();
00602 }
00603
00608 template<typename Derived>
00609 inline typename DenseBase<Derived>::ColwiseReturnType
00610 DenseBase<Derived>::colwise()
00611 {
00612 return derived();
00613 }
00614
00622 template<typename Derived>
00623 inline const typename DenseBase<Derived>::ConstRowwiseReturnType
00624 DenseBase<Derived>::rowwise() const
00625 {
00626 return derived();
00627 }
00628
00633 template<typename Derived>
00634 inline typename DenseBase<Derived>::RowwiseReturnType
00635 DenseBase<Derived>::rowwise()
00636 {
00637 return derived();
00638 }
00639
00640 }
00641
00642 #endif // EIGEN_PARTIAL_REDUX_H