fuzzy.hpp
Go to the documentation of this file.
1 
11 /*****************************************************************************
12 ** Ifdefs
13 *****************************************************************************/
14 
15 #ifndef ECL_MATH_FUZZY_HPP_
16 #define ECL_MATH_FUZZY_HPP_
17 
18 /*****************************************************************************
19 ** Includes
20 *****************************************************************************/
21 
22 //#include "num_traits.hpp"
23 #include <cmath> // floating point std::abs
24 #include <cstdlib> // integral std::abs
25 #include <algorithm> // std::min, std::max
26 #include <ecl/type_traits/numeric_limits.hpp>
27 
28 /*****************************************************************************
29 ** Namespaces
30 *****************************************************************************/
31 
32 namespace ecl {
36 namespace implementations {
37 
38 /****************************************************************************
39 * Implementation of fuzzy comparisons *
40 ****************************************************************************/
41 
47 template<typename Scalar,
48  bool IsInteger>
49 struct scalar_fuzzy_default_impl {};
50 
56 template<typename Scalar>
57 struct scalar_fuzzy_default_impl<Scalar, false>
58 {
59  typedef typename ecl::numeric_limits<Scalar>::Precision Precision;
60 
61  template<typename OtherScalar>
62  static inline bool isApprox(const Scalar& x, const OtherScalar& y, const Precision& prec) {
63  // casting just in case y is an integer type.
64  return std::abs(x - static_cast<Scalar>(y)) <= std::min( std::abs(x), std::abs(static_cast<Scalar>(y))) * prec;
65  }
66 
67  template<typename OtherScalar>
68  static inline bool isApproxOrLessThan(const Scalar& x, const OtherScalar& y, const Precision& prec) {
69  return x <= y || isApprox(x, y, prec);
70  }
71 };
72 
78 template<typename Scalar>
79 struct scalar_fuzzy_default_impl<Scalar, true> {
80 
81  typedef typename ecl::numeric_limits<Scalar>::Precision Precision;
82 
83  template<typename OtherScalar>
84  static inline bool isApprox(const Scalar& x, const OtherScalar& y, const Precision& prec) {
85  // this will trigger if default argument is used (dummy precision for integers == 0)
87  return x == y;
88  } else {
89  // only get here if its not complex, so OtherScalar has to be a floating type
91  if ( prec == 0.0 ) {
93  } else {
94  precision = static_cast<OtherScalar>(prec);
95  }
96  return std::abs(static_cast<OtherScalar>(x) - y) <= std::min( std::abs(static_cast<OtherScalar>(x)), std::abs(y)) * precision;
97  }
98  }
99  template<typename OtherScalar>
100  static inline bool isApproxOrLessThan(const Scalar& x, const OtherScalar& y, const Precision&) {
101  return x <= y;
102  }
103 };
104 
106 // * @brief Fuzzy math implementation for complex numbers.
107 // *
108 // * Specialisation of fuzzy math functions for complex numbers.
109 // *
110 // * @tparam Scalar : autoselected by numeric traits as always being complex.
111 // */
112 //template<typename Scalar>
113 //struct scalar_fuzzy_default_impl<Scalar, true, false> {
114 // typedef typename ecl::NumTraits<Scalar>::Precision Precision;
115 //
116 // static inline bool isApprox(const Scalar& x, const Scalar& y, const Precision& prec) {
117 // return ei_abs2(x - y) <= std::min(ei_abs2(x), ei_abs2(y)) * prec * prec;
118 // }
119 //};
120 
128 template<typename Scalar>
129 struct scalar_fuzzy_impl : implementations::scalar_fuzzy_default_impl<Scalar, numeric_limits<Scalar>::is_integer> {};
130 
131 } // implementations
132 
136 /*****************************************************************************
137 ** Direct Interfaces
138 *****************************************************************************/
139 
153 template<typename Scalar, typename OtherScalar>
154 inline bool isApprox(const Scalar& x, const OtherScalar& y, typename numeric_limits<Scalar>::Precision precision = numeric_limits<Scalar>::dummy_precision) {
155  return implementations::scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
156 }
157 
171 template<typename Scalar, typename OtherScalar>
172 inline bool isApproxOrLessThan(const Scalar& x, const OtherScalar& y, typename numeric_limits<Scalar>::Precision precision = numeric_limits<Scalar>::dummy_precision) {
173  return implementations::scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
174 }
175 
176 
177 
178 } // namespace ecl
179 
180 #endif /* ECL_MATH_FUZZY_HPP_ */
bool isApproxOrLessThan(const Scalar &x, const OtherScalar &y, typename numeric_limits< Scalar >::Precision precision=numeric_limits< Scalar >::dummy_precision)
Checks if the first value is less than or approximate to the second.
Definition: fuzzy.hpp:172
Expands the std numeric_limits class.
bool isApprox(const Scalar &x, const OtherScalar &y, typename numeric_limits< Scalar >::Precision precision=numeric_limits< Scalar >::dummy_precision)
Checks if two values are approximate.
Definition: fuzzy.hpp:154


xbot_driver
Author(s): Roc, wangpeng@droid.ac.cn
autogenerated on Sat Oct 10 2020 03:27:37