source: NonGTP/Boost/boost/numeric/interval/utility.hpp @ 857

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