numerix_doc 0.4
/Users/mourrain/Devel/mmx/numerix/include/numerix/interval.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : interval.hpp
00004 * DESCRIPTION: Intervals
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_INTERVAL_HPP
00014 #define __MMX_INTERVAL_HPP
00015 #include <basix/function.hpp>
00016 #include <numerix/rounded.hpp>
00017 namespace mmx {
00018 #define TMPL_DEF template<typename C,typename V=std_interval>
00019 #define TMPL template<typename C,typename V>
00020 #define Interval interval<C,V>
00021 #define Up V::template rnd_helper<C>::UV
00022 #define Down V::template rnd_helper<C>::DV
00023 TMPL class interval;
00024 TMPL inline C lower (const Interval& z);
00025 TMPL inline C upper (const Interval& z);
00026 
00027 /******************************************************************************
00028 * Interval variants
00029 ******************************************************************************/
00030 
00031 struct std_interval {
00032   template<typename C>
00033   struct rnd_helper {
00034     typedef Round_up(C) UV;
00035     typedef Round_down(C) DV;
00036   };
00037 };
00038 
00039 /******************************************************************************
00040 * The interval type
00041 ******************************************************************************/
00042 
00043 TMPL_DEF
00044 class interval {
00045 MMX_ALLOCATORS
00046 private:
00047   C l;
00048   C r;
00049 
00050 public:      
00051   typedef C boundary_type;
00052 
00053   inline interval (): l (0), r (0) {}
00054   template<typename T> inline interval (const T& x):
00055     l (Down::template as<C> (x)),
00056     r (Up::template as<C> (x)) {}
00057   template<typename T> inline interval (const interval<T,V>& x):
00058     l (Down::template as<C> (lower (x))),
00059     r (Up::template as<C> (upper (x))) {}
00060   template<typename LT,typename UT> inline
00061   interval (const LT& l2, const UT& u2):
00062     l (Down::template as<C> (l2)),
00063     r (Up::template as<C> (u2)) {}
00064   inline interval (const C& x): l (x), r (x) {}
00065   inline interval (const C& l2, const C& r2): l (l2), r (r2) {}
00066   friend C lower LESSGTR (const Interval& x);
00067   friend C upper LESSGTR (const Interval& x);
00068 
00069   static inline Interval nan ();
00070   static inline Interval maximal ();
00071   static inline Interval minimal ();
00072   static inline Interval infinity ();
00073   static inline Interval fuzzy ();
00074   static inline Interval log2 ();
00075   static inline Interval pi ();
00076   static inline Interval euler ();
00077 
00078   inline Interval& operator += (const Interval& x);
00079   inline Interval& operator -= (const Interval& x);
00080   inline Interval& operator <<= (const xint& shift);
00081   inline Interval& operator >>= (const xint& shift);
00082 };
00083 DEFINE_UNARY_FORMAT_1 (interval)
00084 
00085 UNARY_RETURN_TYPE(TMPL,center_op,Interval,C);
00086 UNARY_RETURN_TYPE(TMPL,radius_op,Interval,C);
00087 TMPL struct rounding_helper<Interval >: public rounding_helper<C> {};
00088 
00089 /******************************************************************************
00090 * Standard constructors and accessors
00091 ******************************************************************************/
00092 
00093 template<typename C, typename V, typename C2, typename R2>
00094 struct make_ball_helper<Interval,C2,R2> {
00095   static inline Interval val (const C2& c, const R2& r) {
00096     typedef Round_up(C2) Rnd_Up;
00097     typedef Round_down(C2) Rnd_Down;
00098     return Interval (Rnd_Down::template sub_as<C2> (c, r),
00099                      Rnd_Up::template add_as<C2> (c, r));
00100   }
00101 };
00102 
00103 template<typename C, typename V, typename C2>
00104 struct make_interval_helper<Interval,C2> {
00105   static inline Interval val (const C2& l, const C2& r) {
00106     return Interval (l, r); }
00107 };
00108 
00109 TMPL inline C lower (const Interval& x) { return x.l; }
00110 TMPL inline C upper (const Interval& x) { return x.r; }
00111 TMPL inline C center (const Interval& x) {
00112   return decexp2 (lower (x) + upper (x)); }
00113 TMPL inline C radius (const Interval& x) {
00114   if (is_infinite (x)) return 0;
00115   return Up::add (decexp2 (Up::sub (upper (x), lower (x))),
00116                   multiplicative_error (center (x))); }
00117 TMPL inline format<C> CF (const Interval& x) {
00118   return get_format (lower (x)); }
00119 
00120 TMPL inline Interval abs (const Interval& x);
00121 TMPL inline C abs_down (const Interval& x) { return lower (abs (x)); }
00122 TMPL inline C abs_up (const Interval& x) { return upper (abs (x)); }
00123 TMPL inline C bnd_down (const Interval& x) { return lower (x); }
00124 TMPL inline C bnd_up (const Interval& x) { return upper (x); }
00125 
00126 /******************************************************************************
00127 * Basic routines
00128 ******************************************************************************/
00129 
00130 TMPL inline Interval copy (const Interval& x) {
00131   return Interval (copy (lower (x)), copy (upper (x))); }
00132 TMPL inline Interval duplicate (const Interval& x) {
00133   return Interval (duplicate (lower (x)), duplicate (upper (x))); }
00134 
00135 TMPL inline bool is_exact_zero (const Interval& x) {
00136   return is_exact_zero (lower (x)) && is_exact_zero (upper (x)); }
00137 
00138 template<typename Op, typename C, typename V> nat
00139 unary_hash (const Interval& x) {
00140   nat h= Op::op (lower (x));
00141   return (h<<3) ^ (h<<15) ^ (h>>29) ^ Op::op (upper (x));
00142 }
00143 
00144 template<typename Op, typename C, typename V> bool
00145 binary_test (const Interval& x1, const Interval& x2) {
00146   return Op::op (lower (x1), lower (x2)) && Op::op (upper (x1), upper (x2));
00147 }
00148 
00149 template<typename S1, typename D> interval<D>
00150 map (const function_1<D,Argument(S1) >& fun, const interval<S1>& x) {
00151   return interval<D> (fun (lower (x)), fun (upper (x)));
00152 }
00153 
00154 template<typename S1, typename D> interval<D>
00155 map (D (*fun) (const S1&), const interval<S1>& x) {
00156   return interval<D> (fun (lower (x)), fun (upper (x)));
00157 }
00158 
00159 EXACT_IDENTITY_OP_SUGAR(TMPL,Interval)
00160 HARD_IDENTITY_OP_SUGAR(TMPL,Interval)
00161 TMPL nat hash (const Interval& x) { return 12721; }
00162 
00163 TMPL syntactic
00164 flatten (const Interval& x) {
00165   if (is_nan (x)) return Nan (syntactic);
00166   if (lower (x) == 0 && upper (x) == 0) return 0;
00167   return flatten_range (lower (x), upper (x));
00168   // return flatten ("interval", lower (x), upper (x));
00169 }
00170 
00171 TMPL syntactic
00172 flatten (const Interval& x, xnat dd) {
00173   if (is_nan (x)) return Nan (syntactic);
00174   if (lower (x) == 0 && upper (x) == 0) return 0;
00175   return flatten_range (lower (x), upper (x), dd);
00176 }
00177 
00178 TMPL
00179 struct binary_helper<Interval >: public void_binary_helper<Interval > {
00180   static inline string short_type_name () {
00181     return "I" * Short_type_name (C); }
00182   static inline generic full_type_name () {
00183     return gen ("Interval", Full_type_name (C)); }
00184   static inline generic disassemble (const Interval& x) {
00185     return gen_vec (as<generic> (lower (x)), as<generic> (upper (x))); }
00186   static inline Interval assemble (const generic& v) {
00187     return Interval (as<C> (vector_access (v, 0)),
00188                      as<C> (vector_access (v, 1))); }
00189   static inline void write (const port& out, const Interval& x) {
00190     binary_write<C> (out, lower (x));
00191     binary_write<C> (out, upper (x)); }
00192   static inline Interval read (const port& in) {
00193     C l= binary_read<C> (in);
00194     C r= binary_read<C> (in);
00195     return Interval (l, r); }
00196 };
00197 
00198 /******************************************************************************
00199 * Comparisons
00200 ******************************************************************************/
00201 
00202 TMPL inline bool
00203 intersect (Interval& r, const Interval &a, const Interval &b) {
00204   if ((upper (a) < lower (b)) || (lower (a) > upper (b))) return false;
00205   r = Interval (max (lower (a), lower (b)), min (upper (a), upper (b)));
00206   return true;
00207 }
00208 
00209 TMPL inline bool
00210 is_zero (const Interval& x) {
00211   return is_finite (x) && sign (lower (x)) * sign (upper (x)) <= 0;
00212 }
00213 
00214 TMPL inline bool
00215 is_non_zero (const Interval& x) {
00216   return !is_finite (x) || sign (lower (x)) * sign (upper (x)) > 0;
00217 }
00218 
00219 TMPL inline bool
00220 operator == (const Interval& x1, const Interval& x2) {
00221   if (is_nan (x1) || is_nan (x2)) return is_nan (x1) && is_nan (x2);
00222   return lower (x1) <= upper (x2) && lower (x2) <= upper (x1);
00223 }
00224 
00225 TMPL inline bool
00226 operator != (const Interval& x1, const Interval& x2) {
00227   if (is_nan (x1) || is_nan (x2)) return !(is_nan (x1) && is_nan (x2));
00228   return lower (x1) > upper (x2) || lower (x2) > upper (x1);
00229 }
00230 
00231 TMPL inline bool
00232 operator <= (const Interval& x1, const Interval& x2) {
00233   if (is_nan (x1) || is_nan (x2)) return false;
00234   return lower (x1) <= upper (x2);
00235 }
00236 
00237 TMPL inline bool
00238 operator < (const Interval& x1, const Interval& x2) {
00239   if (is_nan (x1) || is_nan (x2)) return false;
00240   return lower (x2) > upper (x1);
00241 }
00242 
00243 TMPL inline bool
00244 operator >= (const Interval& x1, const Interval& x2) {
00245   if (is_nan (x1) || is_nan (x2)) return false;
00246   return lower (x2) <= upper (x1);
00247 }
00248 
00249 TMPL inline bool
00250 operator > (const Interval& x1, const Interval& x2) {
00251   if (is_nan (x1) || is_nan (x2)) return false;
00252   return lower (x1) > upper (x2);
00253 }
00254 
00255 EQUAL_INT_SUGAR(TMPL,Interval);
00256 COMPARE_INT_SUGAR(TMPL,Interval);
00257 
00258 /******************************************************************************
00259 * Other order related functions
00260 ******************************************************************************/
00261 
00262 TMPL inline Interval
00263 abs (const Interval& x) {
00264   if (is_nan (x)) return x;
00265   C r= max (abs (lower (x)), abs (upper (x)));
00266   if (sign (lower (x)) * sign (upper (x)) <= 0) return Interval (C(0), r);
00267   return Interval (min (abs (lower (x)), abs (upper (x))), r);
00268 }
00269 
00270 TMPL Interval
00271 min (const Interval& x1, const Interval& x2) {
00272   return Interval (min (lower (x1), lower (x2)), min (upper (x1), upper (x2)));
00273 }
00274 
00275 TMPL Interval
00276 max (const Interval& x1, const Interval& x2) {
00277   return Interval (max (lower (x1), lower (x2)), max (upper (x1), upper (x2)));
00278 }
00279 
00280 TMPL Interval
00281 floor (const Interval& x) {
00282   return Interval (Down::floor (lower (x)), Up::floor (upper (x)));
00283 }
00284 
00285 TMPL Interval
00286 trunc (const Interval& x) {
00287   return Interval (Down::trunc (lower (x)), Up::trunc (upper (x)));
00288 }
00289 
00290 TMPL Interval
00291 ceil (const Interval& x) {
00292   return Interval (Down::ceil (lower (x)), Up::ceil (upper (x)));
00293 }
00294 
00295 TMPL Interval
00296 round (const Interval& x) {
00297   return Interval (Down::round (lower (x)), Up::round (upper (x)));
00298 }
00299 
00300 /******************************************************************************
00301 * Constants
00302 ******************************************************************************/
00303 
00304 TMPL inline void set_nan (Interval& x) {
00305   x= Interval (Nan (C), Nan (C)); }
00306 TMPL inline void set_maximal (Interval& x) {
00307   x= Interval (Maximal (C), Maximal (C)); }
00308 TMPL inline void set_minimal (Interval& x) {
00309   x= Interval (Minimal (C), Minimal (C)); }
00310 TMPL inline void set_infinity (Interval& x) {
00311   x= Interval (Infinity (C), Infinity (C)); }
00312 TMPL inline void set_fuzz (Interval& x) {
00313   x= Interval (Minimal (C), Maximal (C)); }
00314 TMPL inline void set_smallest (Interval& x) {
00315   x= Interval (Smallest (C), Smallest (C)); }
00316 TMPL inline void set_largest (Interval& x) {
00317   x= Interval (Largest (C), Largest (C)); }
00318 TMPL inline void set_accuracy (Interval& x) {
00319   x= Interval (Accuracy (C), Accuracy (C)); }
00320 TMPL inline void set_log2 (Interval& x) {
00321   x= Interval (Down::template log2<C>(), Up::template log2<C>()); }
00322 TMPL inline void set_pi (Interval& x) {
00323   x= Interval (Down::template pi<C>(), Up::template pi<C>()); }
00324 TMPL inline void set_euler (Interval& x) {
00325   x= Interval (Down::template euler<C>(), Up::template euler<C>()); }
00326 TMPL inline void set_catalan (Interval& x) {
00327   x= Interval (Down::template catalan<C>(), Up::template catalan<C>()); }
00328 TMPL inline Interval times_infinity (const Interval& x) {
00329   return x * infinity_cst<Interval > (); }
00330 
00331 /******************************************************************************
00332 * Basic arithmetic
00333 ******************************************************************************/
00334 
00335 TMPL inline Interval
00336 operator - (const Interval& x) {
00337   return Interval (-upper (x), -lower (x));
00338 }
00339 
00340 TMPL inline Interval
00341 operator + (const Interval& x1, const Interval& x2) {
00342   return Interval (Down::add (lower (x1), lower (x2)),
00343                    Up::add (upper (x1), upper (x2)));
00344 }
00345 
00346 TMPL inline Interval
00347 operator + (const Interval& x1, const C& x2) {
00348   return Interval (Down::add (lower (x1), x2), Up::add (upper (x1), x2));
00349 }
00350 
00351 TMPL inline Interval
00352 operator + (const C& x1, const Interval& x2) {
00353   return Interval (Down::add (x1, lower (x2)), Up::add (x1, upper (x2)));
00354 }
00355 
00356 TMPL inline Interval
00357 operator - (const Interval& x1, const Interval& x2) {
00358   return Interval (Down::sub (lower (x1), upper (x2)),
00359                    Up::sub (upper (x1), lower (x2)));
00360 }
00361 
00362 TMPL inline Interval
00363 operator - (const Interval& x1, const C& x2) {
00364   return Interval (Down::add (lower (x1), x2), Up::add (upper (x1), x2));
00365 }
00366 
00367 TMPL inline Interval
00368 operator - (const C& x1, const Interval& x2) {
00369   return Interval (Down::add (x1, upper (x2)), Up::add (x1, lower (x2)));
00370 }
00371 
00372 TMPL Interval
00373 operator * (const Interval& x1, const Interval& x2) {
00374   if (lower (x1) >= 0)
00375     return Interval (lower (x2) >= 0?
00376                      Down::mul (lower (x1), lower (x2)):
00377                      Down::mul (upper (x1), lower (x2)),
00378                      upper (x2) >= 0?
00379                      Up::mul (upper (x1), upper (x2)):
00380                      Up::mul (lower (x1), upper (x2)));
00381   else if (upper (x1) <= 0)
00382     return Interval (upper (x2) >= 0?
00383                      Down::mul (lower (x1), upper (x2)):
00384                      Down::mul (upper (x1), upper (x2)),
00385                      lower (x2) >= 0?
00386                      Up::mul (upper (x1), lower (x2)):
00387                      Up::mul (lower (x1), lower (x2)));
00388   else if (lower (x2) >= 0)
00389     return Interval (Down::mul (lower (x1), upper (x2)),
00390                      Up::mul (upper (x1), upper (x2)));
00391   else if (upper (x2) <= 0)
00392     return Interval (Down::mul (upper (x1), lower (x2)),
00393                      Up::mul (lower (x1), lower (x2)));
00394   else
00395     return Interval (min (Down::mul (lower (x1), upper (x2)),
00396                           Down::mul (upper (x1), lower (x2))),
00397                      max (Up::mul (lower (x1), lower (x2)),
00398                           Up::mul (upper (x1), upper (x2))));
00399 }
00400 
00401 TMPL inline Interval operator * (const Interval& x1, const C& x2) {
00402   return x1 * Interval (x2); }
00403 TMPL inline Interval operator * (const C& x1, const Interval& x2) {
00404   return Interval (x1) * x2; }
00405 
00406 TMPL inline Interval
00407 square (const Interval& x) {
00408   if (lower (x) >= 0)
00409     return Interval (Down::mul (lower (x), lower (x)),
00410                      Up::mul (upper (x), upper (x)));
00411   else if (upper (x) <= 0)
00412     return Interval (Down::mul (upper (x), upper (x)),
00413                      Up::mul (lower (x), lower (x)));
00414   else return Interval (Down::mul (lower (x), upper (x)),
00415                         max (Up::mul (lower (x), lower (x)),
00416                              Up::mul (upper (x), upper (x))));
00417 }
00418 
00419 TMPL Interval
00420 operator / (const Interval& x1, const Interval& x2) {
00421   if (is_zero (x2)) return Nan (Interval);
00422   else if (lower (x2) > 0)
00423     return Interval (lower (x1) > 0?
00424                      Down::div (lower (x1), upper (x2)):
00425                      Down::div (lower (x1), lower (x2)),
00426                      upper (x1) > 0?
00427                      Up::div (upper (x1), lower (x2)):
00428                      Up::div (upper (x1), upper (x2)));
00429   else if (upper (x2) < 0)
00430     return Interval (upper (x1) > 0?
00431                      Down::div (upper (x1), upper (x2)):
00432                      Down::div (upper (x1), lower (x2)),
00433                      lower (x1) > 0?
00434                      Up::div (lower (x1), lower (x2)):
00435                      Up::div (lower (x1), upper (x2)));
00436   else return Nan (Interval);
00437 }
00438 
00439 TMPL inline Interval operator / (const Interval& x1, const C& x2) {
00440   return x1 / Interval (x2); }
00441 TMPL inline Interval operator / (const C& x1, const Interval& x2) {
00442   return Interval (x1) / x2; }
00443 
00444 ARITH_INT_SUGAR(TMPL,Interval);
00445 
00446 /******************************************************************************
00447 * In place arithmetic operations
00448 ******************************************************************************/
00449 
00450 TMPL inline Interval&
00451 Interval::operator += (const Interval& x) {
00452   l= Down::add (l, lower (x));
00453   r= Up::add (r, upper (x));
00454   return *this;
00455 }
00456 
00457 TMPL inline Interval&
00458 Interval::operator -= (const Interval& x) {
00459   l= Down::sub (l, upper (x));
00460   r= Up::sub (r, lower (x));
00461   return *this;
00462 }
00463 
00464 /******************************************************************************
00465 * Elementary functions
00466 ******************************************************************************/
00467 
00468 TMPL Interval
00469 sqrt (const Interval& x) {
00470   return Interval (Down::sqrt (lower (x)), Up::sqrt (upper (x)));
00471 }
00472 
00473 TMPL Interval
00474 hypot (const Interval& x, const Interval& y) {
00475   Interval z= square (x) + square (y);
00476   if (z > 0) return sqrt (z);
00477   else return Interval (0, Up::sqrt (upper (z)));
00478 }
00479 
00480 TMPL Interval
00481 exp (const Interval& x) {
00482   return Interval (Down::exp (lower (x)), Up::exp (upper (x)));
00483 }
00484 
00485 TMPL Interval
00486 log (const Interval& x) {
00487   return Interval (Down::log (lower (x)), Up::log (upper (x)));
00488 }
00489 
00490 TMPL inline Interval
00491 pow (const Interval& x, const Interval& y) {
00492   return exp (y * log (x));
00493 }
00494 
00495 TMPL Interval
00496 cos (const Interval& x) {
00497   C pi_lo= promote (314159, lower (x)) / promote (100000, lower (x));
00498   if (Up::sub (upper (x), lower (x)) >= pi_lo)
00499     return Interval (promote (-1, lower (x)), promote (1, lower (x)));
00500   else {
00501     int s1= -sign (sin (lower (x)));
00502     int s2= -sign (sin (upper (x)));
00503     if (s1 >= 0 && s2 >= 0)
00504       return Interval (Down::cos (lower (x)), Up::cos (upper (x)));
00505     else if (s1 <= 0 && s2 <= 0)
00506       return Interval (Down::cos (upper (x)), Down::cos (lower (x)));
00507     else if (s1 >= 0)
00508       return Interval (min (Down::cos (lower (x)), Down::cos (upper (x))),
00509                        promote (1, lower (x)));
00510     else
00511       return Interval (promote (-1, lower (x)),
00512                        max (Down::cos (lower (x)), Down::cos (upper (x))));
00513   }
00514 }
00515 
00516 TMPL Interval
00517 sin (const Interval& x) {
00518   C pi_lo= promote (314159, lower (x)) / promote (100000, lower (x));
00519   if (Up::sub (upper (x), lower (x)) >= pi_lo)
00520     return Interval (promote (-1, lower (x)), promote (1, lower (x)));
00521   else {
00522     int s1= sign (cos (lower (x)));
00523     int s2= sign (cos (upper (x)));
00524     if (s1 >= 0 && s2 >= 0)
00525       return Interval (Down::sin (lower (x)), Up::sin (upper (x)));
00526     else if (s1 <= 0 && s2 <= 0)
00527       return Interval (Down::sin (upper (x)), Down::sin (lower (x)));
00528     else if (s1 >= 0)
00529       return Interval (min (Down::sin (lower (x)), Down::sin (upper (x))),
00530                        promote (1, lower (x)));
00531     else
00532       return Interval (promote (-1, lower (x)),
00533                        max (Down::sin (lower (x)), Down::sin (upper (x))));
00534   }
00535 }
00536 
00537 TMPL Interval
00538 tan (const Interval& x) {
00539   return sin (x) / cos (x);
00540 }
00541 
00542 TMPL inline Interval
00543 cosh (const Interval& x) {
00544   if (is_nan (x)) return Nan (Interval);
00545   else if (lower (x) >= 0)
00546     return Interval (Down::cosh (lower (x)), Up::cosh (upper (x)));
00547   else if (upper (x) <= 0)
00548     return Interval (Down::cosh (upper (x)), Up::cosh (lower (x)));
00549   else return Interval (1, max (Up::cosh (lower (x)), Up::cosh (upper (x))));
00550 }
00551 
00552 TMPL inline Interval
00553 sinh (const Interval& x) {
00554   return Interval (Down::sinh (lower (x)), Up::sinh (upper (x)));
00555 }
00556 
00557 TMPL Interval
00558 tanh (const Interval& x) {
00559   return sinh (x) / cosh (x);
00560 }
00561 
00562 TMPL Interval
00563 acos (const Interval& x) {
00564   return Interval (Down::acos (upper (x)), Up::acos (lower (x)));
00565 }
00566 
00567 TMPL Interval
00568 asin (const Interval& x) {
00569   return Interval (Down::asin (lower (x)), Up::asin (upper (x)));
00570 }
00571 
00572 TMPL Interval
00573 atan (const Interval& x) {
00574   return Interval (Down::atan (lower (x)), Up::atan (upper (x)));
00575 }
00576 
00577 TMPL Interval
00578 atan2 (const Interval& y, const Interval& x) {
00579   if (sign (lower (x)) > 0) return atan (y/x);
00580   if (sign (lower (y)) > 0) return atan (-x/y) + (Pi (Interval) >> 1);
00581   if (sign (upper (y)) < 0) return atan (-x/y) - (Pi (Interval) >> 1);
00582   if (sign (upper (x)) < 0) return atan (y/x) + Pi (Interval);
00583   C pi= Up::template pi<C> ();
00584   return Interval (-pi, pi);
00585 }
00586 
00587 INV_TRIGO_SUGAR(TMPL,Interval)
00588 INV_HYPER_SUGAR(TMPL,Interval)
00589 ARG_HYPER_SUGAR(TMPL,Interval)
00590 
00591 /******************************************************************************
00592 * Floating point related functions
00593 ******************************************************************************/
00594 
00595 TMPL inline bool is_finite (const Interval& x) {
00596   return is_finite (lower (x)) && is_finite (upper (x)); }
00597 TMPL inline bool is_infinite (const Interval& x) {
00598   return is_infinite (lower (x)) && upper (x) == lower (x); }
00599 TMPL inline bool is_fuzz (const Interval& x) {
00600   return is_infinite (lower (x)) && is_infinite (upper (x)) &&
00601     lower (x) != upper (x); }
00602 TMPL inline bool is_nan (const Interval& x) {
00603   return is_nan (lower (x)) || is_nan (upper (x)); }
00604 TMPL inline bool is_reliable (const Interval& x) {
00605   (void) x; return true; }
00606 
00607 TMPL inline Interval change_precision (const Interval& x, xnat prec) {
00608   return Interval (change_precision (lower (x), prec),
00609                    change_precision (upper (x), prec)); }
00610 TMPL inline xnat precision (const Interval& x) {
00611   return min (precision (lower (x)), precision (upper (x))); }
00612 
00613 TMPL inline xint exponent (const Interval& x) {
00614   return max (exponent (lower (x)), exponent (upper (x))); }
00615 TMPL inline double magnitude (const Interval& x) {
00616   return max (magnitude (lower (x)), magnitude (upper (x))); }
00617 TMPL inline Interval operator << (const Interval& x, const xint& shift) {
00618   return Interval (incexp2 (lower (x), shift), incexp2 (upper (x), shift)); }
00619 TMPL inline Interval operator >> (const Interval& x, const xint& shift) {
00620   return Interval (decexp2 (lower (x), shift), decexp2 (upper (x), shift)); }
00621 
00622 TMPL inline Interval&
00623 Interval::operator <<= (const xint& shift) {
00624   incexp2_assign (l, shift);
00625   incexp2_assign (r, shift);
00626   return *this;
00627 }
00628 
00629 TMPL inline Interval&
00630 Interval::operator >>= (const xint& shift) {
00631   decexp2_assign (l, shift);
00632   decexp2_assign (r, shift);
00633   return *this;
00634 }
00635 
00636 TMPL inline Interval sharpen (const Interval& x) {
00637   return Interval (center (x)); }
00638 TMPL inline Interval blur (const Interval& x, const C& r) {
00639   return x + Interval (-r, r); }
00640 TMPL inline Interval blur (const Interval& x, const Interval& r) {
00641   return blur (x, abs_up (r)); }
00642 
00643 #undef TMPL_DEF
00644 #undef TMPL
00645 #undef Interval
00646 #undef Up
00647 #undef Down
00648 } // namespace mmx
00649 #endif // __MMX_INTERVAL_HPP
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines