PageRenderTime 23ms CodeModel.GetById 18ms app.highlight 4ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Geometry_Eigen/Eigen/src/Core/Fuzzy.h

http://github.com/Akranar/daguerreo
C Header | 161 lines | 83 code | 14 blank | 64 comment | 3 complexity | 26f7a314741ac28ac604a3a5c28040c3 MD5 | raw file
Possible License(s): AGPL-3.0, LGPL-2.1, LGPL-3.0, GPL-2.0
  1// This file is part of Eigen, a lightweight C++ template library
  2// for linear algebra.
  3//
  4// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
  5// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
  6//
  7// Eigen is free software; you can redistribute it and/or
  8// modify it under the terms of the GNU Lesser General Public
  9// License as published by the Free Software Foundation; either
 10// version 3 of the License, or (at your option) any later version.
 11//
 12// Alternatively, you can redistribute it and/or
 13// modify it under the terms of the GNU General Public License as
 14// published by the Free Software Foundation; either version 2 of
 15// the License, or (at your option) any later version.
 16//
 17// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
 18// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 19// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
 20// GNU General Public License for more details.
 21//
 22// You should have received a copy of the GNU Lesser General Public
 23// License and a copy of the GNU General Public License along with
 24// Eigen. If not, see <http://www.gnu.org/licenses/>.
 25
 26#ifndef EIGEN_FUZZY_H
 27#define EIGEN_FUZZY_H
 28
 29namespace internal
 30{
 31
 32template<typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
 33struct isApprox_selector
 34{
 35  static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec)
 36  {
 37    using std::min;
 38    const typename internal::nested<Derived,2>::type nested(x);
 39    const typename internal::nested<OtherDerived,2>::type otherNested(y);
 40    return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * (min)(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum());
 41  }
 42};
 43
 44template<typename Derived, typename OtherDerived>
 45struct isApprox_selector<Derived, OtherDerived, true>
 46{
 47  static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar)
 48  {
 49    return x.matrix() == y.matrix();
 50  }
 51};
 52
 53template<typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
 54struct isMuchSmallerThan_object_selector
 55{
 56  static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec)
 57  {
 58    return x.cwiseAbs2().sum() <= abs2(prec) * y.cwiseAbs2().sum();
 59  }
 60};
 61
 62template<typename Derived, typename OtherDerived>
 63struct isMuchSmallerThan_object_selector<Derived, OtherDerived, true>
 64{
 65  static bool run(const Derived& x, const OtherDerived&, typename Derived::RealScalar)
 66  {
 67    return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix();
 68  }
 69};
 70
 71template<typename Derived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
 72struct isMuchSmallerThan_scalar_selector
 73{
 74  static bool run(const Derived& x, const typename Derived::RealScalar& y, typename Derived::RealScalar prec)
 75  {
 76    return x.cwiseAbs2().sum() <= abs2(prec * y);
 77  }
 78};
 79
 80template<typename Derived>
 81struct isMuchSmallerThan_scalar_selector<Derived, true>
 82{
 83  static bool run(const Derived& x, const typename Derived::RealScalar&, typename Derived::RealScalar)
 84  {
 85    return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix();
 86  }
 87};
 88
 89} // end namespace internal
 90
 91
 92/** \returns \c true if \c *this is approximately equal to \a other, within the precision
 93  * determined by \a prec.
 94  *
 95  * \note The fuzzy compares are done multiplicatively. Two vectors \f$ v \f$ and \f$ w \f$
 96  * are considered to be approximately equal within precision \f$ p \f$ if
 97  * \f[ \Vert v - w \Vert \leqslant p\,\(min)(\Vert v\Vert, \Vert w\Vert). \f]
 98  * For matrices, the comparison is done using the Hilbert-Schmidt norm (aka Frobenius norm
 99  * L2 norm).
100  *
101  * \note Because of the multiplicativeness of this comparison, one can't use this function
102  * to check whether \c *this is approximately equal to the zero matrix or vector.
103  * Indeed, \c isApprox(zero) returns false unless \c *this itself is exactly the zero matrix
104  * or vector. If you want to test whether \c *this is zero, use internal::isMuchSmallerThan(const
105  * RealScalar&, RealScalar) instead.
106  *
107  * \sa internal::isMuchSmallerThan(const RealScalar&, RealScalar) const
108  */
109template<typename Derived>
110template<typename OtherDerived>
111bool DenseBase<Derived>::isApprox(
112  const DenseBase<OtherDerived>& other,
113  RealScalar prec
114) const
115{
116  return internal::isApprox_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec);
117}
118
119/** \returns \c true if the norm of \c *this is much smaller than \a other,
120  * within the precision determined by \a prec.
121  *
122  * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is
123  * considered to be much smaller than \f$ x \f$ within precision \f$ p \f$ if
124  * \f[ \Vert v \Vert \leqslant p\,\vert x\vert. \f]
125  *
126  * For matrices, the comparison is done using the Hilbert-Schmidt norm. For this reason,
127  * the value of the reference scalar \a other should come from the Hilbert-Schmidt norm
128  * of a reference matrix of same dimensions.
129  *
130  * \sa isApprox(), isMuchSmallerThan(const DenseBase<OtherDerived>&, RealScalar) const
131  */
132template<typename Derived>
133bool DenseBase<Derived>::isMuchSmallerThan(
134  const typename NumTraits<Scalar>::Real& other,
135  RealScalar prec
136) const
137{
138  return internal::isMuchSmallerThan_scalar_selector<Derived>::run(derived(), other, prec);
139}
140
141/** \returns \c true if the norm of \c *this is much smaller than the norm of \a other,
142  * within the precision determined by \a prec.
143  *
144  * \note The fuzzy compares are done multiplicatively. A vector \f$ v \f$ is
145  * considered to be much smaller than a vector \f$ w \f$ within precision \f$ p \f$ if
146  * \f[ \Vert v \Vert \leqslant p\,\Vert w\Vert. \f]
147  * For matrices, the comparison is done using the Hilbert-Schmidt norm.
148  *
149  * \sa isApprox(), isMuchSmallerThan(const RealScalar&, RealScalar) const
150  */
151template<typename Derived>
152template<typename OtherDerived>
153bool DenseBase<Derived>::isMuchSmallerThan(
154  const DenseBase<OtherDerived>& other,
155  RealScalar prec
156) const
157{
158  return internal::isMuchSmallerThan_object_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec);
159}
160
161#endif // EIGEN_FUZZY_H