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