sl@0: /* Boost interval/utility.hpp template implementation file sl@0: * sl@0: * Copyright 2000 Jens Maurer sl@0: * Copyright 2002-2003 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion sl@0: * sl@0: * Distributed under the Boost Software License, Version 1.0. sl@0: * (See accompanying file LICENSE_1_0.txt or sl@0: * copy at http://www.boost.org/LICENSE_1_0.txt) sl@0: */ sl@0: sl@0: #ifndef BOOST_NUMERIC_INTERVAL_UTILITY_HPP sl@0: #define BOOST_NUMERIC_INTERVAL_UTILITY_HPP sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: /* sl@0: * Implementation of simple functions sl@0: */ sl@0: sl@0: namespace boost { sl@0: namespace numeric { sl@0: sl@0: /* sl@0: * Utility Functions sl@0: */ sl@0: sl@0: template inline sl@0: const T& lower(const interval& x) sl@0: { sl@0: return x.lower(); sl@0: } sl@0: sl@0: template inline sl@0: const T& upper(const interval& x) sl@0: { sl@0: return x.upper(); sl@0: } sl@0: sl@0: template inline sl@0: T checked_lower(const interval& x) sl@0: { sl@0: if (empty(x)) { sl@0: typedef typename Policies::checking checking; sl@0: return checking::nan(); sl@0: } sl@0: return x.lower(); sl@0: } sl@0: sl@0: template inline sl@0: T checked_upper(const interval& x) sl@0: { sl@0: if (empty(x)) { sl@0: typedef typename Policies::checking checking; sl@0: return checking::nan(); sl@0: } sl@0: return x.upper(); sl@0: } sl@0: sl@0: template inline sl@0: T width(const interval& x) sl@0: { sl@0: if (interval_lib::detail::test_input(x)) return static_cast(0); sl@0: typename Policies::rounding rnd; sl@0: return rnd.sub_up(x.upper(), x.lower()); sl@0: } sl@0: sl@0: template inline sl@0: T median(const interval& x) sl@0: { sl@0: if (interval_lib::detail::test_input(x)) { sl@0: typedef typename Policies::checking checking; sl@0: return checking::nan(); sl@0: } sl@0: typename Policies::rounding rnd; sl@0: return rnd.median(x.lower(), x.upper()); sl@0: } sl@0: sl@0: template inline sl@0: interval widen(const interval& x, const T& v) sl@0: { sl@0: if (interval_lib::detail::test_input(x)) sl@0: return interval::empty(); sl@0: typename Policies::rounding rnd; sl@0: return interval(rnd.sub_down(x.lower(), v), sl@0: rnd.add_up (x.upper(), v), true); sl@0: } sl@0: sl@0: /* sl@0: * Set-like operations sl@0: */ sl@0: sl@0: template inline sl@0: bool empty(const interval& x) sl@0: { sl@0: return interval_lib::detail::test_input(x); sl@0: } sl@0: sl@0: template inline sl@0: bool zero_in(const interval& x) sl@0: { sl@0: if (interval_lib::detail::test_input(x)) return false; sl@0: return (!interval_lib::user::is_pos(x.lower())) && sl@0: (!interval_lib::user::is_neg(x.upper())); sl@0: } sl@0: sl@0: template inline sl@0: bool in_zero(const interval& x) // DEPRECATED sl@0: { sl@0: return zero_in(x); sl@0: } sl@0: sl@0: template inline sl@0: bool in(const T& x, const interval& y) sl@0: { sl@0: if (interval_lib::detail::test_input(x, y)) return false; sl@0: return y.lower() <= x && x <= y.upper(); sl@0: } sl@0: sl@0: template inline sl@0: bool subset(const interval& x, sl@0: const interval& y) sl@0: { sl@0: if (empty(x)) return true; sl@0: return !empty(y) && y.lower() <= x.lower() && x.upper() <= y.upper(); sl@0: } sl@0: sl@0: template inline sl@0: bool proper_subset(const interval& x, sl@0: const interval& y) sl@0: { sl@0: if (empty(y)) return false; sl@0: if (empty(x)) return true; sl@0: return y.lower() <= x.lower() && x.upper() <= y.upper() && sl@0: (y.lower() != x.lower() || x.upper() != y.upper()); sl@0: } sl@0: sl@0: template inline sl@0: bool overlap(const interval& x, sl@0: const interval& y) sl@0: { sl@0: if (interval_lib::detail::test_input(x, y)) return false; sl@0: return x.lower() <= y.lower() && y.lower() <= x.upper() || sl@0: y.lower() <= x.lower() && x.lower() <= y.upper(); sl@0: } sl@0: sl@0: template inline sl@0: bool singleton(const interval& x) sl@0: { sl@0: return !empty(x) && x.lower() == x.upper(); sl@0: } sl@0: sl@0: template inline sl@0: bool equal(const interval& x, const interval& y) sl@0: { sl@0: if (empty(x)) return empty(y); sl@0: return !empty(y) && x.lower() == y.lower() && x.upper() == y.upper(); sl@0: } sl@0: sl@0: template inline sl@0: interval intersect(const interval& x, sl@0: const interval& y) sl@0: { sl@0: BOOST_USING_STD_MIN(); sl@0: BOOST_USING_STD_MAX(); sl@0: if (interval_lib::detail::test_input(x, y)) sl@0: return interval::empty(); sl@0: const T& l = max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()); sl@0: const T& u = min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()); sl@0: if (l <= u) return interval(l, u, true); sl@0: else return interval::empty(); sl@0: } sl@0: sl@0: template inline sl@0: interval hull(const interval& x, sl@0: const interval& y) sl@0: { sl@0: BOOST_USING_STD_MIN(); sl@0: BOOST_USING_STD_MAX(); sl@0: bool bad_x = interval_lib::detail::test_input(x); sl@0: bool bad_y = interval_lib::detail::test_input(y); sl@0: if (bad_x) sl@0: if (bad_y) return interval::empty(); sl@0: else return y; sl@0: else sl@0: if (bad_y) return x; sl@0: return interval(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()), sl@0: max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true); sl@0: } sl@0: sl@0: template inline sl@0: interval hull(const interval& x, const T& y) sl@0: { sl@0: BOOST_USING_STD_MIN(); sl@0: BOOST_USING_STD_MAX(); sl@0: bool bad_x = interval_lib::detail::test_input(x); sl@0: bool bad_y = interval_lib::detail::test_input(y); sl@0: if (bad_y) sl@0: if (bad_x) return interval::empty(); sl@0: else return x; sl@0: else sl@0: if (bad_x) return interval(y, y, true); sl@0: return interval(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y), sl@0: max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true); sl@0: } sl@0: sl@0: template inline sl@0: interval hull(const T& x, const interval& y) sl@0: { sl@0: BOOST_USING_STD_MIN(); sl@0: BOOST_USING_STD_MAX(); sl@0: bool bad_x = interval_lib::detail::test_input(x); sl@0: bool bad_y = interval_lib::detail::test_input(y); sl@0: if (bad_x) sl@0: if (bad_y) return interval::empty(); sl@0: else return y; sl@0: else sl@0: if (bad_y) return interval(x, x, true); sl@0: return interval(min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()), sl@0: max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true); sl@0: } sl@0: sl@0: template inline sl@0: interval hull(const T& x, const T& y) sl@0: { sl@0: return interval::hull(x, y); sl@0: } sl@0: sl@0: template inline sl@0: std::pair, interval > sl@0: bisect(const interval& x) sl@0: { sl@0: typedef interval I; sl@0: if (interval_lib::detail::test_input(x)) sl@0: return std::pair(I::empty(), I::empty()); sl@0: const T m = median(x); sl@0: return std::pair(I(x.lower(), m, true), I(m, x.upper(), true)); sl@0: } sl@0: sl@0: /* sl@0: * Elementary functions sl@0: */ sl@0: sl@0: template inline sl@0: T norm(const interval& x) sl@0: { sl@0: typedef interval I; sl@0: if (interval_lib::detail::test_input(x)) { sl@0: typedef typename Policies::checking checking; sl@0: return checking::nan(); sl@0: } sl@0: BOOST_USING_STD_MAX(); sl@0: return max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast(-x.lower()), x.upper()); sl@0: } sl@0: sl@0: template inline sl@0: interval abs(const interval& x) sl@0: { sl@0: typedef interval I; sl@0: if (interval_lib::detail::test_input(x)) sl@0: return I::empty(); sl@0: if (!interval_lib::user::is_neg(x.lower())) return x; sl@0: if (!interval_lib::user::is_pos(x.upper())) return -x; sl@0: BOOST_USING_STD_MAX(); sl@0: return I(static_cast(0), max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast(-x.lower()), x.upper()), true); sl@0: } sl@0: sl@0: template inline sl@0: interval max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval& x, sl@0: const interval& y) sl@0: { sl@0: typedef interval I; sl@0: if (interval_lib::detail::test_input(x, y)) sl@0: return I::empty(); sl@0: BOOST_USING_STD_MAX(); sl@0: return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()), max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true); sl@0: } sl@0: sl@0: template inline sl@0: interval max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval& x, const T& y) sl@0: { sl@0: typedef interval I; sl@0: if (interval_lib::detail::test_input(x, y)) sl@0: return I::empty(); sl@0: BOOST_USING_STD_MAX(); sl@0: return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y), max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true); sl@0: } sl@0: sl@0: template inline sl@0: interval max BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval& y) sl@0: { sl@0: typedef interval I; sl@0: if (interval_lib::detail::test_input(x, y)) sl@0: return I::empty(); sl@0: BOOST_USING_STD_MAX(); sl@0: return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()), max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true); sl@0: } sl@0: sl@0: template inline sl@0: interval min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval& x, sl@0: const interval& y) sl@0: { sl@0: typedef interval I; sl@0: if (interval_lib::detail::test_input(x, y)) sl@0: return I::empty(); sl@0: BOOST_USING_STD_MIN(); sl@0: return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()), min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true); sl@0: } sl@0: sl@0: template inline sl@0: interval min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval& x, const T& y) sl@0: { sl@0: typedef interval I; sl@0: if (interval_lib::detail::test_input(x, y)) sl@0: return I::empty(); sl@0: BOOST_USING_STD_MIN(); sl@0: return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y), min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true); sl@0: } sl@0: sl@0: template inline sl@0: interval min BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval& y) sl@0: { sl@0: typedef interval I; sl@0: if (interval_lib::detail::test_input(x, y)) sl@0: return I::empty(); sl@0: BOOST_USING_STD_MIN(); sl@0: return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()), min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true); sl@0: } sl@0: sl@0: } // namespace numeric sl@0: } // namespace boost sl@0: sl@0: #endif // BOOST_NUMERIC_INTERVAL_UTILITY_HPP