From 627595ad191ffbb2bdab0466d15b951fdce55273 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 10 Jun 2009 11:20:30 +0200 Subject: [PATCH] * rename PartialRedux to VectorwiseOp * add VectorwiseOp's +, -, +=, -= operators --- Eigen/Array | 2 +- Eigen/src/Array/Replicate.h | 12 +- Eigen/src/Array/Reverse.h | 4 +- .../Array/{PartialRedux.h => VectorwiseOp.h} | 134 ++++++++++++++++-- Eigen/src/Core/Functors.h | 10 +- Eigen/src/Core/MatrixBase.h | 18 +-- Eigen/src/Core/util/ForwardDeclarations.h | 2 +- Eigen/src/Geometry/Homogeneous.h | 12 +- Eigen/src/Geometry/OrthoMethods.h | 4 +- Eigen/src/Geometry/Transform.h | 2 +- Eigen/src/Sparse/SparseMatrixBase.h | 4 +- ...dux_reverse.cpp => Vectorwise_reverse.cpp} | 0 test/array.cpp | 22 ++- 13 files changed, 174 insertions(+), 52 deletions(-) rename Eigen/src/Array/{PartialRedux.h => VectorwiseOp.h} (76%) rename doc/snippets/{PartialRedux_reverse.cpp => Vectorwise_reverse.cpp} (100%) diff --git a/Eigen/Array b/Eigen/Array index 57bd39e9e..2b5af088a 100644 --- a/Eigen/Array +++ b/Eigen/Array @@ -32,7 +32,7 @@ namespace Eigen { #include "src/Array/Functors.h" #include "src/Array/BooleanRedux.h" #include "src/Array/Select.h" -#include "src/Array/PartialRedux.h" +#include "src/Array/VectorwiseOp.h" #include "src/Array/Random.h" #include "src/Array/Norms.h" #include "src/Array/Replicate.h" diff --git a/Eigen/src/Array/Replicate.h b/Eigen/src/Array/Replicate.h index 4ffcc51e5..df3afbbdb 100644 --- a/Eigen/src/Array/Replicate.h +++ b/Eigen/src/Array/Replicate.h @@ -99,7 +99,7 @@ template class Replicate * Example: \include MatrixBase_replicate.cpp * Output: \verbinclude MatrixBase_replicate.out * - * \sa PartialRedux::replicate(), MatrixBase::replicate(int,int), class Replicate + * \sa VectorwiseOp::replicate(), MatrixBase::replicate(int,int), class Replicate */ template template @@ -115,7 +115,7 @@ MatrixBase::replicate() const * Example: \include MatrixBase_replicate_int_int.cpp * Output: \verbinclude MatrixBase_replicate_int_int.out * - * \sa PartialRedux::replicate(), MatrixBase::replicate(), class Replicate + * \sa VectorwiseOp::replicate(), MatrixBase::replicate(), class Replicate */ template inline const Replicate @@ -130,11 +130,11 @@ MatrixBase::replicate(int rowFactor,int colFactor) const * Example: \include DirectionWise_replicate_int.cpp * Output: \verbinclude DirectionWise_replicate_int.out * - * \sa PartialRedux::replicate(), MatrixBase::replicate(), class Replicate + * \sa VectorwiseOp::replicate(), MatrixBase::replicate(), class Replicate */ template const Replicate -PartialRedux::replicate(int factor) const +VectorwiseOp::replicate(int factor) const { return Replicate (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1); @@ -146,12 +146,12 @@ PartialRedux::replicate(int factor) const * Example: \include DirectionWise_replicate.cpp * Output: \verbinclude DirectionWise_replicate.out * - * \sa PartialRedux::replicate(int), MatrixBase::replicate(), class Replicate + * \sa VectorwiseOp::replicate(int), MatrixBase::replicate(), class Replicate */ template template const Replicate -PartialRedux::replicate(int factor) const +VectorwiseOp::replicate(int factor) const { return Replicate (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1); diff --git a/Eigen/src/Array/Reverse.h b/Eigen/src/Array/Reverse.h index 3ddf58d7a..4807bea55 100644 --- a/Eigen/src/Array/Reverse.h +++ b/Eigen/src/Array/Reverse.h @@ -36,10 +36,10 @@ * \param MatrixType the type of the object of which we are taking the reverse * * This class represents an expression of the reverse of a vector. - * It is the return type of MatrixBase::reverse() and PartialRedux::reverse() + * It is the return type of MatrixBase::reverse() and VectorwiseOp::reverse() * and most of the time this is the only way it is used. * - * \sa MatrixBase::reverse(), PartialRedux::reverse() + * \sa MatrixBase::reverse(), VectorwiseOp::reverse() */ template struct ei_traits > diff --git a/Eigen/src/Array/PartialRedux.h b/Eigen/src/Array/VectorwiseOp.h similarity index 76% rename from Eigen/src/Array/PartialRedux.h rename to Eigen/src/Array/VectorwiseOp.h index e2018edd0..50302bba4 100644 --- a/Eigen/src/Array/PartialRedux.h +++ b/Eigen/src/Array/VectorwiseOp.h @@ -37,10 +37,10 @@ * \param Direction indicates the direction of the redux (Vertical or Horizontal) * * This class represents an expression of a partial redux operator of a matrix. - * It is the return type of PartialRedux functions, + * It is the return type of some VectorwiseOp functions, * and most of the time this is the only way it is used. * - * \sa class PartialRedux + * \sa class VectorwiseOp */ template< typename MatrixType, typename MemberOp, int Direction> @@ -139,7 +139,7 @@ struct ei_member_redux { /** \array_module \ingroup Array_Module * - * \class PartialRedux + * \class VectorwiseOp * * \brief Pseudo expression providing partial reduction operations * @@ -155,7 +155,7 @@ struct ei_member_redux { * * \sa MatrixBase::colwise(), MatrixBase::rowwise(), class PartialReduxExpr */ -template class PartialRedux +template class VectorwiseOp { public: @@ -179,7 +179,45 @@ template class PartialRedux > Type; }; - inline PartialRedux(const ExpressionType& matrix) : m_matrix(matrix) {} + protected: + + /** \internal + * \returns the i-th subvector according to the \c Direction */ + typedef typename ei_meta_if::ret SubVector; + SubVector subVector(int i) + { + return SubVector(m_matrix.derived(),i); + } + + /** \internal + * \returns the number of subvectors in the direction \c Direction */ + int subVectors() const + { return Direction==Vertical?m_matrix.cols():m_matrix.rows(); } + + template struct ExtendedType { + typedef Replicate Type; + }; + + /** \internal + * Replicates a vector to match the size of \c *this */ + template + typename ExtendedType::Type + extendedTo(const MatrixBase& other) const + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived); + return typename ExtendedType::Type + (other.derived(), + Direction==Vertical ? 1 : m_matrix.rows(), + Direction==Horizontal ? 1 : m_matrix.cols()); + } + + public: + + inline VectorwiseOp(const ExpressionType& matrix) : m_matrix(matrix) {} /** \internal */ inline const ExpressionType& _expression() const { return m_matrix; } @@ -292,6 +330,48 @@ template class PartialRedux const Replicate replicate(int factor = Factor) const; +/////////// Artithmetic operators /////////// + + /** Adds the vector \a other to each subvector of \c *this */ + template + ExpressionType& operator+=(const MatrixBase& other) + { + for(int j=0; j(m_matrix); + } + + /** Substracts the vector \a other to each subvector of \c *this */ + template + ExpressionType& operator-=(const MatrixBase& other) + { + for(int j=0; j(m_matrix); + } + + /** Returns the expression of the sum of the vector \a other to each subvector of \c *this */ + template + CwiseBinaryOp, + ExpressionType, + NestByValue::Type> > + operator+(const MatrixBase& other) const + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived); + return m_matrix + extendedTo(other).nestByValue(); + } + + /** Returns the expression of the difference between each subvector of \c *this and the vector \a other */ + template + CwiseBinaryOp, + ExpressionType, + NestByValue::Type> > + operator-(const MatrixBase& other) const + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived); + return m_matrix - extendedTo(other).nestByValue(); + } + /////////// Geometry module /////////// const Homogeneous homogeneous() const; @@ -330,15 +410,15 @@ template class PartialRedux /** \array_module * - * \returns a PartialRedux wrapper of *this providing additional partial reduction operations + * \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations * * Example: \include MatrixBase_colwise.cpp * Output: \verbinclude MatrixBase_colwise.out * - * \sa rowwise(), class PartialRedux + * \sa rowwise(), class VectorwiseOp */ template -inline const PartialRedux +inline const VectorwiseOp MatrixBase::colwise() const { return derived(); @@ -346,31 +426,57 @@ MatrixBase::colwise() const /** \array_module * - * \returns a PartialRedux wrapper of *this providing additional partial reduction operations + * \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations + * + * \sa rowwise(), class VectorwiseOp + */ +template +inline VectorwiseOp +MatrixBase::colwise() +{ + return derived(); +} + +/** \array_module + * + * \returns a VectorwiseOp wrapper of *this providing additional partial reduction operations * * Example: \include MatrixBase_rowwise.cpp * Output: \verbinclude MatrixBase_rowwise.out * - * \sa colwise(), class PartialRedux + * \sa colwise(), class VectorwiseOp */ template -inline const PartialRedux +inline const VectorwiseOp MatrixBase::rowwise() const { return derived(); } +/** \array_module + * + * \returns a writable VectorwiseOp wrapper of *this providing additional partial reduction operations + * + * \sa colwise(), class VectorwiseOp + */ +template +inline VectorwiseOp +MatrixBase::rowwise() +{ + return derived(); +} + /** \returns a row or column vector expression of \c *this reduxed by \a func * * The template parameter \a BinaryOp is the type of the functor * of the custom redux operator. Note that func must be an associative operator. * - * \sa class PartialRedux, MatrixBase::colwise(), MatrixBase::rowwise() + * \sa class VectorwiseOp, MatrixBase::colwise(), MatrixBase::rowwise() */ template template -const typename PartialRedux::template ReduxReturnType::Type -PartialRedux::redux(const BinaryOp& func) const +const typename VectorwiseOp::template ReduxReturnType::Type +VectorwiseOp::redux(const BinaryOp& func) const { return typename ReduxReturnType::Type(_expression(), func); } diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h index d360646a8..89badb353 100644 --- a/Eigen/src/Core/Functors.h +++ b/Eigen/src/Core/Functors.h @@ -30,7 +30,7 @@ /** \internal * \brief Template functor to compute the sum of two scalars * - * \sa class CwiseBinaryOp, MatrixBase::operator+, class PartialRedux, MatrixBase::sum() + * \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum() */ template struct ei_scalar_sum_op EIGEN_EMPTY_STRUCT { EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; } @@ -52,7 +52,7 @@ struct ei_functor_traits > { /** \internal * \brief Template functor to compute the product of two scalars * - * \sa class CwiseBinaryOp, Cwise::operator*(), class PartialRedux, MatrixBase::redux() + * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux() */ template struct ei_scalar_product_op EIGEN_EMPTY_STRUCT { EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; } @@ -74,7 +74,7 @@ struct ei_functor_traits > { /** \internal * \brief Template functor to compute the min of two scalars * - * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class PartialRedux, MatrixBase::minCoeff() + * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff() */ template struct ei_scalar_min_op EIGEN_EMPTY_STRUCT { EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); } @@ -96,7 +96,7 @@ struct ei_functor_traits > { /** \internal * \brief Template functor to compute the max of two scalars * - * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class PartialRedux, MatrixBase::maxCoeff() + * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff() */ template struct ei_scalar_max_op EIGEN_EMPTY_STRUCT { EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); } @@ -382,7 +382,7 @@ struct ei_scalar_quotient1_op : ei_scalar_quotient1_impl::HasFloatingPoint >(other) {} }; template -struct ei_functor_traits > +struct ei_functor_traits > : ei_functor_traits::HasFloatingPoint> > {}; diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index a24fa77b8..addf59570 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -32,7 +32,7 @@ * * This class is the base that is inherited by all matrix, vector, and expression * types. Most of the Eigen API is contained in this class. Other important classes for - * the Eigen API are Matrix, Cwise, and PartialRedux. + * the Eigen API are Matrix, Cwise, and VectorwiseOp. * * Note that some methods are defined in the \ref Array_Module array module. * @@ -437,10 +437,10 @@ template class MatrixBase template Diagonal diagonal(); template const Diagonal diagonal() const; - + Diagonal diagonal(int index); const Diagonal diagonal(int index) const; - + template Part part(); template const Part part() const; @@ -526,7 +526,7 @@ template class MatrixBase const CwiseUnaryOp::Scalar, NewType>, Derived> >::type cast() const; - + /** \returns the matrix or vector obtained by evaluating this expression. * * Notice that in the case of a plain matrix or vector (not an expression) this function just returns @@ -560,7 +560,7 @@ template class MatrixBase template const CwiseUnaryOp unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const; - + template const CwiseUnaryView unaryViewExpr(const CustomViewOp& func = CustomViewOp()) const; @@ -605,8 +605,10 @@ template class MatrixBase bool any(void) const; int count() const; - const PartialRedux rowwise() const; - const PartialRedux colwise() const; + const VectorwiseOp rowwise() const; + VectorwiseOp rowwise(); + const VectorwiseOp colwise() const; + VectorwiseOp colwise(); static const CwiseNullaryOp,Derived> Random(int rows, int cols); static const CwiseNullaryOp,Derived> Random(int size); @@ -638,7 +640,7 @@ template class MatrixBase /////////// LU module /////////// const LU lu() const; - const PartialLU partialLu() const; + const PartialLU partialLu() const; const PlainMatrixType inverse() const; void computeInverse(PlainMatrixType *result) const; Scalar determinant() const; diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index e60870015..9606771a1 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -105,7 +105,7 @@ void ei_cache_friendly_product( // Array module template class Select; template class PartialReduxExpr; -template class PartialRedux; +template class VectorwiseOp; template class Replicate; template class Reverse; diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h index fde624beb..530725d90 100644 --- a/Eigen/src/Geometry/Homogeneous.h +++ b/Eigen/src/Geometry/Homogeneous.h @@ -147,13 +147,13 @@ MatrixBase::homogeneous() const * \nonstableyet * \returns a matrix expression of homogeneous column (or row) vectors * - * Example: \include PartialRedux_homogeneous.cpp - * Output: \verbinclude PartialRedux_homogeneous.out + * Example: \include VectorwiseOp_homogeneous.cpp + * Output: \verbinclude VectorwiseOp_homogeneous.out * * \sa MatrixBase::homogeneous() */ template inline const Homogeneous -PartialRedux::homogeneous() const +VectorwiseOp::homogeneous() const { return _expression(); } @@ -165,7 +165,7 @@ PartialRedux::homogeneous() const * Example: \include MatrixBase_hnormalized.cpp * Output: \verbinclude MatrixBase_hnormalized.out * - * \sa PartialRedux::hnormalized() */ + * \sa VectorwiseOp::hnormalized() */ template inline const typename MatrixBase::HNormalizedReturnType MatrixBase::hnormalized() const @@ -185,8 +185,8 @@ MatrixBase::hnormalized() const * * \sa MatrixBase::hnormalized() */ template -inline const typename PartialRedux::HNormalizedReturnType -PartialRedux::hnormalized() const +inline const typename VectorwiseOp::HNormalizedReturnType +VectorwiseOp::hnormalized() const { return HNormalized_Block(_expression(),0,0, Direction==Vertical ? _expression().rows()-1 : _expression().rows(), diff --git a/Eigen/src/Geometry/OrthoMethods.h b/Eigen/src/Geometry/OrthoMethods.h index 35fb27bb6..6d4a8f673 100644 --- a/Eigen/src/Geometry/OrthoMethods.h +++ b/Eigen/src/Geometry/OrthoMethods.h @@ -105,8 +105,8 @@ MatrixBase::cross3(const MatrixBase& other) const * \sa MatrixBase::cross() */ template template -const typename PartialRedux::CrossReturnType -PartialRedux::cross(const MatrixBase& other) const +const typename VectorwiseOp::CrossReturnType +VectorwiseOp::cross(const MatrixBase& other) const { EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,3) EIGEN_STATIC_ASSERT((ei_is_same_type::ret), diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h index 78d45a7cb..c186e5ec4 100644 --- a/Eigen/src/Geometry/Transform.h +++ b/Eigen/src/Geometry/Transform.h @@ -205,7 +205,7 @@ public: * If Mode==Affine, then the last row is set to [0 ... 0 1] */ inline Transform() { - if (Mode==Affine) + if (int(Mode)==Affine) makeAffine(); } diff --git a/Eigen/src/Sparse/SparseMatrixBase.h b/Eigen/src/Sparse/SparseMatrixBase.h index c4adf3ac0..8d9406cfb 100644 --- a/Eigen/src/Sparse/SparseMatrixBase.h +++ b/Eigen/src/Sparse/SparseMatrixBase.h @@ -562,8 +562,8 @@ template class SparseMatrixBase bool all(void) const; bool any(void) const; - const PartialRedux rowwise() const; - const PartialRedux colwise() const; + const VectorwiseOp rowwise() const; + const VectorwiseOp colwise() const; static const CwiseNullaryOp,Derived> Random(int rows, int cols); static const CwiseNullaryOp,Derived> Random(int size); diff --git a/doc/snippets/PartialRedux_reverse.cpp b/doc/snippets/Vectorwise_reverse.cpp similarity index 100% rename from doc/snippets/PartialRedux_reverse.cpp rename to doc/snippets/Vectorwise_reverse.cpp diff --git a/test/array.cpp b/test/array.cpp index 053f97327..37deeaa4f 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -33,7 +33,8 @@ template void array(const MatrixType& m) typedef typename MatrixType::Scalar Scalar; typedef typename NumTraits::Real RealScalar; - typedef Matrix VectorType; + typedef Matrix ColVectorType; + typedef Matrix RowVectorType; int rows = m.rows(); int cols = m.cols(); @@ -42,6 +43,9 @@ template void array(const MatrixType& m) m2 = MatrixType::Random(rows, cols), m3(rows, cols); + ColVectorType cv1 = ColVectorType::Random(rows); + RowVectorType rv1 = RowVectorType::Random(cols); + Scalar s1 = ei_random(), s2 = ei_random(); @@ -62,6 +66,16 @@ template void array(const MatrixType& m) if (!ei_isApprox(m1.sum(), (m1+m2).sum())) VERIFY_IS_NOT_APPROX(((m1+m2).rowwise().sum()).sum(), m1.sum()); VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(ei_scalar_sum_op())); + + // vector-wise ops + m3 = m1; + VERIFY_IS_APPROX(m3.colwise() += cv1, m1.colwise() + cv1); + m3 = m1; + VERIFY_IS_APPROX(m3.colwise() -= cv1, m1.colwise() - cv1); + m3 = m1; + VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1); + m3 = m1; + VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1); } template void comparisons(const MatrixType& m) @@ -89,13 +103,13 @@ template void comparisons(const MatrixType& m) VERIFY(! (m1.cwise() < m3).all() ); VERIFY(! (m1.cwise() > m3).all() ); } - + // comparisons to scalar VERIFY( (m1.cwise() != (m1(r,c)+1) ).any() ); VERIFY( (m1.cwise() > (m1(r,c)-1) ).any() ); VERIFY( (m1.cwise() < (m1(r,c)+1) ).any() ); VERIFY( (m1.cwise() == m1(r,c) ).any() ); - + // test Select VERIFY_IS_APPROX( (m1.cwise()m2).select(m1,m2), m1.cwise().max(m2) ); @@ -112,7 +126,7 @@ template void comparisons(const MatrixType& m) .select(m1,0), m3); // even shorter version: VERIFY_IS_APPROX( (m1.cwise().abs().cwise()RealScalar(0.1)).count() == rows*cols); VERIFY_IS_APPROX(((m1.cwise().abs().cwise()+1).cwise()>RealScalar(0.1)).colwise().count(), RowVectorXi::Constant(cols,rows));