Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/numeric/interval/interval.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /* Boost interval/interval.hpp header file | |
2 * | |
3 * Copyright 2002-2003 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion | |
4 * | |
5 * Distributed under the Boost Software License, Version 1.0. | |
6 * (See accompanying file LICENSE_1_0.txt or | |
7 * copy at http://www.boost.org/LICENSE_1_0.txt) | |
8 */ | |
9 | |
10 #ifndef BOOST_NUMERIC_INTERVAL_INTERVAL_HPP | |
11 #define BOOST_NUMERIC_INTERVAL_INTERVAL_HPP | |
12 | |
13 #include <stdexcept> | |
14 #include <string> | |
15 #include <boost/numeric/interval/detail/interval_prototype.hpp> | |
16 | |
17 namespace boost { | |
18 namespace numeric { | |
19 | |
20 namespace interval_lib { | |
21 | |
22 class comparison_error | |
23 : public std::runtime_error | |
24 { | |
25 public: | |
26 comparison_error() | |
27 : std::runtime_error("boost::interval: uncertain comparison") | |
28 { } | |
29 }; | |
30 | |
31 } // namespace interval_lib | |
32 | |
33 /* | |
34 * interval class | |
35 */ | |
36 | |
37 template<class T, class Policies> | |
38 class interval | |
39 { | |
40 private: | |
41 struct interval_holder; | |
42 struct number_holder; | |
43 public: | |
44 typedef T base_type; | |
45 typedef Policies traits_type; | |
46 | |
47 T const &lower() const; | |
48 T const &upper() const; | |
49 | |
50 interval(); | |
51 interval(T const &v); | |
52 template<class T1> interval(T1 const &v); | |
53 interval(T const &l, T const &u); | |
54 template<class T1, class T2> interval(T1 const &l, T2 const &u); | |
55 interval(interval<T, Policies> const &r); | |
56 template<class Policies1> interval(interval<T, Policies1> const &r); | |
57 template<class T1, class Policies1> interval(interval<T1, Policies1> const &r); | |
58 | |
59 interval &operator=(T const &v); | |
60 template<class T1> interval &operator=(T1 const &v); | |
61 interval &operator=(interval<T, Policies> const &r); | |
62 template<class Policies1> interval &operator=(interval<T, Policies1> const &r); | |
63 template<class T1, class Policies1> interval &operator=(interval<T1, Policies1> const &r); | |
64 | |
65 void assign(const T& l, const T& u); | |
66 | |
67 static interval empty(); | |
68 static interval whole(); | |
69 static interval hull(const T& x, const T& y); | |
70 | |
71 interval& operator+= (const T& r); | |
72 interval& operator+= (const interval& r); | |
73 interval& operator-= (const T& r); | |
74 interval& operator-= (const interval& r); | |
75 interval& operator*= (const T& r); | |
76 interval& operator*= (const interval& r); | |
77 interval& operator/= (const T& r); | |
78 interval& operator/= (const interval& r); | |
79 | |
80 bool operator< (const interval_holder& r) const; | |
81 bool operator> (const interval_holder& r) const; | |
82 bool operator<= (const interval_holder& r) const; | |
83 bool operator>= (const interval_holder& r) const; | |
84 bool operator== (const interval_holder& r) const; | |
85 bool operator!= (const interval_holder& r) const; | |
86 | |
87 bool operator< (const number_holder& r) const; | |
88 bool operator> (const number_holder& r) const; | |
89 bool operator<= (const number_holder& r) const; | |
90 bool operator>= (const number_holder& r) const; | |
91 bool operator== (const number_holder& r) const; | |
92 bool operator!= (const number_holder& r) const; | |
93 | |
94 // the following is for internal use only, it is not a published interface | |
95 // nevertheless, it's public because friends don't always work correctly. | |
96 interval(const T& l, const T& u, bool): low(l), up(u) {} | |
97 void set_empty(); | |
98 void set_whole(); | |
99 void set(const T& l, const T& u); | |
100 | |
101 private: | |
102 struct interval_holder { | |
103 template<class Policies2> | |
104 interval_holder(const interval<T, Policies2>& r) | |
105 : low(r.lower()), up(r.upper()) | |
106 { | |
107 typedef typename Policies2::checking checking2; | |
108 if (checking2::is_empty(low, up)) | |
109 throw interval_lib::comparison_error(); | |
110 } | |
111 | |
112 const T& low; | |
113 const T& up; | |
114 }; | |
115 | |
116 struct number_holder { | |
117 number_holder(const T& r) : val(r) | |
118 { | |
119 typedef typename Policies::checking checking; | |
120 if (checking::is_nan(r)) | |
121 throw interval_lib::comparison_error(); | |
122 } | |
123 | |
124 const T& val; | |
125 }; | |
126 | |
127 typedef typename Policies::checking checking; | |
128 typedef typename Policies::rounding rounding; | |
129 | |
130 T low; | |
131 T up; | |
132 }; | |
133 | |
134 template<class T, class Policies> inline | |
135 interval<T, Policies>::interval(): | |
136 low(static_cast<T>(0)), up(static_cast<T>(0)) | |
137 {} | |
138 | |
139 template<class T, class Policies> inline | |
140 interval<T, Policies>::interval(T const &v): low(v), up(v) | |
141 { | |
142 if (checking::is_nan(v)) set_empty(); | |
143 } | |
144 | |
145 template<class T, class Policies> template<class T1> inline | |
146 interval<T, Policies>::interval(T1 const &v) | |
147 { | |
148 if (checking::is_nan(v)) set_empty(); | |
149 else { | |
150 rounding rnd; | |
151 low = rnd.conv_down(v); | |
152 up = rnd.conv_up (v); | |
153 } | |
154 } | |
155 | |
156 template<class T, class Policies> template<class T1, class T2> inline | |
157 interval<T, Policies>::interval(T1 const &l, T2 const &u) | |
158 { | |
159 if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u)) set_empty(); | |
160 else { | |
161 rounding rnd; | |
162 low = rnd.conv_down(l); | |
163 up = rnd.conv_up (u); | |
164 } | |
165 } | |
166 | |
167 template<class T, class Policies> inline | |
168 interval<T, Policies>::interval(T const &l, T const &u): low(l), up(u) | |
169 { | |
170 if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u)) | |
171 set_empty(); | |
172 } | |
173 | |
174 | |
175 template<class T, class Policies> inline | |
176 interval<T, Policies>::interval(interval<T, Policies> const &r): low(r.lower()), up(r.upper()) | |
177 {} | |
178 | |
179 template<class T, class Policies> template<class Policies1> inline | |
180 interval<T, Policies>::interval(interval<T, Policies1> const &r): low(r.lower()), up(r.upper()) | |
181 { | |
182 typedef typename Policies1::checking checking1; | |
183 if (checking1::is_empty(r.lower(), r.upper())) set_empty(); | |
184 } | |
185 | |
186 template<class T, class Policies> template<class T1, class Policies1> inline | |
187 interval<T, Policies>::interval(interval<T1, Policies1> const &r) | |
188 { | |
189 typedef typename Policies1::checking checking1; | |
190 if (checking1::is_empty(r.lower(), r.upper())) set_empty(); | |
191 else { | |
192 rounding rnd; | |
193 low = rnd.conv_down(r.lower()); | |
194 up = rnd.conv_up (r.upper()); | |
195 } | |
196 } | |
197 | |
198 template<class T, class Policies> inline | |
199 interval<T, Policies> &interval<T, Policies>::operator=(T const &v) | |
200 { | |
201 if (checking::is_nan(v)) set_empty(); | |
202 else low = up = v; | |
203 return *this; | |
204 } | |
205 | |
206 template<class T, class Policies> template<class T1> inline | |
207 interval<T, Policies> &interval<T, Policies>::operator=(T1 const &v) | |
208 { | |
209 if (checking::is_nan(v)) set_empty(); | |
210 else { | |
211 rounding rnd; | |
212 low = rnd.conv_down(v); | |
213 up = rnd.conv_up (v); | |
214 } | |
215 return *this; | |
216 } | |
217 | |
218 template<class T, class Policies> inline | |
219 interval<T, Policies> &interval<T, Policies>::operator=(interval<T, Policies> const &r) | |
220 { | |
221 low = r.lower(); | |
222 up = r.upper(); | |
223 return *this; | |
224 } | |
225 | |
226 template<class T, class Policies> template<class Policies1> inline | |
227 interval<T, Policies> &interval<T, Policies>::operator=(interval<T, Policies1> const &r) | |
228 { | |
229 typedef typename Policies1::checking checking1; | |
230 if (checking1::is_empty(r.lower(), r.upper())) set_empty(); | |
231 else { | |
232 low = r.lower(); | |
233 up = r.upper(); | |
234 } | |
235 return *this; | |
236 } | |
237 | |
238 template<class T, class Policies> template<class T1, class Policies1> inline | |
239 interval<T, Policies> &interval<T, Policies>::operator=(interval<T1, Policies1> const &r) | |
240 { | |
241 typedef typename Policies1::checking checking1; | |
242 if (checking1::is_empty(r.lower(), r.upper())) set_empty(); | |
243 else { | |
244 rounding rnd; | |
245 low = rnd.conv_down(r.lower()); | |
246 up = rnd.conv_up (r.upper()); | |
247 } | |
248 return *this; | |
249 } | |
250 | |
251 template<class T, class Policies> inline | |
252 void interval<T, Policies>::assign(const T& l, const T& u) | |
253 { | |
254 if (checking::is_nan(l) || checking::is_nan(u) || !(l <= u)) | |
255 set_empty(); | |
256 else set(l, u); | |
257 } | |
258 | |
259 template<class T, class Policies> inline | |
260 void interval<T, Policies>::set(const T& l, const T& u) | |
261 { | |
262 low = l; | |
263 up = u; | |
264 } | |
265 | |
266 template<class T, class Policies> inline | |
267 void interval<T, Policies>::set_empty() | |
268 { | |
269 low = checking::empty_lower(); | |
270 up = checking::empty_upper(); | |
271 } | |
272 | |
273 template<class T, class Policies> inline | |
274 void interval<T, Policies>::set_whole() | |
275 { | |
276 low = checking::neg_inf(); | |
277 up = checking::pos_inf(); | |
278 } | |
279 | |
280 template<class T, class Policies> inline | |
281 interval<T, Policies> interval<T, Policies>::hull(const T& x, const T& y) | |
282 { | |
283 bool bad_x = checking::is_nan(x); | |
284 bool bad_y = checking::is_nan(y); | |
285 if (bad_x) | |
286 if (bad_y) return interval::empty(); | |
287 else return interval(y, y, true); | |
288 else | |
289 if (bad_y) return interval(x, x, true); | |
290 if (x <= y) return interval(x, y, true); | |
291 else return interval(y, x, true); | |
292 } | |
293 | |
294 template<class T, class Policies> inline | |
295 interval<T, Policies> interval<T, Policies>::empty() | |
296 { | |
297 return interval<T, Policies>(checking::empty_lower(), | |
298 checking::empty_upper(), true); | |
299 } | |
300 | |
301 template<class T, class Policies> inline | |
302 interval<T, Policies> interval<T, Policies>::whole() | |
303 { | |
304 return interval<T, Policies>(checking::neg_inf(), checking::pos_inf(), true); | |
305 } | |
306 | |
307 template<class T, class Policies> inline | |
308 const T& interval<T, Policies>::lower() const | |
309 { | |
310 return low; | |
311 } | |
312 | |
313 template<class T, class Policies> inline | |
314 const T& interval<T, Policies>::upper() const | |
315 { | |
316 return up; | |
317 } | |
318 | |
319 /* | |
320 * interval/interval comparisons | |
321 */ | |
322 | |
323 template<class T, class Policies> inline | |
324 bool interval<T, Policies>::operator< (const interval_holder& r) const | |
325 { | |
326 if (!checking::is_empty(low, up)) { | |
327 if (up < r.low) return true; | |
328 else if (low >= r.up) return false; | |
329 } | |
330 throw interval_lib::comparison_error(); | |
331 } | |
332 | |
333 template<class T, class Policies> inline | |
334 bool interval<T, Policies>::operator> (const interval_holder& r) const | |
335 { | |
336 if (!checking::is_empty(low, up)) { | |
337 if (low > r.up) return true; | |
338 else if (up <= r.low) return false; | |
339 } | |
340 throw interval_lib::comparison_error(); | |
341 } | |
342 | |
343 template<class T, class Policies> inline | |
344 bool interval<T, Policies>::operator<= (const interval_holder& r) const | |
345 { | |
346 if (!checking::is_empty(low, up)) { | |
347 if (up <= r.low) return true; | |
348 else if (low > r.up) return false; | |
349 } | |
350 throw interval_lib::comparison_error(); | |
351 } | |
352 | |
353 template<class T, class Policies> inline | |
354 bool interval<T, Policies>::operator>= (const interval_holder& r) const | |
355 { | |
356 if (!checking::is_empty(low, up)) { | |
357 if (low >= r.up) return true; | |
358 else if (up < r.low) return false; | |
359 } | |
360 throw interval_lib::comparison_error(); | |
361 } | |
362 | |
363 template<class T, class Policies> inline | |
364 bool interval<T, Policies>::operator== (const interval_holder& r) const | |
365 { | |
366 if (!checking::is_empty(low, up)) { | |
367 if (up == r.low && low == r.up) return true; | |
368 else if (up < r.low || low > r.up) return false; | |
369 } | |
370 throw interval_lib::comparison_error(); | |
371 } | |
372 | |
373 template<class T, class Policies> inline | |
374 bool interval<T, Policies>::operator!= (const interval_holder& r) const | |
375 { | |
376 if (!checking::is_empty(low, up)) { | |
377 if (up < r.low || low > r.up) return true; | |
378 else if (up == r.low && low == r.up) return false; | |
379 } | |
380 throw interval_lib::comparison_error(); | |
381 } | |
382 | |
383 /* | |
384 * interval/number comparisons | |
385 */ | |
386 | |
387 template<class T, class Policies> inline | |
388 bool interval<T, Policies>::operator< (const number_holder& r) const | |
389 { | |
390 if (!checking::is_empty(low, up)) { | |
391 if (up < r.val) return true; | |
392 else if (low >= r.val) return false; | |
393 } | |
394 throw interval_lib::comparison_error(); | |
395 } | |
396 | |
397 template<class T, class Policies> inline | |
398 bool interval<T, Policies>::operator> (const number_holder& r) const | |
399 { | |
400 if (!checking::is_empty(low, up)) { | |
401 if (low > r.val) return true; | |
402 else if (up <= r.val) return false; | |
403 } | |
404 throw interval_lib::comparison_error(); | |
405 } | |
406 | |
407 template<class T, class Policies> inline | |
408 bool interval<T, Policies>::operator<= (const number_holder& r) const | |
409 { | |
410 if (!checking::is_empty(low, up)) { | |
411 if (up <= r.val) return true; | |
412 else if (low > r.val) return false; | |
413 } | |
414 throw interval_lib::comparison_error(); | |
415 } | |
416 | |
417 template<class T, class Policies> inline | |
418 bool interval<T, Policies>::operator>= (const number_holder& r) const | |
419 { | |
420 if (!checking::is_empty(low, up)) { | |
421 if (low >= r.val) return true; | |
422 else if (up < r.val) return false; | |
423 } | |
424 throw interval_lib::comparison_error(); | |
425 } | |
426 | |
427 template<class T, class Policies> inline | |
428 bool interval<T, Policies>::operator== (const number_holder& r) const | |
429 { | |
430 if (!checking::is_empty(low, up)) { | |
431 if (up == r.val && low == r.val) return true; | |
432 else if (up < r.val || low > r.val) return false; | |
433 } | |
434 throw interval_lib::comparison_error(); | |
435 } | |
436 | |
437 template<class T, class Policies> inline | |
438 bool interval<T, Policies>::operator!= (const number_holder& r) const | |
439 { | |
440 if (!checking::is_empty(low, up)) { | |
441 if (up < r.val || low > r.val) return true; | |
442 else if (up == r.val && low == r.val) return false; | |
443 } | |
444 throw interval_lib::comparison_error(); | |
445 } | |
446 | |
447 } // namespace numeric | |
448 } // namespace boost | |
449 | |
450 #endif // BOOST_NUMERIC_INTERVAL_INTERVAL_HPP |