# Eigen functions of the day: normalize() and stableNormalize().

In computer vision, I find myself needing unit vectors, a lot. In other words, doing the following in C++,

Vector3d v;

// v's unnormalized value is computed.

v /= v.norm();


I also need image homogenous coordinates ‘normalized’, in other words, dividing the vector by the third element (scale):

Vector3d v;

// v's unnormalized value is computed. Something like v = P*X;

v /= v(2);


I looked up the Eigen function normalize(), docs, and normalize() will return a unit vector - the first case I mention. Here’s the Eigen code:

// from Dot.h
template<typename Derived>
inline void MatrixBase<Derived>::normalize()
{
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);
}


So one could write

Vector3d v;

// v's unnormalized value is computed.

v.normalize();


oohhh but then by poking around in the .h files (which I really recommend), I came across stableNormalize(), docs, which computes the unit vector (of a non-zero vector) whole reducing under- and over-flow risks:

/** 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;
}


and the function can be used like this:

Vector3d v;

// v's unnormalized value is computed.

v.stableNormalize();


© Amy Tabb 2018 - 2022. All rights reserved. The contents of this site reflect my personal perspectives and not those of any other entity.