1 /* Boost interval/utility.hpp template implementation file
3 * Copyright 2000 Jens Maurer
4 * Copyright 2002-2003 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion
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)
11 #ifndef BOOST_NUMERIC_INTERVAL_UTILITY_HPP
12 #define BOOST_NUMERIC_INTERVAL_UTILITY_HPP
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>
21 * Implementation of simple functions
31 template<class T, class Policies> inline
32 const T& lower(const interval<T, Policies>& x)
37 template<class T, class Policies> inline
38 const T& upper(const interval<T, Policies>& x)
43 template<class T, class Policies> inline
44 T checked_lower(const interval<T, Policies>& x)
47 typedef typename Policies::checking checking;
48 return checking::nan();
53 template<class T, class Policies> inline
54 T checked_upper(const interval<T, Policies>& x)
57 typedef typename Policies::checking checking;
58 return checking::nan();
63 template<class T, class Policies> inline
64 T width(const interval<T, Policies>& x)
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());
71 template<class T, class Policies> inline
72 T median(const interval<T, Policies>& x)
74 if (interval_lib::detail::test_input(x)) {
75 typedef typename Policies::checking checking;
76 return checking::nan();
78 typename Policies::rounding rnd;
79 return rnd.median(x.lower(), x.upper());
82 template<class T, class Policies> inline
83 interval<T, Policies> widen(const interval<T, Policies>& x, const T& v)
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);
96 template<class T, class Policies> inline
97 bool empty(const interval<T, Policies>& x)
99 return interval_lib::detail::test_input(x);
102 template<class T, class Policies> inline
103 bool zero_in(const interval<T, Policies>& x)
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()));
110 template<class T, class Policies> inline
111 bool in_zero(const interval<T, Policies>& x) // DEPRECATED
113 return zero_in<T, Policies>(x);
116 template<class T, class Policies> inline
117 bool in(const T& x, const interval<T, Policies>& y)
119 if (interval_lib::detail::test_input(x, y)) return false;
120 return y.lower() <= x && x <= y.upper();
123 template<class T, class Policies> inline
124 bool subset(const interval<T, Policies>& x,
125 const interval<T, Policies>& y)
127 if (empty(x)) return true;
128 return !empty(y) && y.lower() <= x.lower() && x.upper() <= y.upper();
131 template<class T, class Policies1, class Policies2> inline
132 bool proper_subset(const interval<T, Policies1>& x,
133 const interval<T, Policies2>& y)
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());
141 template<class T, class Policies1, class Policies2> inline
142 bool overlap(const interval<T, Policies1>& x,
143 const interval<T, Policies2>& y)
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());
150 template<class T, class Policies> inline
151 bool singleton(const interval<T, Policies>& x)
153 return !empty(x) && x.lower() == x.upper();
156 template<class T, class Policies1, class Policies2> inline
157 bool equal(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
159 if (empty(x)) return empty(y);
160 return !empty(y) && x.lower() == y.lower() && x.upper() == y.upper();
163 template<class T, class Policies> inline
164 interval<T, Policies> intersect(const interval<T, Policies>& x,
165 const interval<T, Policies>& y)
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();
177 template<class T, class Policies> inline
178 interval<T, Policies> hull(const interval<T, Policies>& x,
179 const interval<T, Policies>& y)
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);
186 if (bad_y) return interval<T, Policies>::empty();
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);
194 template<class T, class Policies> inline
195 interval<T, Policies> hull(const interval<T, Policies>& x, const T& y)
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);
202 if (bad_x) return interval<T, Policies>::empty();
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);
210 template<class T, class Policies> inline
211 interval<T, Policies> hull(const T& x, const interval<T, Policies>& y)
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);
218 if (bad_y) return interval<T, Policies>::empty();
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);
226 template<class T> inline
227 interval<T> hull(const T& x, const T& y)
229 return interval<T>::hull(x, y);
232 template<class T, class Policies> inline
233 std::pair<interval<T, Policies>, interval<T, Policies> >
234 bisect(const interval<T, Policies>& x)
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));
244 * Elementary functions
247 template<class T, class Policies> inline
248 T norm(const interval<T, Policies>& x)
250 if (interval_lib::detail::test_input(x)) {
251 typedef typename Policies::checking checking;
252 return checking::nan();
254 BOOST_USING_STD_MAX();
255 return max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast<T>(-x.lower()), x.upper());
258 template<class T, class Policies> inline
259 interval<T, Policies> abs(const interval<T, Policies>& x)
261 typedef interval<T, Policies> I;
262 if (interval_lib::detail::test_input(x))
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);
270 template<class T, class Policies> inline
271 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x,
272 const interval<T, Policies>& y)
274 typedef interval<T, Policies> I;
275 if (interval_lib::detail::test_input(x, y))
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);
281 template<class T, class Policies> inline
282 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
284 typedef interval<T, Policies> I;
285 if (interval_lib::detail::test_input(x, y))
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);
291 template<class T, class Policies> inline
292 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
294 typedef interval<T, Policies> I;
295 if (interval_lib::detail::test_input(x, y))
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);
301 template<class T, class Policies> inline
302 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x,
303 const interval<T, Policies>& y)
305 typedef interval<T, Policies> I;
306 if (interval_lib::detail::test_input(x, y))
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);
312 template<class T, class Policies> inline
313 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
315 typedef interval<T, Policies> I;
316 if (interval_lib::detail::test_input(x, y))
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);
322 template<class T, class Policies> inline
323 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
325 typedef interval<T, Policies> I;
326 if (interval_lib::detail::test_input(x, y))
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);
332 } // namespace numeric
335 #endif // BOOST_NUMERIC_INTERVAL_UTILITY_HPP