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