diff options
author | Gael Guennebaud <g.gael@free.fr> | 2016-06-02 15:29:59 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2016-06-02 15:29:59 +0200 |
commit | 8b6f53222b84d1e4f0f1e86b1d321777b58a28dc (patch) | |
tree | 50933630ccc644d70f20dadc0cc2c1525d057e0a | |
parent | d616a81294175d1266c8a6af198243a6befc8cc6 (diff) |
bug #1193: fix lpNorm<Infinity> for empty input.
-rw-r--r-- | Eigen/src/Core/Dot.h | 7 | ||||
-rw-r--r-- | Eigen/src/Core/Redux.h | 4 | ||||
-rw-r--r-- | test/array_for_matrix.cpp | 16 |
3 files changed, 24 insertions, 3 deletions
diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h index 82d58fc0b..f3c869635 100644 --- a/Eigen/src/Core/Dot.h +++ b/Eigen/src/Core/Dot.h @@ -227,9 +227,12 @@ struct lpNorm_selector<Derived, 2> template<typename Derived> struct lpNorm_selector<Derived, Infinity> { + typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar; EIGEN_DEVICE_FUNC - static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m) + static inline RealScalar run(const MatrixBase<Derived>& m) { + if(Derived::SizeAtCompileTime==0 || (Derived::SizeAtCompileTime==Dynamic && m.size()==0)) + return RealScalar(0); return m.cwiseAbs().maxCoeff(); } }; @@ -240,6 +243,8 @@ struct lpNorm_selector<Derived, Infinity> * of the coefficients of \c *this. If \a p is the special value \a Eigen::Infinity, this function returns the \f$ \ell^\infty \f$ * norm, that is the maximum of the absolute values of the coefficients of \c *this. * + * In all cases, if \c *this is empty, then the value 0 is returned. + * * \note For matrices, this function does not compute the <a href="https://en.wikipedia.org/wiki/Operator_norm">operator-norm</a>. That is, if \c *this is a matrix, then its coefficients are interpreted as a 1D vector. Nonetheless, you can easily compute the 1-norm and \f$\infty\f$-norm matrix operator norms using \link TutorialReductionsVisitorsBroadcastingReductionsNorm partial reductions \endlink. * * \sa norm() diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h index 3a47edf79..7984cd6e1 100644 --- a/Eigen/src/Core/Redux.h +++ b/Eigen/src/Core/Redux.h @@ -438,7 +438,9 @@ DenseBase<Derived>::maxCoeff() const return derived().redux(Eigen::internal::scalar_max_op<Scalar>()); } -/** \returns the sum of all coefficients of *this +/** \returns the sum of all coefficients of \c *this + * + * If \c *this is empty, then the value 0 is returned. * * \sa trace(), prod(), mean() */ diff --git a/test/array_for_matrix.cpp b/test/array_for_matrix.cpp index db5f3b34a..75e6a778f 100644 --- a/test/array_for_matrix.cpp +++ b/test/array_for_matrix.cpp @@ -144,9 +144,21 @@ template<typename MatrixType> void comparisons(const MatrixType& m) template<typename VectorType> void lpNorm(const VectorType& v) { using std::sqrt; + typedef typename VectorType::RealScalar RealScalar; VectorType u = VectorType::Random(v.size()); - VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), u.cwiseAbs().maxCoeff()); + if(v.size()==0) + { + VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), RealScalar(0)); + VERIFY_IS_APPROX(u.template lpNorm<1>(), RealScalar(0)); + VERIFY_IS_APPROX(u.template lpNorm<2>(), RealScalar(0)); + VERIFY_IS_APPROX(u.template lpNorm<5>(), RealScalar(0)); + } + else + { + VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), u.cwiseAbs().maxCoeff()); + } + VERIFY_IS_APPROX(u.template lpNorm<1>(), u.cwiseAbs().sum()); VERIFY_IS_APPROX(u.template lpNorm<2>(), sqrt(u.array().abs().square().sum())); VERIFY_IS_APPROX(numext::pow(u.template lpNorm<5>(), typename VectorType::RealScalar(5)), u.array().abs().pow(5).sum()); @@ -255,6 +267,8 @@ void test_array_for_matrix() CALL_SUBTEST_5( lpNorm(VectorXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) ); CALL_SUBTEST_4( lpNorm(VectorXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) ); } + CALL_SUBTEST_5( lpNorm(VectorXf(0)) ); + CALL_SUBTEST_4( lpNorm(VectorXcf(0)) ); for(int i = 0; i < g_repeat; i++) { CALL_SUBTEST_4( resize(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) ); CALL_SUBTEST_5( resize(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) ); |