diff options
author | Gael Guennebaud <g.gael@free.fr> | 2016-01-23 22:40:11 +0100 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2016-01-23 22:40:11 +0100 |
commit | 1cf85bd875ecbcfa1240b4ec08122d40d79101fd (patch) | |
tree | 64dacc9ef8e8f8fd6d4de1a707fff0c3d73c917f /Eigen/src/Core/Dot.h | |
parent | 369d6d1ae31c3e1a0f03196ccb9c792c6913ed76 (diff) |
bug #977: add stableNormalize[d] methods: they are analogues to normalize[d] but with carefull handling of under/over-flow
Diffstat (limited to 'Eigen/src/Core/Dot.h')
-rw-r--r-- | Eigen/src/Core/Dot.h | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h index 221fc3224..82d58fc0b 100644 --- a/Eigen/src/Core/Dot.h +++ b/Eigen/src/Core/Dot.h @@ -142,6 +142,52 @@ inline void MatrixBase<Derived>::normalize() derived() /= numext::sqrt(z); } +/** \returns an expression of the quotient of \c *this by its own norm while avoiding underflow and overflow. + * + * \only_for_vectors + * + * This method is analogue to the normalized() method, but it reduces the risk of + * underflow and overflow when computing the norm. + * + * \warning If the input vector is too small (i.e., this->norm()==0), + * then this function returns a copy of the input. + * + * \sa stableNorm(), stableNormalize(), normalized() + */ +template<typename Derived> +inline const typename MatrixBase<Derived>::PlainObject +MatrixBase<Derived>::stableNormalized() const +{ + typedef typename internal::nested_eval<Derived,3>::type _Nested; + _Nested n(derived()); + RealScalar w = n.cwiseAbs().maxCoeff(); + RealScalar z = (n/w).squaredNorm(); + if(z>RealScalar(0)) + return n / (numext::sqrt(z)*w); + else + return n; +} + +/** Normalizes the vector while avoid underflow and overflow + * + * \only_for_vectors + * + * This method is analogue to the normalize() method, but it reduces the risk of + * underflow and overflow when computing the norm. + * + * \warning If the input vector is too small (i.e., this->norm()==0), then \c *this is left unchanged. + * + * \sa stableNorm(), stableNormalized(), normalize() + */ +template<typename Derived> +inline void MatrixBase<Derived>::stableNormalize() +{ + RealScalar w = cwiseAbs().maxCoeff(); + RealScalar z = (derived()/w).squaredNorm(); + if(z>RealScalar(0)) + derived() /= numext::sqrt(z)*w; +} + //---------- implementation of other norms ---------- namespace internal { |