os/ossrv/ossrv_pub/boost_apis/boost/numeric/interval/utility.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /* Boost interval/utility.hpp template implementation file
     2  *
     3  * Copyright 2000 Jens Maurer
     4  * Copyright 2002-2003 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion
     5  *
     6  * Distributed under the Boost Software License, Version 1.0.
     7  * (See accompanying file LICENSE_1_0.txt or
     8  * copy at http://www.boost.org/LICENSE_1_0.txt)
     9  */
    10 
    11 #ifndef BOOST_NUMERIC_INTERVAL_UTILITY_HPP
    12 #define BOOST_NUMERIC_INTERVAL_UTILITY_HPP
    13 
    14 #include <boost/config.hpp>
    15 #include <boost/numeric/interval/detail/interval_prototype.hpp>
    16 #include <boost/numeric/interval/detail/test_input.hpp>
    17 #include <boost/numeric/interval/detail/bugs.hpp>
    18 #include <algorithm>
    19 #include <utility>
    20 
    21 /*
    22  * Implementation of simple functions
    23  */
    24 
    25 namespace boost {
    26 namespace numeric {
    27 
    28 /*
    29  * Utility Functions
    30  */
    31 
    32 template<class T, class Policies> inline
    33 const T& lower(const interval<T, Policies>& x)
    34 {
    35   return x.lower();
    36 }
    37 
    38 template<class T, class Policies> inline
    39 const T& upper(const interval<T, Policies>& x)
    40 {
    41   return x.upper();
    42 }
    43 
    44 template<class T, class Policies> inline
    45 T checked_lower(const interval<T, Policies>& x)
    46 {
    47   if (empty(x)) {
    48     typedef typename Policies::checking checking;
    49     return checking::nan();
    50   }
    51   return x.lower();
    52 }
    53 
    54 template<class T, class Policies> inline
    55 T checked_upper(const interval<T, Policies>& x)
    56 {
    57   if (empty(x)) {
    58     typedef typename Policies::checking checking;
    59     return checking::nan();
    60   }
    61   return x.upper();
    62 }
    63 
    64 template<class T, class Policies> inline
    65 T width(const interval<T, Policies>& x)
    66 {
    67   if (interval_lib::detail::test_input(x)) return static_cast<T>(0);
    68   typename Policies::rounding rnd;
    69   return rnd.sub_up(x.upper(), x.lower());
    70 }
    71 
    72 template<class T, class Policies> inline
    73 T median(const interval<T, Policies>& x)
    74 {
    75   if (interval_lib::detail::test_input(x)) {
    76     typedef typename Policies::checking checking;
    77     return checking::nan();
    78   }
    79   typename Policies::rounding rnd;
    80   return rnd.median(x.lower(), x.upper());
    81 }
    82 
    83 template<class T, class Policies> inline
    84 interval<T, Policies> widen(const interval<T, Policies>& x, const T& v)
    85 {
    86   if (interval_lib::detail::test_input(x))
    87     return interval<T, Policies>::empty();
    88   typename Policies::rounding rnd;
    89   return interval<T, Policies>(rnd.sub_down(x.lower(), v),
    90                                rnd.add_up  (x.upper(), v), true);
    91 }
    92 
    93 /*
    94  * Set-like operations
    95  */
    96 
    97 template<class T, class Policies> inline
    98 bool empty(const interval<T, Policies>& x)
    99 {
   100   return interval_lib::detail::test_input(x);
   101 }
   102 
   103 template<class T, class Policies> inline
   104 bool zero_in(const interval<T, Policies>& x)
   105 {
   106   if (interval_lib::detail::test_input(x)) return false;
   107   return (!interval_lib::user::is_pos(x.lower())) &&
   108          (!interval_lib::user::is_neg(x.upper()));
   109 }
   110 
   111 template<class T, class Policies> inline
   112 bool in_zero(const interval<T, Policies>& x) // DEPRECATED
   113 {
   114   return zero_in<T, Policies>(x);
   115 }
   116 
   117 template<class T, class Policies> inline
   118 bool in(const T& x, const interval<T, Policies>& y)
   119 {
   120   if (interval_lib::detail::test_input(x, y)) return false;
   121   return y.lower() <= x && x <= y.upper();
   122 }
   123 
   124 template<class T, class Policies> inline
   125 bool subset(const interval<T, Policies>& x,
   126             const interval<T, Policies>& y)
   127 {
   128   if (empty(x)) return true;
   129   return !empty(y) && y.lower() <= x.lower() && x.upper() <= y.upper();
   130 }
   131 
   132 template<class T, class Policies1, class Policies2> inline
   133 bool proper_subset(const interval<T, Policies1>& x,
   134                    const interval<T, Policies2>& y)
   135 {
   136   if (empty(y)) return false;
   137   if (empty(x)) return true;
   138   return y.lower() <= x.lower() && x.upper() <= y.upper() &&
   139          (y.lower() != x.lower() || x.upper() != y.upper());
   140 }
   141 
   142 template<class T, class Policies1, class Policies2> inline
   143 bool overlap(const interval<T, Policies1>& x,
   144              const interval<T, Policies2>& y)
   145 {
   146   if (interval_lib::detail::test_input(x, y)) return false;
   147   return x.lower() <= y.lower() && y.lower() <= x.upper() ||
   148          y.lower() <= x.lower() && x.lower() <= y.upper();
   149 }
   150 
   151 template<class T, class Policies> inline
   152 bool singleton(const interval<T, Policies>& x)
   153 {
   154  return !empty(x) && x.lower() == x.upper();
   155 }
   156 
   157 template<class T, class Policies1, class Policies2> inline
   158 bool equal(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
   159 {
   160   if (empty(x)) return empty(y);
   161   return !empty(y) && x.lower() == y.lower() && x.upper() == y.upper();
   162 }
   163 
   164 template<class T, class Policies> inline
   165 interval<T, Policies> intersect(const interval<T, Policies>& x,
   166                                 const interval<T, Policies>& y)
   167 {
   168   BOOST_USING_STD_MIN();
   169   BOOST_USING_STD_MAX();
   170   if (interval_lib::detail::test_input(x, y))
   171     return interval<T, Policies>::empty();
   172   const T& l = max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower());
   173   const T& u = min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper());
   174   if (l <= u) return interval<T, Policies>(l, u, true);
   175   else        return interval<T, Policies>::empty();
   176 }
   177 
   178 template<class T, class Policies> inline
   179 interval<T, Policies> hull(const interval<T, Policies>& x,
   180                            const interval<T, Policies>& y)
   181 {
   182   BOOST_USING_STD_MIN();
   183   BOOST_USING_STD_MAX();
   184   bool bad_x = interval_lib::detail::test_input(x);
   185   bool bad_y = interval_lib::detail::test_input(y);
   186   if (bad_x)
   187     if (bad_y) return interval<T, Policies>::empty();
   188     else       return y;
   189   else
   190     if (bad_y) return x;
   191   return interval<T, Policies>(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()),
   192                                max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true);
   193 }
   194 
   195 template<class T, class Policies> inline
   196 interval<T, Policies> hull(const interval<T, Policies>& x, const T& y)
   197 {
   198   BOOST_USING_STD_MIN();
   199   BOOST_USING_STD_MAX();
   200   bool bad_x = interval_lib::detail::test_input(x);
   201   bool bad_y = interval_lib::detail::test_input<T, Policies>(y);
   202   if (bad_y)
   203     if (bad_x) return interval<T, Policies>::empty();
   204     else       return x;
   205   else
   206     if (bad_x) return interval<T, Policies>(y, y, true);
   207   return interval<T, Policies>(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y),
   208                                max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true);
   209 }
   210 
   211 template<class T, class Policies> inline
   212 interval<T, Policies> hull(const T& x, const interval<T, Policies>& y)
   213 {
   214   BOOST_USING_STD_MIN();
   215   BOOST_USING_STD_MAX();
   216   bool bad_x = interval_lib::detail::test_input<T, Policies>(x);
   217   bool bad_y = interval_lib::detail::test_input(y);
   218   if (bad_x)
   219     if (bad_y) return interval<T, Policies>::empty();
   220     else       return y;
   221   else
   222     if (bad_y) return interval<T, Policies>(x, x, true);
   223   return interval<T, Policies>(min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()),
   224                                max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true);
   225 }
   226 
   227 template<class T> inline
   228 interval<T> hull(const T& x, const T& y)
   229 {
   230   return interval<T>::hull(x, y);
   231 }
   232 
   233 template<class T, class Policies> inline
   234 std::pair<interval<T, Policies>, interval<T, Policies> >
   235 bisect(const interval<T, Policies>& x)
   236 {
   237   typedef interval<T, Policies> I;
   238   if (interval_lib::detail::test_input(x))
   239     return std::pair<I,I>(I::empty(), I::empty());
   240   const T m = median(x);
   241   return std::pair<I,I>(I(x.lower(), m, true), I(m, x.upper(), true));
   242 }
   243 
   244 /*
   245  * Elementary functions
   246  */
   247 
   248 template<class T, class Policies> inline
   249 T norm(const interval<T, Policies>& x)
   250 {
   251   typedef interval<T, Policies> I;
   252   if (interval_lib::detail::test_input(x)) {
   253     typedef typename Policies::checking checking;
   254     return checking::nan();
   255   }
   256   BOOST_USING_STD_MAX();
   257   return max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast<T>(-x.lower()), x.upper());
   258 }
   259 
   260 template<class T, class Policies> inline
   261 interval<T, Policies> abs(const interval<T, Policies>& x)
   262 {
   263   typedef interval<T, Policies> I;
   264   if (interval_lib::detail::test_input(x))
   265     return I::empty();
   266   if (!interval_lib::user::is_neg(x.lower())) return x;
   267   if (!interval_lib::user::is_pos(x.upper())) return -x;
   268   BOOST_USING_STD_MAX();
   269   return I(static_cast<T>(0), max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast<T>(-x.lower()), x.upper()), true);
   270 }
   271 
   272 template<class T, class Policies> inline
   273 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x,
   274                                                             const interval<T, Policies>& y)
   275 {
   276   typedef interval<T, Policies> I;
   277   if (interval_lib::detail::test_input(x, y))
   278     return I::empty();
   279   BOOST_USING_STD_MAX();
   280   return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()), max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true);
   281 }
   282 
   283 template<class T, class Policies> inline
   284 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
   285 {
   286   typedef interval<T, Policies> I;
   287   if (interval_lib::detail::test_input(x, y))
   288     return I::empty();
   289   BOOST_USING_STD_MAX();
   290   return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y), max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true);
   291 }
   292 
   293 template<class T, class Policies> inline
   294 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
   295 {
   296   typedef interval<T, Policies> I;
   297   if (interval_lib::detail::test_input(x, y))
   298     return I::empty();
   299   BOOST_USING_STD_MAX();
   300   return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()), max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true);
   301 }
   302 
   303 template<class T, class Policies> inline
   304 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x,
   305                                                             const interval<T, Policies>& y)
   306 {
   307   typedef interval<T, Policies> I;
   308   if (interval_lib::detail::test_input(x, y))
   309     return I::empty();
   310   BOOST_USING_STD_MIN();
   311   return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()), min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true);
   312 }
   313 
   314 template<class T, class Policies> inline
   315 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
   316 {
   317   typedef interval<T, Policies> I;
   318   if (interval_lib::detail::test_input(x, y))
   319     return I::empty();
   320   BOOST_USING_STD_MIN();
   321   return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y), min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true);
   322 }
   323 
   324 template<class T, class Policies> inline
   325 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
   326 {
   327   typedef interval<T, Policies> I;
   328   if (interval_lib::detail::test_input(x, y))
   329     return I::empty();
   330   BOOST_USING_STD_MIN();
   331   return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()), min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true);
   332 }
   333 
   334 } // namespace numeric
   335 } // namespace boost
   336 
   337 #endif // BOOST_NUMERIC_INTERVAL_UTILITY_HPP