Fuzzy.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
00005 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
00006 //
00007 // Eigen is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 3 of the License, or (at your option) any later version.
00011 //
00012 // Alternatively, you can redistribute it and/or
00013 // modify it under the terms of the GNU General Public License as
00014 // published by the Free Software Foundation; either version 2 of
00015 // the License, or (at your option) any later version.
00016 //
00017 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00018 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00019 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00020 // GNU General Public License for more details.
00021 //
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License and a copy of the GNU General Public License along with
00024 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00025 
00026 #ifndef EIGEN_FUZZY_H
00027 #define EIGEN_FUZZY_H
00028 
00029 namespace Eigen { 
00030 
00031 namespace internal
00032 {
00033 
00034 template<typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
00035 struct isApprox_selector
00036 {
00037   static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec)
00038   {
00039     using std::min;
00040     typename internal::nested<Derived,2>::type nested(x);
00041     typename internal::nested<OtherDerived,2>::type otherNested(y);
00042     return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * (min)(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum());
00043   }
00044 };
00045 
00046 template<typename Derived, typename OtherDerived>
00047 struct isApprox_selector<Derived, OtherDerived, true>
00048 {
00049   static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar)
00050   {
00051     return x.matrix() == y.matrix();
00052   }
00053 };
00054 
00055 template<typename Derived, typename OtherDerived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
00056 struct isMuchSmallerThan_object_selector
00057 {
00058   static bool run(const Derived& x, const OtherDerived& y, typename Derived::RealScalar prec)
00059   {
00060     return x.cwiseAbs2().sum() <= abs2(prec) * y.cwiseAbs2().sum();
00061   }
00062 };
00063 
00064 template<typename Derived, typename OtherDerived>
00065 struct isMuchSmallerThan_object_selector<Derived, OtherDerived, true>
00066 {
00067   static bool run(const Derived& x, const OtherDerived&, typename Derived::RealScalar)
00068   {
00069     return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix();
00070   }
00071 };
00072 
00073 template<typename Derived, bool is_integer = NumTraits<typename Derived::Scalar>::IsInteger>
00074 struct isMuchSmallerThan_scalar_selector
00075 {
00076   static bool run(const Derived& x, const typename Derived::RealScalar& y, typename Derived::RealScalar prec)
00077   {
00078     return x.cwiseAbs2().sum() <= abs2(prec * y);
00079   }
00080 };
00081 
00082 template<typename Derived>
00083 struct isMuchSmallerThan_scalar_selector<Derived, true>
00084 {
00085   static bool run(const Derived& x, const typename Derived::RealScalar&, typename Derived::RealScalar)
00086   {
00087     return x.matrix() == Derived::Zero(x.rows(), x.cols()).matrix();
00088   }
00089 };
00090 
00091 } // end namespace internal
00092 
00093 
00111 template<typename Derived>
00112 template<typename OtherDerived>
00113 bool DenseBase<Derived>::isApprox(
00114   const DenseBase<OtherDerived>& other,
00115   RealScalar prec
00116 ) const
00117 {
00118   return internal::isApprox_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec);
00119 }
00120 
00134 template<typename Derived>
00135 bool DenseBase<Derived>::isMuchSmallerThan(
00136   const typename NumTraits<Scalar>::Real& other,
00137   RealScalar prec
00138 ) const
00139 {
00140   return internal::isMuchSmallerThan_scalar_selector<Derived>::run(derived(), other, prec);
00141 }
00142 
00153 template<typename Derived>
00154 template<typename OtherDerived>
00155 bool DenseBase<Derived>::isMuchSmallerThan(
00156   const DenseBase<OtherDerived>& other,
00157   RealScalar prec
00158 ) const
00159 {
00160   return internal::isMuchSmallerThan_object_selector<Derived, OtherDerived>::run(derived(), other.derived(), prec);
00161 }
00162 
00163 } // end namespace Eigen
00164 
00165 #endif // EIGEN_FUZZY_H