From 8c1ee3629f845572caaba28c746bab0ef6a0084a Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 28 Sep 2015 11:36:00 +0200 Subject: [PATCH] Add support for row/col-wise lpNorm() --- Eigen/src/Core/VectorwiseOp.h | 27 +++++++++++++++++++++++++++ test/vectorwiseop.cpp | 5 +++++ 2 files changed, 32 insertions(+) diff --git a/Eigen/src/Core/VectorwiseOp.h b/Eigen/src/Core/VectorwiseOp.h index 37171aaa0..79c7d135d 100644 --- a/Eigen/src/Core/VectorwiseOp.h +++ b/Eigen/src/Core/VectorwiseOp.h @@ -124,6 +124,16 @@ EIGEN_MEMBER_FUNCTOR(any, (Size-1)*NumTraits::AddCost); EIGEN_MEMBER_FUNCTOR(count, (Size-1)*NumTraits::AddCost); EIGEN_MEMBER_FUNCTOR(prod, (Size-1)*NumTraits::MulCost); +template +struct member_lpnorm { + typedef ResultType result_type; + template struct Cost + { enum { value = (Size+5) * NumTraits::MulCost + (Size-1)*NumTraits::AddCost }; }; + EIGEN_DEVICE_FUNC explicit member_lpnorm() {} + template + EIGEN_DEVICE_FUNC inline ResultType operator()(const XprType& mat) const + { return mat.template lpNorm

(); } +}; template struct member_redux { @@ -290,6 +300,10 @@ template class VectorwiseOp typedef typename ReturnType::Type ProdReturnType; typedef Reverse ReverseReturnType; + template struct LpNormReturnType { + typedef PartialReduxExpr,Direction> Type; + }; + /** \returns a row (or column) vector expression of the smallest coefficient * of each column (or row) of the referenced expression. * @@ -340,6 +354,19 @@ template class VectorwiseOp const NormReturnType norm() const { return NormReturnType(_expression()); } + /** \returns a row (or column) vector expression of the norm + * of each column (or row) of the referenced expression. + * This is a vector with real entries, even if the original matrix has complex entries. + * + * Example: \include PartialRedux_norm.cpp + * Output: \verbinclude PartialRedux_norm.out + * + * \sa DenseBase::norm() */ + EIGEN_DEVICE_FUNC + template + const typename LpNormReturnType

::Type lpNorm() const + { return typename LpNormReturnType

::Type(_expression()); } + /** \returns a row (or column) vector expression of the norm * of each column (or row) of the referenced expression, using diff --git a/test/vectorwiseop.cpp b/test/vectorwiseop.cpp index 03f50bb5a..7ec57736c 100644 --- a/test/vectorwiseop.cpp +++ b/test/vectorwiseop.cpp @@ -191,6 +191,11 @@ template void vectorwiseop_matrix(const MatrixType& m) rcres = m1.rowwise().norm(); VERIFY_IS_APPROX(rcres(r), m1.row(r).norm()); + VERIFY_IS_APPROX(m1.cwiseAbs().colwise().sum(), m1.colwise().template lpNorm<1>()); + VERIFY_IS_APPROX(m1.cwiseAbs().rowwise().sum(), m1.rowwise().template lpNorm<1>()); + VERIFY_IS_APPROX(m1.cwiseAbs().colwise().maxCoeff(), m1.colwise().template lpNorm()); + VERIFY_IS_APPROX(m1.cwiseAbs().rowwise().maxCoeff(), m1.rowwise().template lpNorm()); + // test normalized m2 = m1.colwise().normalized(); VERIFY_IS_APPROX(m2.col(c), m1.col(c).normalized());