From a172385720fad3b72a820da28fef158efabdb369 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Fri, 6 Jun 2008 18:37:53 +0000 Subject: Updated fuzzy comparisons to use L2 norm as all my experiments tends to show L2 norm works very well here. (the legacy implementation is still available via a preprocessor token to allow further experiments if needed...) --- Eigen/src/Core/Fuzzy.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'Eigen/src/Core/Fuzzy.h') diff --git a/Eigen/src/Core/Fuzzy.h b/Eigen/src/Core/Fuzzy.h index 22e267c8e..e689fc913 100644 --- a/Eigen/src/Core/Fuzzy.h +++ b/Eigen/src/Core/Fuzzy.h @@ -26,6 +26,78 @@ #ifndef EIGEN_FUZZY_H #define EIGEN_FUZZY_H +#ifndef EIGEN_LEGACY_COMPARES + +/** \returns \c true if \c *this is approximately equal to \a other, within the precision + * determined by \a prec. + * + * \note The fuzzy compares are done multiplicatively. Two vectors \f$ v \f$ and \f$ w \f$ + * are considered to be approximately equal within precision \f$ p \f$ if + * \f[ \Vert v - w \Vert \leqslant p\,\min(\Vert v\Vert, \Vert w\Vert). \f] + * For matrices, the comparison is done using the Hilbert-Schmidt norm (aka Frobenius norm + * L2 norm). + * + * \note Because of the multiplicativeness of this comparison, one can't use this function + * to check whether \c *this is approximately equal to the zero matrix or vector. + * Indeed, \c isApprox(zero) returns false unless \c *this itself is exactly the zero matrix + * or vector. If you want to test whether \c *this is zero, use ei_isMuchSmallerThan(const + * RealScalar&, RealScalar) instead. + * + * \sa ei_isMuchSmallerThan(const RealScalar&, RealScalar) const + */ +template +template +bool MatrixBase::isApprox( + const MatrixBase& other, + typename NumTraits::Real prec +) const +{ + const typename ei_nested::type nested(derived()); + const typename ei_nested::type otherNested(other.derived()); + return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * std::min(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum()); +} + +/** \returns \c true if the norm of \c *this is much smaller than \a other, + * within the precision determined by \a prec. + * + * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is + * considered to be much smaller than \f$ x \f$ within precision \f$ p \f$ if + * \f[ \Vert v \Vert \leqslant p\,\vert x\vert. \f] + * For matrices, the comparison is done using the Hilbert-Schmidt norm. + * + * \sa isApprox(), isMuchSmallerThan(const MatrixBase&, RealScalar) const + */ +template +bool MatrixBase::isMuchSmallerThan( + const typename NumTraits::Real& other, + typename NumTraits::Real prec +) const +{ + return cwiseAbs2().sum() <= prec * prec * other * other * cols() * rows(); +} + +/** \returns \c true if the norm of \c *this is much smaller than the norm of \a other, + * within the precision determined by \a prec. + * + * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is + * considered to be much smaller than a vector \f$ w \f$ within precision \f$ p \f$ if + * \f[ \Vert v \Vert \leqslant p\,\Vert w\Vert. \f] + * For matrices, the comparison is done using the Hilbert-Schmidt norm. + * + * \sa isApprox(), isMuchSmallerThan(const RealScalar&, RealScalar) const + */ +template +template +bool MatrixBase::isMuchSmallerThan( + const MatrixBase& other, + typename NumTraits::Real prec +) const +{ + return this->cwiseAbs2().sum() <= prec * prec * other.cwiseAbs2().sum(); +} + +#else + template struct ei_fuzzy_selector; @@ -154,4 +226,6 @@ struct ei_fuzzy_selector } }; +#endif + #endif // EIGEN_FUZZY_H -- cgit v1.2.3