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