diff options
author | Gael Guennebaud <g.gael@free.fr> | 2015-09-28 11:36:00 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2015-09-28 11:36:00 +0200 |
commit | 8c1ee3629f845572caaba28c746bab0ef6a0084a (patch) | |
tree | 81e1680cd0c186c18671925684098131373978de | |
parent | 75861f6650a175dbefb06003ac59c60cca4704e3 (diff) |
Add support for row/col-wise lpNorm()
-rw-r--r-- | Eigen/src/Core/VectorwiseOp.h | 27 | ||||
-rw-r--r-- | test/vectorwiseop.cpp | 5 |
2 files changed, 32 insertions, 0 deletions
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<Scalar>::AddCost); EIGEN_MEMBER_FUNCTOR(count, (Size-1)*NumTraits<Scalar>::AddCost); EIGEN_MEMBER_FUNCTOR(prod, (Size-1)*NumTraits<Scalar>::MulCost); +template <int p, typename ResultType> +struct member_lpnorm { + typedef ResultType result_type; + template<typename Scalar, int Size> struct Cost + { enum { value = (Size+5) * NumTraits<Scalar>::MulCost + (Size-1)*NumTraits<Scalar>::AddCost }; }; + EIGEN_DEVICE_FUNC explicit member_lpnorm() {} + template<typename XprType> + EIGEN_DEVICE_FUNC inline ResultType operator()(const XprType& mat) const + { return mat.template lpNorm<p>(); } +}; template <typename BinaryOp, typename Scalar> struct member_redux { @@ -290,6 +300,10 @@ template<typename ExpressionType, int Direction> class VectorwiseOp typedef typename ReturnType<internal::member_prod>::Type ProdReturnType; typedef Reverse<ExpressionType, Direction> ReverseReturnType; + template<int p> struct LpNormReturnType { + typedef PartialReduxExpr<ExpressionType, internal::member_lpnorm<p,RealScalar>,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<typename ExpressionType, int Direction> 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<int p> + const typename LpNormReturnType<p>::Type lpNorm() const + { return typename LpNormReturnType<p>::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<typename MatrixType> 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<Infinity>()); + VERIFY_IS_APPROX(m1.cwiseAbs().rowwise().maxCoeff(), m1.rowwise().template lpNorm<Infinity>()); + // test normalized m2 = m1.colwise().normalized(); VERIFY_IS_APPROX(m2.col(c), m1.col(c).normalized()); |