aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/Dot.h
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2016-01-23 22:40:11 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2016-01-23 22:40:11 +0100
commit1cf85bd875ecbcfa1240b4ec08122d40d79101fd (patch)
tree64dacc9ef8e8f8fd6d4de1a707fff0c3d73c917f /Eigen/src/Core/Dot.h
parent369d6d1ae31c3e1a0f03196ccb9c792c6913ed76 (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.h46
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 {