diff options
author | Gael Guennebaud <g.gael@free.fr> | 2016-01-21 20:43:42 +0100 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2016-01-21 20:43:42 +0100 |
commit | ee37eb4eed09fe35be2acc3699e80f49a44ea99a (patch) | |
tree | 6ae146eacf54d459cf0e4b20a1180bbb25090cbe /Eigen/src/Core/Dot.h | |
parent | 7cae8918c019feabf6c143c430d0cd82c74aeec3 (diff) |
bug #977: avoid division by 0 in normalize() and normalized().
Diffstat (limited to 'Eigen/src/Core/Dot.h')
-rw-r--r-- | Eigen/src/Core/Dot.h | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h index ce42854cd..221fc3224 100644 --- a/Eigen/src/Core/Dot.h +++ b/Eigen/src/Core/Dot.h @@ -102,7 +102,10 @@ inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real Matr return numext::sqrt(squaredNorm()); } -/** \returns an expression of the quotient of *this by its own norm. +/** \returns an expression of the quotient of \c *this by its own norm. + * + * \warning If the input vector is too small (i.e., this->norm()==0), + * then this function returns a copy of the input. * * \only_for_vectors * @@ -114,19 +117,29 @@ MatrixBase<Derived>::normalized() const { typedef typename internal::nested_eval<Derived,2>::type _Nested; _Nested n(derived()); - return n / n.norm(); + RealScalar z = n.squaredNorm(); + // NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU + if(z>RealScalar(0)) + return n / numext::sqrt(z); + else + return n; } /** Normalizes the vector, i.e. divides it by its own norm. * * \only_for_vectors * + * \warning If the input vector is too small (i.e., this->norm()==0), then \c *this is left unchanged. + * * \sa norm(), normalized() */ template<typename Derived> inline void MatrixBase<Derived>::normalize() { - *this /= norm(); + RealScalar z = squaredNorm(); + // NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU + if(z>RealScalar(0)) + derived() /= numext::sqrt(z); } //---------- implementation of other norms ---------- |