Fix hypot() and hypotNorm() wrt NaN and INF values.

This commit is contained in:
Gael Guennebaud 2014-09-02 16:09:39 +02:00
parent a44a343f03
commit 42e27d41a2
3 changed files with 26 additions and 11 deletions

View File

@ -308,10 +308,17 @@ struct hypot_impl
using std::sqrt; using std::sqrt;
RealScalar _x = abs(x); RealScalar _x = abs(x);
RealScalar _y = abs(y); RealScalar _y = abs(y);
RealScalar p = (max)(_x, _y); Scalar p, qp;
if(p==RealScalar(0)) return 0; if(_x>_y)
RealScalar q = (min)(_x, _y); {
RealScalar qp = q/p; p = _x;
qp = _y / p;
}
else
{
p = _y;
qp = _x / p;
}
return p * sqrt(RealScalar(1) + qp*qp); return p * sqrt(RealScalar(1) + qp*qp);
} }
}; };

View File

@ -167,9 +167,17 @@ template<typename Scalar> struct scalar_hypot_op {
EIGEN_USING_STD_MATH(max); EIGEN_USING_STD_MATH(max);
EIGEN_USING_STD_MATH(min); EIGEN_USING_STD_MATH(min);
using std::sqrt; using std::sqrt;
Scalar p = (max)(_x, _y); Scalar p, qp;
Scalar q = (min)(_x, _y); if(_x>_y)
Scalar qp = q/p; {
p = _x;
qp = _y / p;
}
else
{
p = _y;
qp = _x / p;
}
return p * sqrt(Scalar(1) + qp*qp); return p * sqrt(Scalar(1) + qp*qp);
} }
}; };

View File

@ -135,7 +135,7 @@ template<typename MatrixType> void stable_norm(const MatrixType& m)
VERIFY(!isFinite(v.norm())); VERIFY(isNaN(v.norm())); VERIFY(!isFinite(v.norm())); VERIFY(isNaN(v.norm()));
VERIFY(!isFinite(v.stableNorm())); VERIFY(isNaN(v.stableNorm())); VERIFY(!isFinite(v.stableNorm())); VERIFY(isNaN(v.stableNorm()));
VERIFY(!isFinite(v.blueNorm())); VERIFY(isNaN(v.blueNorm())); VERIFY(!isFinite(v.blueNorm())); VERIFY(isNaN(v.blueNorm()));
// VERIFY(!isFinite(v.hypotNorm())); //VERIFY(isNaN(v.hypotNorm())); VERIFY(!isFinite(v.hypotNorm())); VERIFY(isNaN(v.hypotNorm()));
} }
// +inf // +inf
@ -146,7 +146,7 @@ template<typename MatrixType> void stable_norm(const MatrixType& m)
VERIFY(!isFinite(v.norm())); VERIFY(isInf(v.norm())); VERIFY(!isFinite(v.norm())); VERIFY(isInf(v.norm()));
VERIFY(!isFinite(v.stableNorm())); VERIFY(isInf(v.stableNorm())); VERIFY(!isFinite(v.stableNorm())); VERIFY(isInf(v.stableNorm()));
VERIFY(!isFinite(v.blueNorm())); VERIFY(isInf(v.blueNorm())); VERIFY(!isFinite(v.blueNorm())); VERIFY(isInf(v.blueNorm()));
// VERIFY(!isFinite(v.hypotNorm())); //VERIFY(isInf(v.hypotNorm())); VERIFY(!isFinite(v.hypotNorm())); VERIFY(isInf(v.hypotNorm()));
} }
// -inf // -inf
@ -157,7 +157,7 @@ template<typename MatrixType> void stable_norm(const MatrixType& m)
VERIFY(!isFinite(v.norm())); VERIFY(isInf(v.norm())); VERIFY(!isFinite(v.norm())); VERIFY(isInf(v.norm()));
VERIFY(!isFinite(v.stableNorm())); VERIFY(isInf(v.stableNorm())); VERIFY(!isFinite(v.stableNorm())); VERIFY(isInf(v.stableNorm()));
VERIFY(!isFinite(v.blueNorm())); VERIFY(isInf(v.blueNorm())); VERIFY(!isFinite(v.blueNorm())); VERIFY(isInf(v.blueNorm()));
// VERIFY(!isFinite(v.hypotNorm())); VERIFY(isInf(v.hypotNorm())); VERIFY(!isFinite(v.hypotNorm())); VERIFY(isInf(v.hypotNorm()));
} }
// mix // mix
@ -171,7 +171,7 @@ template<typename MatrixType> void stable_norm(const MatrixType& m)
VERIFY(!isFinite(v.norm())); VERIFY(isNaN(v.norm())); VERIFY(!isFinite(v.norm())); VERIFY(isNaN(v.norm()));
VERIFY(!isFinite(v.stableNorm())); VERIFY(isNaN(v.stableNorm())); VERIFY(!isFinite(v.stableNorm())); VERIFY(isNaN(v.stableNorm()));
VERIFY(!isFinite(v.blueNorm())); VERIFY(isNaN(v.blueNorm())); VERIFY(!isFinite(v.blueNorm())); VERIFY(isNaN(v.blueNorm()));
// VERIFY(!isFinite(v.hypotNorm())); VERIFY(isNaN(v.hypotNorm())); VERIFY(!isFinite(v.hypotNorm())); VERIFY(isNaN(v.hypotNorm()));
} }
} }