BWAPI
|
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