First public contribution.
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/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>
22 * Implementation of simple functions
32 template<class T, class Policies> inline
33 const T& lower(const interval<T, Policies>& x)
38 template<class T, class Policies> inline
39 const T& upper(const interval<T, Policies>& x)
44 template<class T, class Policies> inline
45 T checked_lower(const interval<T, Policies>& x)
48 typedef typename Policies::checking checking;
49 return checking::nan();
54 template<class T, class Policies> inline
55 T checked_upper(const interval<T, Policies>& x)
58 typedef typename Policies::checking checking;
59 return checking::nan();
64 template<class T, class Policies> inline
65 T width(const interval<T, Policies>& x)
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());
72 template<class T, class Policies> inline
73 T median(const interval<T, Policies>& x)
75 if (interval_lib::detail::test_input(x)) {
76 typedef typename Policies::checking checking;
77 return checking::nan();
79 typename Policies::rounding rnd;
80 return rnd.median(x.lower(), x.upper());
83 template<class T, class Policies> inline
84 interval<T, Policies> widen(const interval<T, Policies>& x, const T& v)
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);
97 template<class T, class Policies> inline
98 bool empty(const interval<T, Policies>& x)
100 return interval_lib::detail::test_input(x);
103 template<class T, class Policies> inline
104 bool zero_in(const interval<T, Policies>& x)
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()));
111 template<class T, class Policies> inline
112 bool in_zero(const interval<T, Policies>& x) // DEPRECATED
114 return zero_in<T, Policies>(x);
117 template<class T, class Policies> inline
118 bool in(const T& x, const interval<T, Policies>& y)
120 if (interval_lib::detail::test_input(x, y)) return false;
121 return y.lower() <= x && x <= y.upper();
124 template<class T, class Policies> inline
125 bool subset(const interval<T, Policies>& x,
126 const interval<T, Policies>& y)
128 if (empty(x)) return true;
129 return !empty(y) && y.lower() <= x.lower() && x.upper() <= y.upper();
132 template<class T, class Policies1, class Policies2> inline
133 bool proper_subset(const interval<T, Policies1>& x,
134 const interval<T, Policies2>& y)
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());
142 template<class T, class Policies1, class Policies2> inline
143 bool overlap(const interval<T, Policies1>& x,
144 const interval<T, Policies2>& y)
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();
151 template<class T, class Policies> inline
152 bool singleton(const interval<T, Policies>& x)
154 return !empty(x) && x.lower() == x.upper();
157 template<class T, class Policies1, class Policies2> inline
158 bool equal(const interval<T, Policies1>& x, const interval<T, Policies2>& y)
160 if (empty(x)) return empty(y);
161 return !empty(y) && x.lower() == y.lower() && x.upper() == y.upper();
164 template<class T, class Policies> inline
165 interval<T, Policies> intersect(const interval<T, Policies>& x,
166 const interval<T, Policies>& y)
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();
178 template<class T, class Policies> inline
179 interval<T, Policies> hull(const interval<T, Policies>& x,
180 const interval<T, Policies>& y)
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);
187 if (bad_y) return interval<T, Policies>::empty();
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);
195 template<class T, class Policies> inline
196 interval<T, Policies> hull(const interval<T, Policies>& x, const T& y)
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);
203 if (bad_x) return interval<T, Policies>::empty();
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);
211 template<class T, class Policies> inline
212 interval<T, Policies> hull(const T& x, const interval<T, Policies>& y)
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);
219 if (bad_y) return interval<T, Policies>::empty();
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);
227 template<class T> inline
228 interval<T> hull(const T& x, const T& y)
230 return interval<T>::hull(x, y);
233 template<class T, class Policies> inline
234 std::pair<interval<T, Policies>, interval<T, Policies> >
235 bisect(const interval<T, Policies>& x)
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));
245 * Elementary functions
248 template<class T, class Policies> inline
249 T norm(const interval<T, Policies>& x)
251 typedef interval<T, Policies> I;
252 if (interval_lib::detail::test_input(x)) {
253 typedef typename Policies::checking checking;
254 return checking::nan();
256 BOOST_USING_STD_MAX();
257 return max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast<T>(-x.lower()), x.upper());
260 template<class T, class Policies> inline
261 interval<T, Policies> abs(const interval<T, Policies>& x)
263 typedef interval<T, Policies> I;
264 if (interval_lib::detail::test_input(x))
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);
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)
276 typedef interval<T, Policies> I;
277 if (interval_lib::detail::test_input(x, y))
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);
283 template<class T, class Policies> inline
284 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
286 typedef interval<T, Policies> I;
287 if (interval_lib::detail::test_input(x, y))
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);
293 template<class T, class Policies> inline
294 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
296 typedef interval<T, Policies> I;
297 if (interval_lib::detail::test_input(x, y))
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);
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)
307 typedef interval<T, Policies> I;
308 if (interval_lib::detail::test_input(x, y))
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);
314 template<class T, class Policies> inline
315 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
317 typedef interval<T, Policies> I;
318 if (interval_lib::detail::test_input(x, y))
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);
324 template<class T, class Policies> inline
325 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
327 typedef interval<T, Policies> I;
328 if (interval_lib::detail::test_input(x, y))
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);
334 } // namespace numeric
337 #endif // BOOST_NUMERIC_INTERVAL_UTILITY_HPP