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 if (interval_lib::detail::test_input(x)) {
252 typedef typename Policies::checking checking;
253 return checking::nan();
255 BOOST_USING_STD_MAX();
256 return max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast<T>(-x.lower()), x.upper());
259 template<class T, class Policies> inline
260 interval<T, Policies> abs(const interval<T, Policies>& x)
262 typedef interval<T, Policies> I;
263 if (interval_lib::detail::test_input(x))
265 if (!interval_lib::user::is_neg(x.lower())) return x;
266 if (!interval_lib::user::is_pos(x.upper())) return -x;
267 BOOST_USING_STD_MAX();
268 return I(static_cast<T>(0), max BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast<T>(-x.lower()), x.upper()), true);
271 template<class T, class Policies> inline
272 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x,
273 const interval<T, Policies>& y)
275 typedef interval<T, Policies> I;
276 if (interval_lib::detail::test_input(x, y))
278 BOOST_USING_STD_MAX();
279 return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()), max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true);
282 template<class T, class Policies> inline
283 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
285 typedef interval<T, Policies> I;
286 if (interval_lib::detail::test_input(x, y))
288 BOOST_USING_STD_MAX();
289 return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y), max BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true);
292 template<class T, class Policies> inline
293 interval<T, Policies> max BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
295 typedef interval<T, Policies> I;
296 if (interval_lib::detail::test_input(x, y))
298 BOOST_USING_STD_MAX();
299 return I(max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()), max BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true);
302 template<class T, class Policies> inline
303 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x,
304 const interval<T, Policies>& y)
306 typedef interval<T, Policies> I;
307 if (interval_lib::detail::test_input(x, y))
309 BOOST_USING_STD_MIN();
310 return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y.lower()), min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y.upper()), true);
313 template<class T, class Policies> inline
314 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const interval<T, Policies>& x, const T& y)
316 typedef interval<T, Policies> I;
317 if (interval_lib::detail::test_input(x, y))
319 BOOST_USING_STD_MIN();
320 return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x.lower(), y), min BOOST_PREVENT_MACRO_SUBSTITUTION(x.upper(), y), true);
323 template<class T, class Policies> inline
324 interval<T, Policies> min BOOST_PREVENT_MACRO_SUBSTITUTION (const T& x, const interval<T, Policies>& y)
326 typedef interval<T, Policies> I;
327 if (interval_lib::detail::test_input(x, y))
329 BOOST_USING_STD_MIN();
330 return I(min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.lower()), min BOOST_PREVENT_MACRO_SUBSTITUTION(x, y.upper()), true);
333 } // namespace numeric
336 #endif // BOOST_NUMERIC_INTERVAL_UTILITY_HPP