BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Interval_nt.h
Go to the documentation of this file.
00001 // Copyright (c) 1998-2005,2007  Utrecht University (The Netherlands),
00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria),
00005 // and Tel-Aviv University (Israel).  All rights reserved.
00006 //
00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public License as
00009 // published by the Free Software Foundation; version 2.1 of the License.
00010 // See the file LICENSE.LGPL distributed with CGAL.
00011 //
00012 // Licensees holding a valid commercial license may use this file in
00013 // accordance with the commercial license agreement provided with the software.
00014 //
00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 //
00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Number_types/include/CGAL/Interval_nt.h $
00019 // $Id: Interval_nt.h 49525 2009-05-22 15:02:08Z spion $
00020 //
00021 //
00022 // Author(s)     : Sylvain Pion, Michael Hemmer
00023 
00024 #ifndef CGAL_INTERVAL_NT_H
00025 #define CGAL_INTERVAL_NT_H
00026 
00027 // This file contains the description of the following classes:
00028 // - Interval_nt<false>  It's a number type that needs the FPU rounding mode
00029 //                       to be set to +inf.  It is also typedef'd to
00030 //                       Interval_nt_advanced for backward compatibility.
00031 // - Interval_nt<true>   Same but it does the rounding mode itself so you
00032 //                       don't have to worry about it.  But it's slower.
00033 //
00034 // Note: When rounding is towards +infinity, to make an operation rounded
00035 // towards -infinity, it's enough to take the opposite of some of the operand,
00036 // and the opposite of the result (see operator+, operator*,...).
00037 
00038 // TODO : 
00039 // - test whether stopping constant propagation only in functions taking
00040 //   double as arguments, improves performance.
00041 
00042 #include <CGAL/number_type_basic.h>
00043 #include <CGAL/Uncertain.h>
00044 #include <iostream>
00045 
00046 CGAL_BEGIN_NAMESPACE
00047 
00048 template <bool Protected = true>
00049 class Interval_nt
00050 {
00051   typedef Interval_nt<Protected>     IA;
00052   typedef std::pair<double, double>  Pair;
00053 
00054 public:
00055 
00056   typedef double      value_type;
00057 
00058   typedef Uncertain_conversion_exception            unsafe_comparison;
00059   typedef Checked_protect_FPU_rounding<Protected>   Internal_protector;
00060   typedef Protect_FPU_rounding<!Protected>          Protector;
00061 
00062   Interval_nt()
00063 #ifndef CGAL_NO_ASSERTIONS
00064       : _inf(1), _sup(0)
00065              // to early and deterministically detect use of uninitialized
00066 #endif
00067     {}
00068 
00069   Interval_nt(int i)
00070     : _inf(i), _sup(i) {}
00071 
00072   Interval_nt(double d)
00073     : _inf(d), _sup(d) { CGAL_assertion(is_finite(d)); }
00074 
00075 // The Intel compiler on Linux is aggressive with constant propagation and
00076 // it seems there is no flag to stop it, so disable this check for it.
00077 #if !defined(CGAL_DISABLE_ROUNDING_MATH_CHECK) && \
00078     defined(__INTEL_COMPILER) && defined(__linux)
00079 #  define CGAL_DISABLE_ROUNDING_MATH_CHECK
00080 #endif
00081 
00082   Interval_nt(double i, double s)
00083     : _inf(i), _sup(s)
00084   {
00085       // VC++ should use instead : (i<=s) || !is_valid(i) || !is_valid(s)
00086       // Or should I use is_valid() ? or is_valid_or_nan() ?
00087     CGAL_assertion_msg(!(i>s),
00088               " Variable used before being initialized (or CGAL bug)");
00089 #ifndef CGAL_DISABLE_ROUNDING_MATH_CHECK
00090     CGAL_assertion_code((void) tester;) // Necessary to trigger a runtime test of rounding modes.
00091 #endif
00092   }
00093 
00094   Interval_nt(const Pair & p)
00095     : _inf(p.first), _sup(p.second) {}
00096 
00097   IA operator-() const { return IA (-sup(), -inf()); }
00098 
00099   IA & operator+= (const IA &d) { return *this = *this + d; }
00100   IA & operator-= (const IA &d) { return *this = *this - d; }
00101   IA & operator*= (const IA &d) { return *this = *this * d; }
00102   IA & operator/= (const IA &d) { return *this = *this / d; }
00103 
00104   bool is_point() const
00105   {
00106     return sup() == inf();
00107   }
00108 
00109   bool is_same (const IA & d) const
00110   {
00111     return inf() == d.inf() && sup() == d.sup();
00112   }
00113 
00114   bool do_overlap (const IA & d) const
00115   {
00116     return !(d.inf() > sup() || d.sup() < inf());
00117   }
00118 
00119   const double & inf() const { return _inf; }
00120   const double & sup() const { return _sup; }
00121 
00122   std::pair<double, double> pair() const
00123   {
00124     return std::pair<double, double>(_inf, _sup);
00125   }
00126 
00127   static IA largest()
00128   {
00129     return IA(-CGALi::infinity, CGALi::infinity);
00130   }
00131 
00132   static IA smallest()
00133   {
00134     return IA(-CGAL_IA_MIN_DOUBLE, CGAL_IA_MIN_DOUBLE);
00135   }
00136 
00137 #if 0 // def CGAL_HISTOGRAM_PROFILER  // not yet ready
00138   ~Interval_nt()
00139   {
00140     CGAL_HISTOGRAM_PROFILER("[Interval_nt relative precision in log2 scale]",
00141                              (unsigned) ( ::log(relative_precision(*this))) / ::log(2.0) )  );
00142   }
00143 #endif
00144 
00145 private:
00146   // Pair inf_sup;
00147   double _inf, _sup;
00148 
00149   struct Test_runtime_rounding_modes {
00150     Test_runtime_rounding_modes()
00151     {
00152       // We test whether GCC's -frounding-math option has been forgotten.
00153       // The macros CGAL_IA_MUL and CGAL_IA_DIV stop constant propagation only
00154       // on the second argument, so if -fno-rounding-math, the compiler optimizes
00155       // the 2 negations and we get wrong rounding.
00156       typename Interval_nt<>::Internal_protector P;
00157       CGAL_assertion_msg(-CGAL_IA_MUL(-1.1, 10.1) != CGAL_IA_MUL(1.1, 10.1),
00158                          "Wrong rounding: did you forget the -frounding-math option if you use GCC?");
00159       CGAL_assertion_msg(-CGAL_IA_DIV(-1, 10) != CGAL_IA_DIV(1, 10),
00160                          "Wrong rounding: did you forget the -frounding-math option if you use GCC?");
00161     }
00162   };
00163 
00164 #ifndef CGAL_DISABLE_ROUNDING_MATH_CHECK
00165   static Test_runtime_rounding_modes tester;
00166 #endif
00167 };
00168 
00169 #ifndef CGAL_DISABLE_ROUNDING_MATH_CHECK
00170 template <bool Protected>
00171 typename Interval_nt<Protected>::Test_runtime_rounding_modes
00172 Interval_nt<Protected>::tester;
00173 #endif
00174 
00175 template <bool Protected>
00176 inline
00177 Uncertain<bool>
00178 operator<(const Interval_nt<Protected> &a, const Interval_nt<Protected> &b)
00179 {
00180   if (a.sup()  < b.inf()) return true;
00181   if (a.inf() >= b.sup()) return false;
00182   return Uncertain<bool>::indeterminate();
00183 }
00184 
00185 template <bool Protected>
00186 inline
00187 Uncertain<bool>
00188 operator>(const Interval_nt<Protected> &a, const Interval_nt<Protected> &b)
00189 { return b < a; }
00190 
00191 template <bool Protected>
00192 inline
00193 Uncertain<bool>
00194 operator<=(const Interval_nt<Protected> &a, const Interval_nt<Protected> &b)
00195 {
00196   if (a.sup() <= b.inf()) return true;
00197   if (a.inf() >  b.sup()) return false;
00198   return Uncertain<bool>::indeterminate();
00199 }
00200 
00201 template <bool Protected>
00202 inline
00203 Uncertain<bool>
00204 operator>=(const Interval_nt<Protected> &a, const Interval_nt<Protected> &b)
00205 { return b <= a; }
00206 
00207 template <bool Protected>
00208 inline
00209 Uncertain<bool>
00210 operator==(const Interval_nt<Protected> &a, const Interval_nt<Protected> &b)
00211 {
00212   if (b.inf() >  a.sup() || b.sup() <  a.inf()) return false;
00213   if (b.inf() == a.sup() && b.sup() == a.inf()) return true;
00214   return Uncertain<bool>::indeterminate();
00215 }
00216 
00217 template <bool Protected>
00218 inline
00219 Uncertain<bool>
00220 operator!=(const Interval_nt<Protected> &a, const Interval_nt<Protected> &b)
00221 { return ! (a == b); }
00222 
00223 
00224 // Mixed operators with int.
00225 
00226 template <bool Protected>
00227 inline
00228 Uncertain<bool>
00229 operator<(int a, const Interval_nt<Protected> &b)
00230 {
00231   if (a < b.inf()) return true;
00232   if (a >= b.sup()) return false;
00233   return Uncertain<bool>::indeterminate();
00234 }
00235 
00236 template <bool Protected>
00237 inline
00238 Uncertain<bool>
00239 operator>(int a, const Interval_nt<Protected> &b)
00240 { return b < a; }
00241 
00242 template <bool Protected>
00243 inline
00244 Uncertain<bool>
00245 operator<=(int a, const Interval_nt<Protected> &b)
00246 {
00247   if (a <= b.inf()) return true;
00248   if (a >  b.sup()) return false;
00249   return Uncertain<bool>::indeterminate();
00250 }
00251 
00252 template <bool Protected>
00253 inline
00254 Uncertain<bool>
00255 operator>=(int a, const Interval_nt<Protected> &b)
00256 { return b <= a; }
00257 
00258 template <bool Protected>
00259 inline
00260 Uncertain<bool>
00261 operator==(int a, const Interval_nt<Protected> &b)
00262 {
00263   if (b.inf() >  a || b.sup() <  a) return false;
00264   if (b.inf() == a && b.sup() == a) return true;
00265   return Uncertain<bool>::indeterminate();
00266 }
00267 
00268 template <bool Protected>
00269 inline
00270 Uncertain<bool>
00271 operator!=(int a, const Interval_nt<Protected> &b)
00272 { return ! (a == b); }
00273 
00274 template <bool Protected>
00275 inline
00276 Uncertain<bool>
00277 operator<(const Interval_nt<Protected> &a, int b)
00278 {
00279   if (a.sup()  < b) return true;
00280   if (a.inf() >= b) return false;
00281   return Uncertain<bool>::indeterminate();
00282 }
00283 
00284 template <bool Protected>
00285 inline
00286 Uncertain<bool>
00287 operator>(const Interval_nt<Protected> &a, int b)
00288 { return b < a; }
00289 
00290 template <bool Protected>
00291 inline
00292 Uncertain<bool>
00293 operator<=(const Interval_nt<Protected> &a, int b)
00294 {
00295   if (a.sup() <= b) return true;
00296   if (a.inf() >  b) return false;
00297   return Uncertain<bool>::indeterminate();
00298 }
00299 
00300 template <bool Protected>
00301 inline
00302 Uncertain<bool>
00303 operator>=(const Interval_nt<Protected> &a, int b)
00304 { return b <= a; }
00305 
00306 template <bool Protected>
00307 inline
00308 Uncertain<bool>
00309 operator==(const Interval_nt<Protected> &a, int b)
00310 {
00311   if (b >  a.sup() || b <  a.inf()) return false;
00312   if (b == a.sup() && b == a.inf()) return true;
00313   return Uncertain<bool>::indeterminate();
00314 }
00315 
00316 template <bool Protected>
00317 inline
00318 Uncertain<bool>
00319 operator!=(const Interval_nt<Protected> &a, int b)
00320 { return ! (a == b); }
00321 
00322 
00323 // Mixed operators with double.
00324 
00325 template <bool Protected>
00326 inline
00327 Uncertain<bool>
00328 operator<(double a, const Interval_nt<Protected> &b)
00329 {
00330   if (a < b.inf()) return true;
00331   if (a >= b.sup()) return false;
00332   return Uncertain<bool>::indeterminate();
00333 }
00334 
00335 template <bool Protected>
00336 inline
00337 Uncertain<bool>
00338 operator>(double a, const Interval_nt<Protected> &b)
00339 { return b < a; }
00340 
00341 template <bool Protected>
00342 inline
00343 Uncertain<bool>
00344 operator<=(double a, const Interval_nt<Protected> &b)
00345 {
00346   if (a <= b.inf()) return true;
00347   if (a >  b.sup()) return false;
00348   return Uncertain<bool>::indeterminate();
00349 }
00350 
00351 template <bool Protected>
00352 inline
00353 Uncertain<bool>
00354 operator>=(double a, const Interval_nt<Protected> &b)
00355 { return b <= a; }
00356 
00357 template <bool Protected>
00358 inline
00359 Uncertain<bool>
00360 operator==(double a, const Interval_nt<Protected> &b)
00361 {
00362   if (b.inf() >  a || b.sup() <  a) return false;
00363   if (b.inf() == a && b.sup() == a) return true;
00364   return Uncertain<bool>::indeterminate();
00365 }
00366 
00367 template <bool Protected>
00368 inline
00369 Uncertain<bool>
00370 operator!=(double a, const Interval_nt<Protected> &b)
00371 { return ! (a == b); }
00372 
00373 template <bool Protected>
00374 inline
00375 Uncertain<bool>
00376 operator<(const Interval_nt<Protected> &a, double b)
00377 {
00378   if (a.sup()  < b) return true;
00379   if (a.inf() >= b) return false;
00380   return Uncertain<bool>::indeterminate();
00381 }
00382 
00383 template <bool Protected>
00384 inline
00385 Uncertain<bool>
00386 operator>(const Interval_nt<Protected> &a, double b)
00387 { return b < a; }
00388 
00389 template <bool Protected>
00390 inline
00391 Uncertain<bool>
00392 operator<=(const Interval_nt<Protected> &a, double b)
00393 {
00394   if (a.sup() <= b) return true;
00395   if (a.inf() >  b) return false;
00396   return Uncertain<bool>::indeterminate();
00397 }
00398 
00399 template <bool Protected>
00400 inline
00401 Uncertain<bool>
00402 operator>=(const Interval_nt<Protected> &a, double b)
00403 { return b <= a; }
00404 
00405 template <bool Protected>
00406 inline
00407 Uncertain<bool>
00408 operator==(const Interval_nt<Protected> &a, double b)
00409 {
00410   if (b >  a.sup() || b <  a.inf()) return false;
00411   if (b == a.sup() && b == a.inf()) return true;
00412   return Uncertain<bool>::indeterminate();
00413 }
00414 
00415 template <bool Protected>
00416 inline
00417 Uncertain<bool>
00418 operator!=(const Interval_nt<Protected> &a, double b)
00419 { return ! (a == b); }
00420 
00421 
00422 
00423 // Non-documented
00424 // Returns true if the interval is a unique representable double.
00425 template <bool Protected>
00426 inline
00427 bool
00428 fit_in_double (const Interval_nt<Protected> & d, double &r)
00429 {
00430   bool b = d.is_point();
00431   if (b)
00432     r = d.inf();
00433   return b;
00434 }
00435 
00436 // Non-documented
00437 template <bool Protected>
00438 inline
00439 bool
00440 is_singleton (const Interval_nt<Protected> & d)
00441 {
00442   return d.is_point();
00443 }
00444 
00445 // Non-documented
00446 template <bool Protected>
00447 inline
00448 double
00449 magnitude (const Interval_nt<Protected> & d)
00450 {
00451   return (std::max)(std::fabs(d.inf()), std::fabs(d.sup()));
00452 }
00453 
00454 // Non-documented
00455 template <bool Protected>
00456 inline
00457 double
00458 width (const Interval_nt<Protected> & d)
00459 {
00460   return d.sup() - d.inf();
00461 }
00462 
00463 // Non-documented
00464 template <bool Protected>
00465 inline
00466 double
00467 radius (const Interval_nt<Protected> & d)
00468 {
00469   return width(d)/2; // This could be improved to avoid overflow.
00470 }
00471 
00472 // Non-documented
00473 // This is the relative precision of to_double() (the center of the interval),
00474 // hence we use radius() instead of width().
00475 template <bool Protected>
00476 inline
00477 bool
00478 has_smaller_relative_precision(const Interval_nt<Protected> & d, double prec)
00479 {
00480   return magnitude(d) == 0 || radius(d) < prec * magnitude(d);
00481 }
00482 
00483 // Non-documented
00484 template <bool Protected>
00485 double
00486 relative_precision(const Interval_nt<Protected> & d)
00487 {
00488   if (magnitude(d) == 0.0)
00489     return 0.0;
00490   return radius(d) / magnitude(d);
00491 }
00492 
00493 
00494 template< bool Protected >
00495 class Is_valid< Interval_nt<Protected> >
00496   : public std::unary_function< Interval_nt<Protected>, bool > {
00497   public :
00498     bool operator()( const Interval_nt<Protected>& x ) const {
00499       return is_valid(x.inf()) &&
00500              is_valid(x.sup()) &&
00501              x.inf() <= x.sup();
00502     }
00503 };
00504 
00505 template <bool Protected>
00506 std::ostream & operator<< (std::ostream &os, const Interval_nt<Protected> & I )
00507 {
00508   return os << "[" << I.inf() << ";" << I.sup() << "]";
00509 }
00510 
00511 #define CGAL_SWALLOW(IS,CHAR)                           \
00512     {                                                   \
00513         char c;                                         \
00514         do c = is.get(); while (isspace(c));            \
00515         if (c != CHAR) {                                \
00516             is.setstate(std::ios_base::failbit);        \
00517         }                                               \
00518     }                                                   \
00519 
00520 template <bool Protected>
00521 std::istream & operator>> (std::istream &is, Interval_nt<Protected> & I)
00522 {
00523     char c;
00524     do c = is.get(); while (isspace(c));
00525     is.putback(c);
00526     if(c == '['){ // read original output from operator <<
00527         double inf,sup;
00528         CGAL_SWALLOW(is, '[');// read the "["
00529         is >> iformat(inf);
00530         CGAL_SWALLOW(is, ';');// read the ";"
00531         is >> iformat(sup);
00532         CGAL_SWALLOW(is, ']');// read the "]"
00533         I = Interval_nt<Protected>(inf,sup);
00534     }else{ //read double (backward compatibility)
00535         double d;
00536         is >> d;
00537         I = d;
00538     }
00539     return is;
00540 }
00541 #undef CGAL_SWALLOW
00542 
00543 typedef Interval_nt<false> Interval_nt_advanced;  // for backward-compatibility
00544 
00545 
00546 template <bool Protected>
00547 inline
00548 Interval_nt<Protected>
00549 operator+ (const Interval_nt<Protected> &a, const Interval_nt<Protected> & b)
00550 {
00551   typename Interval_nt<Protected>::Internal_protector P;
00552   return Interval_nt<Protected> (-CGAL_IA_SUB(-a.inf(), b.inf()),
00553                                   CGAL_IA_ADD(a.sup(), b.sup()));
00554 }
00555 
00556 template <bool Protected>
00557 inline
00558 Interval_nt<Protected>
00559 operator+ (double a, const Interval_nt<Protected> & b)
00560 {
00561   return Interval_nt<Protected>(a)+b;
00562 }
00563 
00564 template <bool Protected>
00565 inline
00566 Interval_nt<Protected>
00567 operator+ (const Interval_nt<Protected> & a, double b)
00568 {
00569   return a+Interval_nt<Protected>(b);
00570 }
00571 
00572 template <bool Protected>
00573 inline
00574 Interval_nt<Protected>
00575 operator+ (int a, const Interval_nt<Protected> & b)
00576 {
00577   return Interval_nt<Protected>(a)+b;
00578 }
00579 
00580 template <bool Protected>
00581 inline
00582 Interval_nt<Protected>
00583 operator+ (const Interval_nt<Protected> & a, int b)
00584 {
00585   return a+Interval_nt<Protected>(b);
00586 }
00587 
00588 template< bool Protected >
00589 inline
00590 Interval_nt<Protected>
00591 operator+( const Interval_nt<Protected>& a ) {
00592   return a;
00593 }
00594 
00595 template <bool Protected>
00596 inline
00597 Interval_nt<Protected>
00598 operator- (const Interval_nt<Protected> &a, const Interval_nt<Protected> & b)
00599 {
00600   typename Interval_nt<Protected>::Internal_protector P;
00601   return Interval_nt<Protected>(-CGAL_IA_SUB(b.sup(), a.inf()),
00602                                  CGAL_IA_SUB(a.sup(), b.inf()));
00603 }
00604 
00605 template <bool Protected>
00606 inline
00607 Interval_nt<Protected>
00608 operator- (double a, const Interval_nt<Protected> & b)
00609 {
00610   return Interval_nt<Protected>(a)-b;
00611 }
00612 
00613 template <bool Protected>
00614 inline
00615 Interval_nt<Protected>
00616 operator- (const Interval_nt<Protected> & a, double b)
00617 {
00618   return a-Interval_nt<Protected>(b);
00619 }
00620 
00621 template <bool Protected>
00622 inline
00623 Interval_nt<Protected>
00624 operator- (int a, const Interval_nt<Protected> & b)
00625 {
00626   return Interval_nt<Protected>(a)-b;
00627 }
00628 
00629 template <bool Protected>
00630 inline
00631 Interval_nt<Protected>
00632 operator- (const Interval_nt<Protected> & a, int b)
00633 {
00634   return a-Interval_nt<Protected>(b);
00635 }
00636 
00637 template <bool Protected>
00638 inline
00639 Interval_nt<Protected>
00640 operator* (const Interval_nt<Protected> &a, const Interval_nt<Protected> & b)
00641 {
00642   typedef Interval_nt<Protected> IA;
00643   typename Interval_nt<Protected>::Internal_protector P;
00644   if (a.inf() >= 0.0)                                   // e>=0
00645   {
00646     // b>=0     [a.inf()*b.inf(); a.sup()*b.sup()]
00647     // b<=0     [a.sup()*b.inf(); a.inf()*b.sup()]
00648     // b~=0     [a.sup()*b.inf(); a.sup()*b.sup()]
00649     double aa = a.inf(), bb = a.sup();
00650     if (b.inf() < 0.0)
00651     {
00652         aa = bb;
00653         if (b.sup() < 0.0)
00654             bb = a.inf();
00655     }
00656     return IA(-CGAL_IA_MUL(aa, -b.inf()), CGAL_IA_MUL(bb, b.sup()));
00657   }
00658   else if (a.sup()<=0.0)                                // e<=0
00659   {
00660     // b>=0     [a.inf()*b.sup(); a.sup()*b.inf()]
00661     // b<=0     [a.sup()*b.sup(); a.inf()*b.inf()]
00662     // b~=0     [a.inf()*b.sup(); a.inf()*b.inf()]
00663     double aa = a.sup(), bb = a.inf();
00664     if (b.inf() < 0.0)
00665     {
00666         aa=bb;
00667         if (b.sup() < 0.0)
00668             bb=a.sup();
00669     }
00670     return IA(-CGAL_IA_MUL(bb, -b.sup()), CGAL_IA_MUL(aa, b.inf()));
00671   }
00672   else                                          // 0 \in [inf();sup()]
00673   {
00674     if (b.inf()>=0.0)                           // d>=0
00675       return IA(-CGAL_IA_MUL(a.inf(), -b.sup()),
00676                  CGAL_IA_MUL(a.sup(), b.sup()));
00677     if (b.sup()<=0.0)                           // d<=0
00678       return IA(-CGAL_IA_MUL(a.sup(), -b.inf()),
00679                  CGAL_IA_MUL(a.inf(), b.inf()));
00680                                                 // 0 \in d
00681     double tmp1 = CGAL_IA_MUL(a.inf(), -b.sup());
00682     double tmp2 = CGAL_IA_MUL(a.sup(), -b.inf());
00683     double tmp3 = CGAL_IA_MUL(a.inf(),  b.inf());
00684     double tmp4 = CGAL_IA_MUL(a.sup(),  b.sup());
00685     return IA(-(std::max)(tmp1,tmp2), (std::max)(tmp3,tmp4));
00686   }
00687 }
00688 
00689 template <bool Protected>
00690 inline
00691 Interval_nt<Protected>
00692 operator* (double a, const Interval_nt<Protected> & b)
00693 {
00694   return Interval_nt<Protected>(a)*b;
00695 }
00696 
00697 template <bool Protected>
00698 inline
00699 Interval_nt<Protected>
00700 operator* (const Interval_nt<Protected> & a, double b)
00701 {
00702   return a*Interval_nt<Protected>(b);
00703 }
00704 
00705 template <bool Protected>
00706 inline
00707 Interval_nt<Protected>
00708 operator* (int a, const Interval_nt<Protected> & b)
00709 {
00710   return Interval_nt<Protected>(a)*b;
00711 }
00712 
00713 template <bool Protected>
00714 inline
00715 Interval_nt<Protected>
00716 operator* (const Interval_nt<Protected> & a, int b)
00717 {
00718   return a*Interval_nt<Protected>(b);
00719 }
00720 
00721 template <bool Protected>
00722 inline
00723 Interval_nt<Protected>
00724 operator/ (const Interval_nt<Protected> &a, const Interval_nt<Protected> & b)
00725 {
00726   typedef Interval_nt<Protected> IA;
00727   typename Interval_nt<Protected>::Internal_protector P;
00728   if (b.inf() > 0.0)                            // b>0
00729   {
00730     // e>=0     [a.inf()/b.sup(); a.sup()/b.inf()]
00731     // e<=0     [a.inf()/b.inf(); a.sup()/b.sup()]
00732     // e~=0     [a.inf()/b.inf(); a.sup()/b.inf()]
00733     double aa = b.sup(), bb = b.inf();
00734     if (a.inf() < 0.0)
00735     {
00736         aa = bb;
00737         if (a.sup() < 0.0)
00738             bb = b.sup();
00739     }
00740     return IA(-CGAL_IA_DIV(a.inf(), -aa), CGAL_IA_DIV(a.sup(), bb));
00741   }
00742   else if (b.sup()<0.0)                 // b<0
00743   {
00744     // e>=0     [a.sup()/b.sup(); a.inf()/b.inf()]
00745     // e<=0     [a.sup()/b.inf(); a.inf()/b.sup()]
00746     // e~=0     [a.sup()/b.sup(); a.inf()/b.sup()]
00747     double aa = b.sup(), bb = b.inf();
00748     if (a.inf() < 0.0)
00749     {
00750         bb = aa;
00751         if (a.sup() < 0.0)
00752             aa = b.inf();
00753     }
00754     return IA(-CGAL_IA_DIV(a.sup(), -aa), CGAL_IA_DIV(a.inf(), bb));
00755   }
00756   else                                  // b~0
00757     return IA::largest();
00758            // We could do slightly better -> [0;infinity] when b.sup()==0,
00759            // but is this worth ?
00760 }
00761 
00762 template <bool Protected>
00763 inline
00764 Interval_nt<Protected>
00765 operator/ (double a, const Interval_nt<Protected> & b)
00766 {
00767   return Interval_nt<Protected>(a)/b;
00768 }
00769 
00770 template <bool Protected>
00771 inline
00772 Interval_nt<Protected>
00773 operator/ (const Interval_nt<Protected> & a, double b)
00774 {
00775   return a/Interval_nt<Protected>(b);
00776 }
00777 
00778 template <bool Protected>
00779 inline
00780 Interval_nt<Protected>
00781 operator/ (int a, const Interval_nt<Protected> & b)
00782 {
00783   return Interval_nt<Protected>(a)/b;
00784 }
00785 
00786 template <bool Protected>
00787 inline
00788 Interval_nt<Protected>
00789 operator/ (const Interval_nt<Protected> & a, int b)
00790 {
00791   return a/Interval_nt<Protected>(b);
00792 }
00793 
00794 // TODO: What about these two guys? Where do they belong to?
00795 template <bool Protected>
00796 struct Min <Interval_nt<Protected> >
00797     : public std::binary_function<Interval_nt<Protected>,
00798                              Interval_nt<Protected>,
00799                              Interval_nt<Protected> >
00800 {
00801     Interval_nt<Protected> operator()( const Interval_nt<Protected>& d,
00802                                        const Interval_nt<Protected>& e) const
00803     {
00804         return Interval_nt<Protected>(
00805                 (std::min)(d.inf(), e.inf()),
00806                 (std::min)(d.sup(), e.sup()));
00807     }
00808 };
00809 
00810 template <bool Protected>
00811 struct Max <Interval_nt<Protected> >
00812     : public std::binary_function<Interval_nt<Protected>,
00813                              Interval_nt<Protected>,
00814                              Interval_nt<Protected> >
00815 {
00816     Interval_nt<Protected> operator()( const Interval_nt<Protected>& d,
00817                                        const Interval_nt<Protected>& e) const
00818     {
00819         return Interval_nt<Protected>(
00820                 (std::max)(d.inf(), e.inf()),
00821                 (std::max)(d.sup(), e.sup()));
00822     }
00823 };
00824 
00825 template<bool Protected> inline 
00826 Interval_nt<Protected> min BOOST_PREVENT_MACRO_SUBSTITUTION(
00827 const Interval_nt<Protected> & x,
00828 const Interval_nt<Protected> & y){
00829   return CGAL::Min<Interval_nt<Protected> > ()(x,y);
00830 }
00831 template<bool Protected> inline 
00832 Interval_nt<Protected> max BOOST_PREVENT_MACRO_SUBSTITUTION(
00833 const Interval_nt<Protected> & x,
00834 const Interval_nt<Protected> & y){
00835   return CGAL::Max<Interval_nt<Protected> > ()(x,y);
00836 }
00837 
00838 
00839 
00840 // TODO : document, when we are OK with the interface.
00841 // - should it allow other number types for the exponent ?
00842 template < bool b >
00843 Interval_nt<b>
00844 ldexp(const Interval_nt<b> &i, int e)
00845 {
00846   double scale = std::ldexp(1.0, e);
00847   Interval_nt<b> scale_interval (
00848                       CGAL_NTS is_finite(scale) ? scale : CGAL_IA_MAX_DOUBLE,
00849                       scale == 0 ? CGAL_IA_MIN_DOUBLE : scale);
00850   return i * scale_interval;
00851 }
00852 
00853 
00854 // We also specialize some corresponding functors returning Uncertain<>.
00855 
00856 // TODO: To which concept do these functors belong? Can we remove them??
00857 template < bool b >
00858 struct Equal_to < Interval_nt<b>, Interval_nt<b> >
00859   : public std::binary_function< Interval_nt<b>, Interval_nt<b>, Uncertain<bool> >
00860 {
00861   Uncertain<bool> operator()( const Interval_nt<b>& x,
00862                               const Interval_nt<b>& y) const
00863   { return x == y; }
00864 };
00865 
00866 template < bool b >
00867 struct Not_equal_to < Interval_nt<b>, Interval_nt<b> >
00868   : public std::binary_function< Interval_nt<b>, Interval_nt<b>, Uncertain<bool> >
00869 {
00870   Uncertain<bool> operator()( const Interval_nt<b>& x,
00871                               const Interval_nt<b>& y) const
00872   { return x != y; }
00873 };
00874 
00875 template < bool b >
00876 struct Greater < Interval_nt<b>, Interval_nt<b> >
00877   : public std::binary_function< Interval_nt<b>, Interval_nt<b>, Uncertain<bool> >
00878 {
00879   Uncertain<bool> operator()( const Interval_nt<b>& x,
00880                               const Interval_nt<b>& y) const
00881   { return x > y; }
00882 };
00883 
00884 template < bool b >
00885 struct Less < Interval_nt<b>, Interval_nt<b> >
00886   : public std::binary_function< Interval_nt<b>, Interval_nt<b>, Uncertain<bool> >
00887 {
00888   Uncertain<bool> operator()( const Interval_nt<b>& x,
00889                               const Interval_nt<b>& y) const
00890   { return x < y; }
00891 };
00892 
00893 template < bool b >
00894 struct Greater_equal < Interval_nt<b>, Interval_nt<b> >
00895   : public std::binary_function< Interval_nt<b>, Interval_nt<b>, Uncertain<bool> >
00896 {
00897   Uncertain<bool> operator()( const Interval_nt<b>& x,
00898                               const Interval_nt<b>& y) const
00899   { return x >= y; }
00900 };
00901 
00902 template < bool b >
00903 struct Less_equal < Interval_nt<b>, Interval_nt<b> >
00904   : public std::binary_function< Interval_nt<b>, Interval_nt<b>, Uncertain<bool> >
00905 {
00906   Uncertain<bool> operator()( const Interval_nt<b>& x,
00907                               const Interval_nt<b>& y) const
00908   { return x <= y; }
00909 };
00910 
00911 
00912 // As in MP_float.h, the namespace INTERN_INTERVAL_NT contains (now) global
00913 // functions like square or sqrt which would have collided with the new
00914 // global functions from AST/RET
00915 //
00916 // TODO: IMHO, a better solution would be to put the INTERN_MP_FLOAT-functions
00917 //       into the MP_Float-class... But there is surely a reason why this is not
00918 //       the case..?
00919 
00920 
00921 namespace INTERN_INTERVAL_NT {
00922 
00923   template <bool Protected>
00924   inline
00925   double
00926   to_double (const Interval_nt<Protected> & d)
00927   {
00928     return (d.sup() + d.inf()) * 0.5;
00929     // This may overflow...
00930   }
00931 
00932   template <bool Protected>
00933   inline
00934   std::pair<double, double>
00935   to_interval (const Interval_nt<Protected> & d)
00936   {
00937     return d.pair();
00938   }
00939 
00940   template <bool Protected>
00941   inline
00942   Interval_nt<Protected>
00943   sqrt (const Interval_nt<Protected> & d)
00944   {
00945     typename Interval_nt<Protected>::Internal_protector P;  // not optimal here.
00946     // sqrt([+a,+b]) => [sqrt(+a);sqrt(+b)]
00947     // sqrt([-a,+b]) => [0;sqrt(+b)] => assumes roundoff error.
00948     // sqrt([-a,-b]) => [0;sqrt(-b)] => assumes user bug (unspecified result).
00949     FPU_set_cw(CGAL_FE_DOWNWARD);
00950     double i = (d.inf() > 0.0) ? CGAL_IA_SQRT(d.inf()) : 0.0;
00951     FPU_set_cw(CGAL_FE_UPWARD);
00952     return Interval_nt<Protected>(i, CGAL_IA_SQRT(d.sup()));
00953   }
00954 
00955   template <bool Protected>
00956   inline
00957   Interval_nt<Protected>
00958   square (const Interval_nt<Protected> & d)
00959   {
00960     typename Interval_nt<Protected>::Internal_protector P;
00961     if (d.inf()>=0.0)
00962         return Interval_nt<Protected>(-CGAL_IA_MUL(d.inf(), -d.inf()),
00963                                  CGAL_IA_MUL(d.sup(), d.sup()));
00964     if (d.sup()<=0.0)
00965         return Interval_nt<Protected>(-CGAL_IA_MUL(d.sup(), -d.sup()),
00966                                CGAL_IA_MUL(d.inf(), d.inf()));
00967     return Interval_nt<Protected>(0.0, CGAL_IA_SQUARE((std::max)(-d.inf(),
00968                      d.sup())));
00969   }
00970 
00971   template <bool Protected>
00972   inline
00973   Interval_nt<Protected>
00974   abs (const Interval_nt<Protected> & d)
00975   {
00976     if (d.inf() >= 0.0) return d;
00977     if (d.sup() <= 0.0) return -d;
00978     return Interval_nt<Protected>(0.0, (std::max)(-d.inf(), d.sup()));
00979   }
00980 
00981   template <bool Protected>
00982   inline
00983   Uncertain<Sign>
00984   sign (const Interval_nt<Protected> & d)
00985   {
00986     if (d.inf() > 0.0) return POSITIVE;
00987     if (d.sup() < 0.0) return NEGATIVE;
00988     if (d.inf() == d.sup()) return ZERO;
00989     return Uncertain<Sign>::indeterminate();
00990   }
00991 
00992   template <bool Protected>
00993   inline
00994   Uncertain<Comparison_result>
00995   compare (const Interval_nt<Protected> & d, const Interval_nt<Protected> & e)
00996   {
00997     if (d.inf() > e.sup()) return LARGER;
00998     if (e.inf() > d.sup()) return SMALLER;
00999     if (e.inf() == d.sup() && d.inf() == e.sup()) return EQUAL;
01000     return Uncertain<Comparison_result>::indeterminate();
01001   }
01002 
01003   template <bool Protected>
01004   inline
01005   Uncertain<bool>
01006   is_zero (const Interval_nt<Protected> & d)
01007   {
01008     if (d.inf() > 0.0) return false;
01009     if (d.sup() < 0.0) return false;
01010     if (d.inf() == d.sup()) return true;
01011     return Uncertain<bool>::indeterminate();
01012   }
01013 
01014   template <bool Protected>
01015   inline
01016   Uncertain<bool>
01017   is_one (const Interval_nt<Protected> & d)
01018   {
01019     if (d.inf() > 1) return false;
01020     if (d.sup() < 1) return false;
01021     if (d.inf() == d.sup()) return true;
01022     return Uncertain<bool>::indeterminate();
01023   }
01024 
01025   template <bool Protected>
01026   inline
01027   Uncertain<bool>
01028   is_positive (const Interval_nt<Protected> & d)
01029   {
01030     if (d.inf() > 0.0) return true;
01031     if (d.sup() <= 0.0) return false;
01032     return Uncertain<bool>::indeterminate();
01033   }
01034 
01035   template <bool Protected>
01036   inline
01037   Uncertain<bool>
01038   is_negative (const Interval_nt<Protected> & d)
01039   {
01040     if (d.inf() >= 0.0) return false;
01041     if (d.sup() < 0.0) return true;
01042     return Uncertain<bool>::indeterminate();
01043   }
01044 
01045  // TODO: Whats this for? Why is this in this file??
01046   inline
01047   std::pair<double, double>
01048   to_interval (const long & l)
01049   {
01050     if (sizeof(double) > sizeof(long)) {
01051       // On 64bit platforms, a long doesn't fit exactly in a double.
01052       // Well, a perfect fix would be to use std::numeric_limits<>, but...
01053       Protect_FPU_rounding<true> P(CGAL_FE_TONEAREST);
01054       Interval_nt<false> approx ((double) l);
01055       FPU_set_cw(CGAL_FE_UPWARD);
01056       approx += Interval_nt<false>::smallest();
01057       return approx.pair();
01058     }
01059     else
01060       return std::pair<double,double>(l,l);
01061   }
01062 } // namespace INTERN_INTERVAL_NT
01063 
01064 
01065 template< bool B > class Real_embeddable_traits< Interval_nt<B> >
01066   : public INTERN_RET::Real_embeddable_traits_base< Interval_nt<B> , CGAL::Tag_true> {
01067   public:
01068     typedef Interval_nt<B>  Type;
01069   typedef Uncertain<CGAL::Sign> Sign;
01070   typedef Uncertain<bool> Boolean;
01071   typedef Uncertain<CGAL::Comparison_result> Comparison_result; 
01072 
01073     class Abs
01074       : public std::unary_function< Type, Type > {
01075       public:
01076         Type operator()( const Type& x ) const {
01077             return INTERN_INTERVAL_NT::abs( x );
01078         }
01079     };
01080 
01081     class Sgn
01082         : public std::unary_function< Type, Uncertain< ::CGAL::Sign > > {
01083       public:
01084         Uncertain< ::CGAL::Sign > operator()( const Type& x ) const {
01085             return INTERN_INTERVAL_NT::sign( x );
01086         }
01087     };
01088 
01089     class Is_positive
01090       : public std::unary_function< Type, Uncertain<bool> > {
01091       public:
01092         Uncertain<bool> operator()( const Type& x ) const {
01093           return INTERN_INTERVAL_NT::is_positive( x );
01094         }
01095     };
01096 
01097     class Is_negative
01098       : public std::unary_function< Type, Uncertain<bool> > {
01099       public:
01100         Uncertain<bool> operator()( const Type& x ) const {
01101           return INTERN_INTERVAL_NT::is_negative( x );
01102         }
01103     };
01104 
01105     class Compare
01106       : public std::binary_function< Type, Type, Comparison_result > {
01107       public:
01108       Comparison_result operator()( const Type& x, const Type& y ) const {
01109         return INTERN_INTERVAL_NT::compare( x, y );
01110       }
01111       CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR_WITH_RT( Type,
01112           Comparison_result )
01113     };
01114 
01115     class To_double
01116       : public std::unary_function< Type, double > {
01117       public:
01118         double operator()( const Type& x ) const {
01119             return INTERN_INTERVAL_NT::to_double( x );
01120         }
01121     };
01122 
01123     class To_interval
01124       : public std::unary_function< Type, std::pair< double, double > > {
01125       public:
01126         std::pair<double, double> operator()( const Type& x ) const {
01127             return INTERN_INTERVAL_NT::to_interval( x );
01128         }
01129     };
01130 
01131     class Is_finite
01132       : public std::unary_function< Type, Boolean > {
01133       public :
01134         Boolean operator()( const Type& x ) const {
01135           return CGAL_NTS is_finite( x.inf() ) && CGAL_NTS is_finite( x.sup() );
01136         }
01137     };
01138 
01139 };
01140 
01141 // Algebraic structure traits
01142 template< bool B >
01143 class Algebraic_structure_traits< Interval_nt<B> >
01144   : public Algebraic_structure_traits_base< Interval_nt<B>,
01145                                             Field_with_sqrt_tag >  {
01146   public:
01147     typedef Interval_nt<B>      Type;
01148     typedef Tag_false           Is_exact;
01149     typedef Tag_true            Is_numerical_sensitive;
01150     typedef Uncertain<bool>     Boolean; 
01151 
01152     class Is_zero
01153       : public std::unary_function< Type, Boolean > {
01154       public:
01155         Boolean operator()( const Type& x ) const {
01156           return INTERN_INTERVAL_NT::is_zero( x );
01157         }
01158     };
01159 
01160     class Is_one
01161       : public std::unary_function< Type, Boolean > {
01162       public:
01163         Boolean operator()( const Type& x ) const {
01164           return INTERN_INTERVAL_NT::is_one( x );
01165         }
01166     };
01167 
01168     class Square
01169       : public std::unary_function< Type, Type > {
01170       public:
01171         Type operator()( const Type& x ) const {
01172           return INTERN_INTERVAL_NT::square( x );
01173         }
01174     };
01175 
01176     class Sqrt
01177       : public std::unary_function< Type, Type > {
01178       public:
01179         Type operator()( const Type& x ) const {
01180           return INTERN_INTERVAL_NT::sqrt( x );
01181         }
01182     };
01183 
01184     struct Is_square
01185         :public std::binary_function<Interval_nt<B>,Interval_nt<B>&,Boolean >
01186     {
01187         Boolean operator()(const Interval_nt<B>& x) const {
01188             return INTERN_INTERVAL_NT::is_positive( x );
01189         }
01190 
01191         Boolean operator()(
01192                 const Interval_nt<B>& x,
01193                 Interval_nt<B>      & result) const {
01194             Boolean is_positive = INTERN_INTERVAL_NT::is_positive( x );
01195             if ( is_positive.inf() == true ){
01196                 typename Algebraic_structure_traits<Interval_nt<B> >::Sqrt sqrt;
01197                 result = sqrt(x);
01198             }else{
01199                 typename Real_embeddable_traits<Interval_nt<B> >::Abs  abs;
01200                 typename Algebraic_structure_traits<Interval_nt<B> >::Sqrt sqrt;
01201                 result = sqrt(abs(x));
01202             }
01203             return is_positive;
01204         }
01205     };
01206 
01207   class Divides
01208     : public std::binary_function< Type, Type, Boolean > { 
01209   public:
01210     Boolean operator()( const Type& x, const Type&) const {
01211       return ! Is_zero()(x);
01212     } 
01213     // second operator computing q
01214     Boolean operator()( const Type& x, const Type& y, Type& q) const {
01215       if (! Is_zero()(x) )
01216         q  = y/x ;
01217       return Boolean(true);
01218     }
01219   };
01220   
01221 };
01222 
01223 
01224 // COERCION_TRAITS BEGIN
01225 template < class A, class B , int > struct Coercion_traits_for_level;
01226 template < class A, class B, class C> struct Coercion_traits_interval_nt;
01227 
01228 template<class A ,bool P >
01229 struct Coercion_traits_for_level<A,Interval_nt<P>,CTL_INTERVAL>
01230     :public Coercion_traits_interval_nt<A,Interval_nt<P>,
01231             typename Real_embeddable_traits<A>::Is_real_embeddable>{};
01232 
01233 template<class A , bool P>
01234 struct Coercion_traits_for_level<Interval_nt<P>,A,CTL_INTERVAL>
01235     :public Coercion_traits_for_level<A,Interval_nt<P>, CTL_INTERVAL>{};
01236 
01237 template<class A , bool P >
01238 struct Coercion_traits_interval_nt<A, Interval_nt<P>,Tag_false>
01239     :public Coercion_traits_for_level<A,Interval_nt<P>,0>{};
01240 
01241 template<class A , bool P>
01242 struct Coercion_traits_interval_nt<A, Interval_nt<P>, Tag_true>{
01243     typedef Tag_true Are_explicit_interoperable;
01244     typedef Tag_false Are_implicit_interoperable;
01245     typedef Interval_nt<P> Type;
01246     struct Cast {
01247         typedef Interval_nt<P> result_type;
01248         Interval_nt<P> inline operator()(const Interval_nt<P>& x ) const {
01249             return x;
01250         }
01251         Interval_nt<P> inline operator()(const A& x ) const {
01252             return typename Real_embeddable_traits<A>::To_interval()(x);
01253         }
01254     };
01255 };
01256 
01257 
01258 // COERCION_TRAITS END
01259 
01260 CGAL_END_NAMESPACE
01261 
01262 #endif // CGAL_INTERVAL_NT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines