.. _program_listing_file__tmp_ws_src_ecl_core_ecl_math_include_ecl_math_fuzzy.hpp: Program Listing for File fuzzy.hpp ================================== |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/ecl_core/ecl_math/include/ecl/math/fuzzy.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /***************************************************************************** ** Ifdefs *****************************************************************************/ #ifndef ECL_MATH_FUZZY_HPP_ #define ECL_MATH_FUZZY_HPP_ /***************************************************************************** ** Includes *****************************************************************************/ //#include "num_traits.hpp" #include // floating point std::abs #include // integral std::abs #include // std::min, std::max #include /***************************************************************************** ** Namespaces *****************************************************************************/ namespace ecl { namespace implementations { /**************************************************************************** * Implementation of fuzzy comparisons * ****************************************************************************/ template struct scalar_fuzzy_default_impl {}; template struct scalar_fuzzy_default_impl { typedef typename ecl::numeric_limits::Precision Precision; template static inline bool isApprox(const Scalar& x, const OtherScalar& y, const Precision& prec) { // casting just in case y is an integer type. return std::abs(x - static_cast(y)) <= std::min( std::abs(x), std::abs(static_cast(y))) * prec; } template static inline bool isApproxOrLessThan(const Scalar& x, const OtherScalar& y, const Precision& prec) { return x <= y || isApprox(x, y, prec); } }; template struct scalar_fuzzy_default_impl { typedef typename ecl::numeric_limits::Precision Precision; template static inline bool isApprox(const Scalar& x, const OtherScalar& y, const Precision& prec) { // this will trigger if default argument is used (dummy precision for integers == 0) if ( ecl::numeric_limits::is_integer ) { return x == y; } else { // only get here if its not complex, so OtherScalar has to be a floating type typename ecl::numeric_limits::Precision precision; if ( prec == 0.0 ) { precision = ecl::numeric_limits::dummy_precision; } else { precision = static_cast(prec); } return std::abs(static_cast(x) - y) <= std::min( std::abs(static_cast(x)), std::abs(y)) * precision; } } template static inline bool isApproxOrLessThan(const Scalar& x, const OtherScalar& y, const Precision&) { return x <= y; } }; // * @brief Fuzzy math implementation for complex numbers. // * // * Specialisation of fuzzy math functions for complex numbers. // * // * @tparam Scalar : autoselected by numeric traits as always being complex. // */ //template //struct scalar_fuzzy_default_impl { // typedef typename ecl::NumTraits::Precision Precision; // // static inline bool isApprox(const Scalar& x, const Scalar& y, const Precision& prec) { // return ei_abs2(x - y) <= std::min(ei_abs2(x), ei_abs2(y)) * prec * prec; // } //}; template struct scalar_fuzzy_impl : implementations::scalar_fuzzy_default_impl::is_integer> {}; } // implementations /***************************************************************************** ** Direct Interfaces *****************************************************************************/ template inline bool isApprox(const Scalar& x, const OtherScalar& y, typename numeric_limits::Precision precision = numeric_limits::dummy_precision) { return implementations::scalar_fuzzy_impl::isApprox(x, y, precision); } template inline bool isApproxOrLessThan(const Scalar& x, const OtherScalar& y, typename numeric_limits::Precision precision = numeric_limits::dummy_precision) { return implementations::scalar_fuzzy_impl::isApproxOrLessThan(x, y, precision); } } // namespace ecl #endif /* ECL_MATH_FUZZY_HPP_ */