numerix_doc 0.4
|
00001 00002 /****************************************************************************** 00003 * MODULE : ball.hpp 00004 * DESCRIPTION: Balls 00005 * COPYRIGHT : (C) 2006 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00011 ******************************************************************************/ 00012 00013 #ifndef __MMX_BALL_HPP 00014 #define __MMX_BALL_HPP 00015 #include <numerix/ball_rounded.hpp> 00016 #include <numerix/ball_rough.hpp> 00017 #include <numerix/ball_infinities.hpp> 00018 namespace mmx { 00019 #define Ball_variant(C) typename ball_variant_helper<C>::BV 00020 #define TMPL_DEF template<typename C, \ 00021 typename R=Default_radius_type(C), \ 00022 typename V=Ball_variant(C) > 00023 #define TMPL template<typename C,typename R,typename V> 00024 #define Ball ball<C,R,V> 00025 #define Abs_ball ball<Abs_type(C),R,Abs_type(V) > 00026 00027 /****************************************************************************** 00028 * The ball type 00029 ******************************************************************************/ 00030 00031 TMPL_DEF 00032 class ball { 00033 MMX_ALLOCATORS 00034 private: 00035 C c; 00036 R r; 00037 00038 public: 00039 typedef implementation<ball_rounding,V> Rnd; 00040 typedef Round_up(R) Up; 00041 00042 inline ball () {} 00043 template<typename T> ball (const T& c2): 00044 c (as<C> (c2)), r (0) { 00045 Rnd::add_additive_error (*this); } 00046 template<typename CT, typename RT, typename VT> 00047 inline ball (const ball<CT,RT,VT>& z): 00048 c (as<C> (center (z))), r (as<R> (radius (z))) { 00049 XVERIFY (r >= 0, "negative radius", r); 00050 // FIXME: we should pre-correct the radius of z as well 00051 Rnd::add_additive_error (*this); } 00052 inline ball (const C& x): 00053 c (x), r (0) {} 00054 inline ball (const C& c2, const R& r2): 00055 c (c2), r (r2) { 00056 XVERIFY (r >= 0, "negative radius", r); } 00057 inline ball (const C& c2, const R& r2, bool adjust): 00058 c (c2), r (r2) { 00059 XVERIFY (r >= 0, "negative radius", r); 00060 if (adjust) Rnd::add_additive_error (*this); } 00061 inline ball (const Real_type(Ball)& x, const Real_type(Ball)& y): 00062 c (gaussian (center (x), center (y))), 00063 r (Up::hypot (radius (x), radius (y))) { 00064 XVERIFY (r >= 0, "negative radius", r); 00065 Rnd::add_additive_error (*this); } 00066 friend C center LESSGTR (const Ball& z); 00067 friend R radius LESSGTR (const Ball& z); 00068 friend C& center LESSGTR (Ball& z); 00069 friend R& radius LESSGTR (Ball& z); 00070 inline Ball& operator <<= (const xint& shift); 00071 inline Ball& operator >>= (const xint& shift); 00072 }; 00073 00074 template<> struct symbolic_type_information<ball<floating<> > > { 00075 static const nat id= SYMBOLIC_BALL; }; 00076 00077 UNARY_RETURN_TYPE(TMPL,center_op,Ball,C); 00078 UNARY_RETURN_TYPE(TMPL,radius_op,Ball,R); 00079 UNARY_RETURN_TYPE(TMPL,abs_op,Ball,Abs_ball); 00080 TMPL struct rounding_helper<Ball >: public rounding_helper<R> {}; 00081 TMPL struct projective_helper<Ball >: public projective_helper<C> {}; 00082 00083 /****************************************************************************** 00084 * Standard constructors and accessors 00085 ******************************************************************************/ 00086 00087 template<typename C, typename R, typename V, typename C2, typename R2> 00088 struct make_ball_helper<Ball,C2,R2> { 00089 static inline Ball val (const C2& c, const R2& r) { 00090 return Ball (c, r); } 00091 }; 00092 00093 template<typename C, typename R, typename V, typename C2> 00094 struct make_interval_helper<Ball,C2> { 00095 static inline Ball val (const C2& l, const C2& r) { 00096 typedef Round_up(C2) Up; 00097 VERIFY (l <= r, "bad interval"); 00098 C2 cc= decexp2 (l+r, 1); 00099 R rr= next_above (as<R> (max (Up::sub (r, cc), Up::sub (cc, l)))); 00100 return Ball (cc, rr); 00101 } 00102 }; 00103 00104 TMPL inline C center (const Ball& z) { return z.c; } 00105 TMPL inline R radius (const Ball& z) { return z.r; } 00106 TMPL inline C& center (Ball& z) { return z.c; } 00107 TMPL inline R& radius (Ball& z) { return z.r; } 00108 00109 TMPL inline C lower (const Ball& z) { 00110 typedef implementation<ball_rounding,V> Rnd; 00111 return Rnd::lower (z); } 00112 TMPL inline C upper (const Ball& z) { 00113 typedef implementation<ball_rounding,V> Rnd; 00114 return Rnd::upper (z); } 00115 TMPL inline R abs_down (const Ball& z) { 00116 typedef implementation<ball_rounding,V> Rnd; 00117 return Rnd::abs_down (z); } 00118 TMPL inline R abs_up (const Ball& z) { 00119 typedef implementation<ball_rounding,V> Rnd; 00120 return Rnd::abs_up (z); } 00121 TMPL inline R bnd_down (const Ball& z) { 00122 typedef implementation<ball_rounding,V> Rnd; 00123 return Rnd::bnd_down (z); } 00124 TMPL inline R bnd_up (const Ball& z) { 00125 typedef implementation<ball_rounding,V> Rnd; 00126 return Rnd::bnd_up (z); } 00127 00128 /****************************************************************************** 00129 * Basic routines 00130 ******************************************************************************/ 00131 00132 TMPL inline void add_rounding_error (Ball& z) { 00133 typedef implementation<ball_rounding,V> Rnd; 00134 Rnd::add_rounding_error (z); } 00135 TMPL inline void add_additive_error (Ball& z) { 00136 typedef implementation<ball_rounding,V> Rnd; 00137 Rnd::add_additive_error (z); } 00138 TMPL inline void add_multiplicative_error (Ball& z) { 00139 typedef implementation<ball_rounding,V> Rnd; 00140 Rnd::add_multiplicative_error (z); } 00141 TMPL inline void add_elementary_error (Ball& z) { 00142 typedef implementation<ball_rounding,V> Rnd; 00143 Rnd::add_elementary_error (z); } 00144 00145 TMPL inline Ball copy (const Ball& z) { 00146 return Ball (copy (center (z)), copy (radius (z))); } 00147 TMPL inline Ball duplicate (const Ball& z) { 00148 return Ball (duplicate (center (z)), duplicate (radius (z))); } 00149 TMPL inline bool is_exact_zero (const Ball& z) { 00150 return is_exact_zero (center (z)) && is_exact_zero (radius (z)); } 00151 00152 template<typename Op, typename C, typename R, typename V> nat 00153 unary_hash (const Ball& x) { 00154 nat h= Op::op (center (x)); 00155 return (h<<3) ^ (h<<11) ^ (h>>29) ^ Op::op (radius (x)); 00156 } 00157 00158 template<typename Op, typename C, typename R, typename V> bool 00159 binary_test (const Ball& x1, const Ball& x2) { 00160 return Op::op (center (x1), center (x2)) && 00161 Op::op (radius (x1), radius (x2)); 00162 } 00163 00164 EXACT_IDENTITY_OP_SUGAR(TMPL,Ball) 00165 HARD_IDENTITY_OP_SUGAR(TMPL,Ball) 00166 00167 TMPL syntactic 00168 flatten (const Ball& z) { 00169 return syn ("ball", flatten (center (z)), flatten (radius (z))); 00170 } 00171 00172 TMPL syntactic 00173 flatten (const Ball& z, xnat dd) { 00174 return syn ("ball", flatten (center (z), dd), flatten (radius (z), dd)); 00175 } 00176 00177 TMPL syntactic 00178 flatten_range (const Ball& z) { 00179 mmx_local_bit_precision tmp (precision (center (z))); 00180 if (is_nan (z)) return Nan (syntactic); 00181 if (is_fuzz (z)) return Fuzz (syntactic); 00182 if (is_exact_zero (z)) return 0; 00183 return flatten_range (lower (z), upper (z)); 00184 } 00185 00186 TMPL syntactic 00187 flatten_range (const Ball& z, xnat dd) { 00188 mmx_local_bit_precision tmp (precision (center (z))); 00189 if (is_nan (z)) return Nan (syntactic); 00190 if (is_fuzz (z)) return Fuzz (syntactic); 00191 if (is_exact_zero (z)) return 0; 00192 return flatten_range (lower (z), upper (z), dd); 00193 } 00194 00195 template<typename R, typename V> inline syntactic 00196 flatten (const ball<double,R,V>& z) { 00197 return flatten_range (z); } 00198 template<typename R, typename V> inline syntactic 00199 flatten (const ball<double,R,V>& z, xnat dd) { 00200 return flatten_range (z, dd); } 00201 template<typename FV, typename R, typename V> inline syntactic 00202 flatten (const ball<floating<FV>,R,V>& z) { 00203 return flatten_range (z); } 00204 template<typename FV, typename R, typename V> inline syntactic 00205 flatten (const ball<floating<FV>,R,V>& z, xnat dd) { 00206 return flatten_range (z, dd); } 00207 00208 TMPL 00209 struct binary_helper<Ball >: public void_binary_helper<Ball > { 00210 static inline string short_type_name () { 00211 return "Ba" * Short_type_name (C) * Short_type_name (R); } 00212 static inline generic full_type_name () { 00213 return gen ("Ball", Full_type_name (C), Full_type_name (R)); } 00214 static inline generic disassemble (const Ball& z) { 00215 return gen_vec (as<generic> (center (z)), as<generic> (radius (z))); } 00216 static inline Ball assemble (const generic& v) { 00217 return Ball (as<C> (vector_access (v, 0)), 00218 as<R> (vector_access (v, 1))); } 00219 static inline void write (const port& out, const Ball& z) { 00220 binary_write<C> (out, center (z)); 00221 binary_write<R> (out, radius (z)); } 00222 static inline Ball read (const port& in) { 00223 C c= binary_read<C> (in); 00224 R r= binary_read<R> (in); 00225 return Ball (c, r, false); } 00226 }; 00227 00228 template<typename TC, typename TR, typename TV, 00229 typename FC, typename FR, typename FV> inline void 00230 set_as (ball<TC,TR,TV>& r, const ball<FC,FR,FV>& z) { 00231 typedef implementation<ball_rounding,TV> Rnd; 00232 set_as (center (r), center (z)); 00233 set_as (radius (r), radius (z)); 00234 Rnd::add_additive_error (r); 00235 } 00236 00237 template<typename TC, typename TR, typename TV, typename F> inline void 00238 set_as (ball<TC,TR,TV>& r, const F& z) { 00239 typedef implementation<ball_rounding,TV> Rnd; 00240 set_as (center (r), z); 00241 set_as (radius (r), 0); 00242 Rnd::add_additive_error (r); 00243 } 00244 00245 /****************************************************************************** 00246 * Comparisons 00247 ******************************************************************************/ 00248 00249 TMPL inline bool 00250 is_zero (const Ball& z) { 00251 return !is_nan (center (z)) && !is_nan (radius (z)) && 00252 abs_down (z) == 0; 00253 } 00254 00255 TMPL inline bool 00256 is_non_zero (const Ball& z) { 00257 return is_nan (center (z)) || is_nan (radius (z)) || 00258 abs_down (z) != 0; 00259 } 00260 00261 TMPL inline bool 00262 is_negative_or_zero (const Ball& z) { 00263 return !is_nan (center (z)) && bnd_down (z) <= 0; 00264 } 00265 00266 TMPL inline bool 00267 is_negative (const Ball& z) { 00268 return !is_nan (center (z)) && bnd_up (z) < 0; 00269 } 00270 00271 TMPL inline bool 00272 is_positive_or_zero (const Ball& z) { 00273 return !is_nan (center (z)) && bnd_up (z) >= 0; 00274 } 00275 00276 TMPL inline bool 00277 is_positive (const Ball& z) { 00278 return !is_nan (center (z)) && bnd_down (z) > 0; 00279 } 00280 00281 TMPL bool 00282 operator == (const Ball& z1, const Ball& z2) { 00283 if (is_nan (z1) || is_nan (z2)) return is_nan (z1) && is_nan (z2); 00284 Ball d= z1 - z2; 00285 return abs_down (d) == 0; 00286 } 00287 00288 TMPL bool 00289 operator != (const Ball& z1, const Ball& z2) { 00290 if (is_nan (z1) || is_nan (z2)) return !(is_nan (z1) && is_nan (z2)); 00291 Ball d= z1 - z2; 00292 return abs_down (d) != 0; 00293 } 00294 00295 TMPL inline bool 00296 operator <= (const Ball& z1, const Ball& z2) { 00297 return is_negative_or_zero (z1 - z2); 00298 } 00299 00300 TMPL inline bool 00301 operator < (const Ball& z1, const Ball& z2) { 00302 return is_negative (z1 - z2); 00303 } 00304 00305 TMPL inline bool 00306 operator >= (const Ball& z1, const Ball& z2) { 00307 return is_positive_or_zero (z1 - z2); 00308 } 00309 00310 TMPL inline bool 00311 operator > (const Ball& z1, const Ball& z2) { 00312 return is_positive (z1 - z2); 00313 } 00314 00315 TMPL inline bool 00316 included (const Ball& b1, const Ball& b2) { 00317 // returns true if b1 is provably included in b2 00318 return radius (b1 - Ball (center (b2))) <= radius (b2); 00319 } 00320 00321 TMPL nat 00322 hash (const Ball& z) { 00323 (void) z; 00324 // return hash (center (z)); 00325 return 123123123; 00326 } 00327 00328 EQUAL_INT_SUGAR(TMPL,Ball); 00329 COMPARE_INT_SUGAR(TMPL,Ball); 00330 00331 /****************************************************************************** 00332 * Constants 00333 ******************************************************************************/ 00334 00335 TMPL inline void set_nan (Ball& x) { x= Ball (Nan (C), 0); } 00336 TMPL inline void set_maximal (Ball& x) { x= Ball (Maximal (C), 0); } 00337 TMPL inline void set_minimal (Ball& x) { x= Ball (Minimal (C), 0); } 00338 TMPL inline void set_infinity (Ball& x) { x= Ball (Infinity (C), 0); } 00339 TMPL inline void set_fuzz (Ball& x) { x= Ball (0, Infinity (R)); } 00340 TMPL inline void set_smallest (Ball& x) { x= Ball (Smallest (C), 0); } 00341 TMPL inline void set_largest (Ball& x) { x= Ball (Largest (C), 0); } 00342 TMPL inline void set_accuracy (Ball& x) { x= Ball (Accuracy (C), 0); } 00343 TMPL inline void set_log2 (Ball& x) { x= Ball (Log2 (C), 0, true); } 00344 TMPL inline void set_pi (Ball& x) { x= Ball (Pi (C), 0, true); } 00345 TMPL inline void set_euler (Ball& x) { x= Ball (Euler (C), 0, true); } 00346 TMPL inline void set_imaginary (Ball& x) { 00347 x= Ball (Real_type (Ball) (0), Real_type (Ball) (1)); } 00348 TMPL inline Ball times_infinity (const Ball& x) { 00349 return x * infinity_cst<Ball > (); } 00350 00351 /****************************************************************************** 00352 * Basic arithmetic 00353 ******************************************************************************/ 00354 00355 TMPL inline Ball 00356 operator - (const Ball& z) { 00357 typedef implementation<ball_additive,V> Impl; 00358 Ball d; Impl::neg (d, z); return d; 00359 } 00360 00361 TMPL inline Ball 00362 operator + (const Ball& z1, const Ball& z2) { 00363 typedef implementation<ball_additive,V> Impl; 00364 Ball d; Impl::add (d, z1, z2); return d; 00365 } 00366 00367 TMPL inline Ball 00368 operator + (const Ball& z1, const C& z2) { 00369 typedef implementation<ball_additive,V> Impl; 00370 Ball d; Impl::add (d, z1, z2); return d; 00371 } 00372 00373 TMPL inline Ball 00374 operator + (const C& z1, const Ball& z2) { 00375 typedef implementation<ball_additive,V> Impl; 00376 Ball d; Impl::add (d, z1, z2); return d; 00377 } 00378 00379 TMPL inline Ball 00380 operator - (const Ball& z1, const Ball& z2) { 00381 typedef implementation<ball_additive,V> Impl; 00382 Ball d; Impl::sub (d, z1, z2); return d; 00383 } 00384 00385 TMPL inline Ball 00386 operator - (const Ball& z1, const C& z2) { 00387 typedef implementation<ball_additive,V> Impl; 00388 Ball d; Impl::sub (d, z1, z2); return d; 00389 } 00390 00391 TMPL inline Ball 00392 operator - (const C& z1, const Ball& z2) { 00393 typedef implementation<ball_additive,V> Impl; 00394 Ball d; Impl::sub (d, z1, z2); return d; 00395 } 00396 00397 TMPL inline Ball 00398 operator * (const Ball& z1, const Ball& z2) { 00399 typedef implementation<ball_multiplicative,V> Impl; 00400 Ball d; Impl::mul (d, z1, z2); return d; 00401 } 00402 00403 TMPL inline Ball 00404 operator * (const Ball& z1, const C& z2) { 00405 typedef implementation<ball_multiplicative,V> Impl; 00406 Ball d; Impl::mul (d, z1, z2); return d; 00407 } 00408 00409 TMPL inline Ball 00410 operator * (const C& z1, const Ball& z2) { 00411 typedef implementation<ball_multiplicative,V> Impl; 00412 Ball d; Impl::mul (d, z1, z2); return d; 00413 } 00414 00415 TMPL inline Ball 00416 square (const Ball& z) { 00417 typedef implementation<ball_multiplicative,V> Impl; 00418 Ball d; Impl::square (d, z); return d; 00419 } 00420 00421 TMPL inline Ball 00422 invert (const Ball& z) { 00423 typedef implementation<ball_multiplicative,V> Impl; 00424 Ball d; Impl::invert (d, z); return d; 00425 } 00426 00427 TMPL inline Ball 00428 operator / (const Ball& z1, const Ball& z2) { 00429 typedef implementation<ball_multiplicative,V> Impl; 00430 Ball d; Impl::div (d, z1, z2); return d; 00431 } 00432 00433 TMPL inline Ball 00434 operator / (const Ball& z1, const C& z2) { 00435 typedef implementation<ball_multiplicative,V> Impl; 00436 Ball d; Impl::div (d, z1, z2); return d; 00437 } 00438 00439 TMPL inline Ball 00440 operator / (const C& z1, const Ball& z2) { 00441 typedef implementation<ball_multiplicative,V> Impl; 00442 Ball d; Impl::div (d, z1, z2); return d; 00443 } 00444 00445 ARITH_INT_SUGAR(TMPL,Ball); 00446 00447 /****************************************************************************** 00448 * Elementary functions 00449 ******************************************************************************/ 00450 00451 template<typename V> struct ball_complex; 00452 00453 template<typename C, typename Real, typename V> 00454 struct elementary_variant { 00455 typedef ball_complex<V> EV; 00456 }; 00457 00458 template<typename C, typename V> 00459 struct elementary_variant<C,C,V> { 00460 typedef V EV; 00461 }; 00462 00463 #define Elementary_variant(C,V) \ 00464 typename elementary_variant<C,Real_type(C),V>::EV 00465 00466 TMPL inline Ball 00467 sqrt (const Ball& z) { 00468 typedef Elementary_variant(C,V) EV; 00469 typedef implementation<ball_root,EV> Impl; 00470 Ball d; Impl::sqrt (d, z); return d; 00471 } 00472 00473 TMPL inline Ball 00474 hypot (const Ball& x, const Ball& y) { 00475 typedef Elementary_variant(C,V) EV; 00476 typedef implementation<ball_root,EV> Impl; 00477 Ball d; Impl::hypot (d, x, y); return d; 00478 } 00479 00480 TMPL inline Ball 00481 exp (const Ball& z) { 00482 typedef Elementary_variant(C,V) EV; 00483 typedef implementation<ball_elementary,EV> Impl; 00484 Ball d; Impl::exp (d, z); return d; 00485 } 00486 00487 TMPL inline Ball 00488 log (const Ball& z) { 00489 typedef Elementary_variant(C,V) EV; 00490 typedef implementation<ball_elementary,EV> Impl; 00491 Ball d; Impl::log (d, z); return d; 00492 } 00493 00494 TMPL inline Ball 00495 pow (const Ball& z, const Ball& y) { 00496 typedef Elementary_variant(C,V) EV; 00497 typedef implementation<ball_elementary,EV> Impl; 00498 Ball d; Impl::pow (d, z, y); return d; 00499 } 00500 00501 TMPL inline Ball 00502 pow (const Ball& z, const int& y) { 00503 typedef Elementary_variant(C,V) EV; 00504 typedef implementation<ball_elementary,EV> Impl; 00505 Ball d; Impl::pow (d, z, Ball (y)); return d; 00506 } 00507 00508 TMPL inline Ball 00509 pow (const int& z, const Ball& y) { 00510 typedef Elementary_variant(C,V) EV; 00511 typedef implementation<ball_elementary,EV> Impl; 00512 Ball d; Impl::pow (d, Ball (z), y); return d; 00513 } 00514 00515 TMPL inline Ball 00516 cos (const Ball& z) { 00517 typedef Elementary_variant(C,V) EV; 00518 typedef implementation<ball_elementary,EV> Impl; 00519 Ball d; Impl::cos (d, z); return d; 00520 } 00521 00522 TMPL inline Ball 00523 sin (const Ball& z) { 00524 typedef Elementary_variant(C,V) EV; 00525 typedef implementation<ball_elementary,EV> Impl; 00526 Ball d; Impl::sin (d, z); return d; 00527 } 00528 00529 TMPL inline Ball 00530 tan (const Ball& z) { 00531 typedef Elementary_variant(C,V) EV; 00532 typedef implementation<ball_elementary,EV> Impl; 00533 Ball d; Impl::tan (d, z); return d; 00534 } 00535 00536 TMPL inline Ball 00537 cosh (const Ball& z) { 00538 typedef Elementary_variant(C,V) EV; 00539 typedef implementation<ball_elementary,EV> Impl; 00540 Ball d; Impl::cosh (d, z); return d; 00541 } 00542 00543 TMPL inline Ball 00544 sinh (const Ball& z) { 00545 typedef Elementary_variant(C,V) EV; 00546 typedef implementation<ball_elementary,EV> Impl; 00547 Ball d; Impl::sinh (d, z); return d; 00548 } 00549 00550 TMPL inline Ball 00551 tanh (const Ball& z) { 00552 typedef Elementary_variant(C,V) EV; 00553 typedef implementation<ball_elementary,EV> Impl; 00554 Ball d; Impl::tanh (d, z); return d; 00555 } 00556 00557 TMPL inline Ball 00558 acos (const Ball& z) { 00559 typedef Elementary_variant(C,V) EV; 00560 typedef implementation<ball_elementary,EV> Impl; 00561 Ball d; Impl::acos (d, z); return d; 00562 } 00563 00564 TMPL inline Ball 00565 asin (const Ball& z) { 00566 typedef Elementary_variant(C,V) EV; 00567 typedef implementation<ball_elementary,EV> Impl; 00568 Ball d; Impl::asin (d, z); return d; 00569 } 00570 00571 TMPL inline Ball 00572 atan (const Ball& z) { 00573 typedef Elementary_variant(C,V) EV; 00574 typedef implementation<ball_elementary,EV> Impl; 00575 Ball d; Impl::atan (d, z); return d; 00576 } 00577 00578 TMPL inline Ball 00579 atan2 (const Ball& y, const Ball& x) { 00580 typedef Elementary_variant(C,V) EV; 00581 typedef implementation<ball_elementary,EV> Impl; 00582 Ball d; Impl::atan2 (d, y, x); return d; 00583 } 00584 00585 INV_TRIGO_SUGAR(TMPL,Ball) 00586 INV_HYPER_SUGAR(TMPL,Ball) 00587 ARG_HYPER_SUGAR(TMPL,Ball) 00588 00589 /****************************************************************************** 00590 * Other order related functions 00591 ******************************************************************************/ 00592 00593 TMPL inline Abs_ball 00594 abs (const Ball& z) { 00595 typedef implementation<ball_abs,V> Impl; 00596 Abs_ball d; Impl::abs (d, z); return d; 00597 } 00598 00599 TMPL inline Ball 00600 min (const Ball& z1, const Ball& z2) { 00601 typedef implementation<ball_ordered,V> Impl; 00602 Ball d; Impl::min (d, z1, z2); return d; 00603 } 00604 00605 TMPL inline Ball 00606 max (const Ball& z1, const Ball& z2) { 00607 typedef implementation<ball_ordered,V> Impl; 00608 Ball d; Impl::max (d, z1, z2); return d; 00609 } 00610 00611 TMPL inline Ball 00612 floor (const Ball& z) { 00613 typedef implementation<ball_ordered,V> Impl; 00614 Ball d; Impl::floor (d, z); return d; 00615 } 00616 00617 TMPL inline Ball 00618 trunc (const Ball& z) { 00619 typedef implementation<ball_ordered,V> Impl; 00620 Ball d; Impl::trunc (d, z); return d; 00621 } 00622 00623 TMPL inline Ball 00624 ceil (const Ball& z) { 00625 typedef implementation<ball_ordered,V> Impl; 00626 Ball d; Impl::ceil (d, z); return d; 00627 } 00628 00629 TMPL inline Ball 00630 round (const Ball& z) { 00631 typedef implementation<ball_ordered,V> Impl; 00632 Ball d; Impl::round (d, z); return d; 00633 } 00634 00635 /****************************************************************************** 00636 * Floating point related functions 00637 ******************************************************************************/ 00638 00639 TMPL inline bool is_finite (const Ball& z) { 00640 return is_finite (center (z)) && is_finite (radius (z)); } 00641 TMPL inline bool is_infinite (const Ball& z) { 00642 return is_infinite (center (z)) && is_finite (radius (z)); } 00643 TMPL inline bool is_fuzz (const Ball& z) { 00644 return !is_nan (center (z)) && is_infinite (radius (z)); } 00645 TMPL inline bool is_nan (const Ball& z) { 00646 return is_nan (center (z)) || is_nan (radius (z)); } 00647 TMPL inline bool is_reliable (const Ball& z) { 00648 (void) z; return true; } 00649 00650 TMPL inline Ball change_precision (const Ball& z, xnat prec) { 00651 return Ball (change_precision (center (z), prec), radius (z)); } 00652 TMPL inline xnat precision (const Ball& x) { 00653 return precision (center (x)); } 00654 TMPL inline Abs_ball additive_error (const Ball& x) { 00655 return Abs_ball (additive_error (center (x))); } 00656 TMPL inline Abs_ball multiplicative_error (const Ball& x) { 00657 return Abs_ball (multiplicative_error (center (x))); } 00658 TMPL inline Abs_ball elementary_error (const Ball& x) { 00659 return Abs_ball (elementary_error (center (x))); } 00660 00661 TMPL inline xint exponent (const Ball& z) { 00662 return max (exponent (center (z)), exponent (radius (z))); } 00663 TMPL inline double magnitude (const Ball& z) { 00664 return max (magnitude (center (z)), magnitude (radius (z))); } 00665 TMPL inline Ball operator << (const Ball& z, const xint& shift) { 00666 typedef implementation<ball_shift,V> Impl; 00667 Ball d; Impl::shiftl (d, z, shift); return d; } 00668 TMPL inline Ball operator >> (const Ball& z, const xint& shift) { 00669 typedef implementation<ball_shift,V> Impl; 00670 Ball d; Impl::shiftr (d, z, shift); return d; } 00671 TMPL inline Ball& Ball::operator <<= (const xint& shift) { 00672 typedef implementation<ball_shift,V> Impl; 00673 Impl::shiftl (*this, shift); return *this; } 00674 TMPL inline Ball& Ball::operator >>= (const xint& shift) { 00675 typedef implementation<ball_shift,V> Impl; 00676 Impl::shiftr (*this, shift); return *this; } 00677 00678 TMPL inline Ball sharpen (const Ball& z) { 00679 return Ball (center (z)); } 00680 TMPL inline Ball blur (const Ball& z, const R& r) { 00681 typedef Round_up(R) Up; 00682 return Ball (center (z), Up::add (radius (z), r)); } 00683 template<typename C, typename R, typename V, typename K> inline Ball 00684 blur (const Ball& z, const ball<K,R,V>& r) { 00685 typedef Round_up(R) Up; 00686 return Ball (center (z), Up::add (radius (z), abs_up (r))); } 00687 00688 /****************************************************************************** 00689 * Extras for glue 00690 ******************************************************************************/ 00691 00692 #define mmx_ball(R,C) ball<C > 00693 00694 template<typename R, typename C> inline ball<C> 00695 make_mmx_ball (const C& c, const R& r) { 00696 return ball<C> (c, as<Default_radius_type(C) > (r), true); 00697 } 00698 00699 template<typename C> inline ball<C> 00700 make_mmx_ball (const C& c) { 00701 return ball<C> (c, as<Default_radius_type(C) > (promote (0, abs (c)))); 00702 } 00703 00704 template<typename C> inline Abs_type(C) 00705 mmx_radius (const ball<C>& z) { 00706 return as<Abs_type(C) > (radius (z)); 00707 } 00708 00709 #undef TMPL_DEF 00710 #undef TMPL 00711 #undef Ball 00712 #undef Abs_ball 00713 } // namespace mmx 00714 #endif // __MMX_BALL_HPP