BWAPI
|
00001 // Copyright (c) 2005 Stanford University (USA). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public License as 00006 // published by the Free Software Foundation; version 2.1 of the License. 00007 // See the file LICENSE.LGPL distributed with CGAL. 00008 // 00009 // Licensees holding a valid commercial license may use this file in 00010 // accordance with the commercial license agreement provided with the software. 00011 // 00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00014 // 00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Kinetic_data_structures/include/CGAL/Polynomial/internal/Isolating_interval.h $ 00016 // $Id: Isolating_interval.h 40832 2007-11-08 00:27:20Z ameyer $ 00017 // 00018 // 00019 // Author(s) : Daniel Russel <drussel@alumni.princeton.edu> 00020 00021 #ifndef CGAL_POLYNOMIAL_INTERNAL_ISOLATING_INTERVAL_H 00022 #define CGAL_POLYNOMIAL_INTERNAL_ISOLATING_INTERVAL_H 00023 #include <CGAL/Polynomial/basic.h> 00024 #include <CGAL/Polynomial/internal/interval_arithmetic.h> 00025 #include <iostream> 00026 00027 CGAL_POLYNOMIAL_BEGIN_INTERNAL_NAMESPACE 00028 00030 template <class NT, class Functor> 00031 typename Functor::result_type apply(const Functor &f, const NT &a) 00032 { 00033 return f(a); 00034 } 00035 00036 00038 template <class NT, class Functor> 00039 typename Functor::result_type apply(const Functor &f, const NT &a, 00040 const NT &b) 00041 { 00042 return f( a, b); 00043 } 00044 00045 00047 template <class NT, class Functor, class Data> 00048 typename Functor::result_type apply(const Functor &f, const NT &a, 00049 const NT &b, const Data &da, const Data &db) 00050 { 00051 return f( a, b, da, db); 00052 } 00053 00054 00056 00060 template <class FT_t> 00061 class Isolating_interval 00062 { 00063 typedef Isolating_interval<FT_t> This; 00064 public: 00065 typedef FT_t NT; 00066 Isolating_interval(): b_(1, -1){} 00067 Isolating_interval(const NT &lbi): b_(lbi, lbi) { 00068 } 00069 Isolating_interval(const NT &lbi, const NT &ubi): b_(lbi, ubi) { 00070 if(0) print(); // make sure it is instantiated 00071 if (lb() > ub()) { 00072 std::cerr << "b_.first=" << lb() << " and b_.second=" << ub() << std::endl; 00073 } 00074 CGAL_Polynomial_assertion(lb() <= ub()); 00075 } 00076 00077 typedef enum Endpoint {UPPER, LOWER} 00078 Endpoint; 00079 00081 template <class Function> 00082 typename Function::result_type apply_to_endpoint(const Function &f, Endpoint b) const 00083 { 00084 CGAL_Polynomial_assertion(lb() <= ub()); 00085 if (b==UPPER) { 00086 return apply(f,ub()); 00087 } 00088 else { 00089 return apply(f, lb()); 00090 } 00091 } 00092 00094 template <class Function> 00095 typename Function::result_type apply_to_midpoint(const Function &f) { 00096 CGAL_Polynomial_assertion(lb() <= ub()); 00097 return apply(f,middle()); 00098 } 00099 00101 template <class Function> 00102 typename Function::result_type apply_to_interval(const Function &f) const 00103 { 00104 CGAL_Polynomial_assertion(lb() <= ub()); 00105 return apply(f, lb(), ub()); 00106 } 00107 00109 template <class Function, class Data> 00110 typename Function::result_type apply_to_interval(const Function &f, 00111 const Data &d0, const Data &d1) const 00112 { 00113 CGAL_Polynomial_assertion(lb() <= ub()); 00114 return apply(f, lb(), ub(), d0, d1); 00115 } 00116 00117 This upper_endpoint_interval() const 00118 { 00119 CGAL_Polynomial_assertion(lb() <= ub()); 00120 return This(ub()); 00121 } 00122 00123 This lower_endpoint_interval() const 00124 { 00125 CGAL_Polynomial_assertion(lb() <= ub()); 00126 return This(lb()); 00127 } 00128 00130 This endpoint_interval(Endpoint b) const 00131 { 00132 CGAL_Polynomial_assertion(lb() <= ub()); 00133 if (b==UPPER) { 00134 return This(ub()); 00135 } 00136 else { 00137 return This(lb()); 00138 } 00139 } 00140 00141 This midpoint_interval() const 00142 { 00143 CGAL_Polynomial_assertion(lb() <= ub()); 00144 return This(middle()); 00145 } 00146 00148 This first_half() const 00149 { 00150 CGAL_Polynomial_assertion(lb() <= ub()); 00151 return This(lb(), middle()); 00152 } 00154 This second_half() const 00155 { 00156 CGAL_Polynomial_assertion(lb() <= ub()); 00157 return This(middle(), ub()); 00158 } 00159 00161 std::pair<This,This> split() const 00162 { 00163 CGAL_Polynomial_assertion(lb() <= ub()); 00164 NT mid = middle(); 00165 return std::pair<This,This>(This(lb(), mid), This(mid, ub())); 00166 } 00167 00169 This middle_half() const 00170 { 00171 CGAL_Polynomial_assertion(lb() <= ub()); 00172 NT mid = middle(); 00173 NT mid_left = midpoint(lb(), middle()); 00174 NT mid_right = midpoint(middle(), ub()); 00175 00176 return This(mid_left, mid_right); 00177 } 00178 00179 std::pair<This,This> split_at(const NT& x) const 00180 { 00181 CGAL_Polynomial_assertion(lb() <= ub()); 00182 CGAL_precondition( !is_singular() && 00183 lower_bound() < x && x < upper_bound() ); 00184 return std::pair<This,This>( This(lower_bound(), x), 00185 This(x, upper_bound()) ); 00186 } 00187 00188 This split_at_first_half(const NT& x) const 00189 { 00190 CGAL_Polynomial_assertion(lb() <= ub()); 00191 CGAL_precondition( !is_singular() && 00192 lower_bound() < x && x < upper_bound() ); 00193 return This(lower_bound(), x); 00194 } 00195 This split_at_second_half(const NT& x) const 00196 { 00197 CGAL_Polynomial_assertion(lb() <= ub()); 00198 CGAL_precondition( !is_singular() && 00199 lower_bound() < x && x < upper_bound() ); 00200 return This(x, upper_bound()); 00201 } 00202 00203 This interval_around_endpoint(Endpoint b) const 00204 { 00205 CGAL_Polynomial_assertion(lb() <= ub()); 00206 NT mid = middle(); 00207 00208 if ( b == LOWER ) { 00209 return This(lower_bound()-NT(1), mid); 00210 } // end-if 00211 00212 // b == UPPER 00213 return This(mid, upper_bound()+NT(1)); 00214 } 00215 00217 bool is_singular() const 00218 { 00219 CGAL_Polynomial_assertion(lb() <= ub()); 00220 return lb()==ub(); 00221 } 00222 00223 const NT &to_nt() const 00224 { 00225 CGAL_Polynomial_assertion(lb() <= ub()); 00226 CGAL_Polynomial_precondition(is_singular()); 00227 return lb(); 00228 } 00229 00230 /*bool overlaps(const This &o) const { 00231 if (b_.first > o.b_.first && b_.first < o.b_.second) return true; 00232 else if (b_.second > o.b_.first && b_.first < o.b_.second) return true; 00233 else if (o.b_.second > b_.first && b_.first < b_.second) return true; 00234 else if (o.b_.first > b_.first && b_.first < b_.second) return true; 00235 else if (*this==o) return true; 00236 else return false; 00237 }*/ 00238 00240 Order order(const This &o) const 00241 { 00242 CGAL_Polynomial_assertion(lb() <= ub()); 00243 CGAL_Polynomial_assertion(o.lb() <= o.ub()); 00244 if (*this < o) return STRICTLY_BELOW; 00245 else if (o < *this) return STRICTLY_ABOVE; 00246 else if (lb() <= o.lb() && ub() >= o.ub()) return CONTAINS; 00247 else if (o.lb() <= lb() && o.ub() >= ub()) return CONTAINED; 00248 else if (*this == o) return EQUAL; 00249 else if (lb() < o.lb()) return BELOW; 00250 else return ABOVE; 00251 } 00252 00254 00258 /*This chop(const This &o, Endpoint bd) const { 00259 if (bd== UPPER) { 00260 Polynomial_assertion(lb()== o.lb() && ub() > o.ub()); 00261 return This(o.ub(), ub()); 00262 } else { 00263 Polynomial_assertion(ub()== o.ub() && lb() < o.lb()); 00264 return This(lb(),o.lb()); 00265 } 00266 }*/ 00267 00268 int number_overlap_intervals(const This &o) const 00269 { 00270 CGAL_Polynomial_assertion(lb() <= ub()); 00271 CGAL_Polynomial_assertion(o.lb() <= o.ub()); 00272 Order ord= order(o); 00273 switch(ord) { 00274 case CONTAINS: 00275 return 3; 00276 case CONTAINED: 00277 return 1; 00278 case BELOW: 00279 case ABOVE: 00280 return 2; 00281 case STRICTLY_ABOVE: 00282 case STRICTLY_BELOW: 00283 return 1; 00284 default: 00285 return -1; 00286 } 00287 } 00288 00289 // If we have two partially overllaping intervals, then 00290 // *_overlap_interval return the three possible intervals of *this: 00291 // the common interval and the non-common remainders of the two 00292 // intervals. 00293 This first_overlap_interval(const This &o) const 00294 { 00295 CGAL_Polynomial_assertion(lb() <= ub()); 00296 CGAL_Polynomial_assertion(o.lb() <= o.ub()); 00297 Order ord= order(o); 00298 switch(ord) { 00299 case CONTAINS: 00300 return This(lb(), o.lb()); 00301 case CONTAINED: 00302 case STRICTLY_ABOVE: 00303 case STRICTLY_BELOW: 00304 return *this; 00305 case BELOW: 00306 return This(lb(), o.lb()); 00307 case ABOVE: 00308 return This(lb(), o.ub()); 00309 default: 00310 return This(); 00311 }; 00312 } 00313 00314 This second_overlap_interval(const This &o) const 00315 { 00316 CGAL_Polynomial_assertion(lb() <= ub()); 00317 CGAL_Polynomial_assertion(o.lb() <= o.ub()); 00318 Order ord= order(o); 00319 switch(ord) { 00320 case CONTAINS: 00321 return This(o.lb(), o.ub()); 00322 case BELOW: 00323 return This(o.lb(), ub()); 00324 case ABOVE: 00325 return This(o.ub(), ub()); 00326 default: 00327 return This(); 00328 }; 00329 } 00330 00331 This third_overlap_interval(const This &o) const 00332 { 00333 CGAL_Polynomial_assertion(lb() <= ub()); 00334 CGAL_Polynomial_assertion(o.lb() <= o.ub()); 00335 Order ord= order(o); 00336 switch(ord) { 00337 case CONTAINS: 00338 return This(o.ub(), ub()); 00339 default: 00340 return This(); 00341 }; 00342 } 00343 00344 /*std::pair<This, This> split_with(const This &o) const { 00345 bool I_would_like_to_get_rid_of_this; 00346 CGAL_precondition(0); 00347 Order ord= order(o); 00348 typedef std::pair<This, This> IP; 00349 switch(ord){ 00350 case STRICTLY_BELOW: 00351 return IP(*this, endpoint_interval(UPPER)); 00352 case STRICTLY_ABOVE: 00353 return IP(endpoint_interval(LOWER, *this)); 00354 case BELOW: 00355 return IP(This(lb(), o.lb()), This(ub(), o.ub())); 00356 case CONTAINS: 00357 return IP(This(lb(), o.lb()), This(); 00358 } 00359 }*/ 00360 00362 00366 /* 00367 void subintervals(const This &o, This &a, This &b, This &c) const { 00368 bool I_would_like_to_get_rid_of_this; 00369 00370 Order ord= order(o); 00371 switch (ord){ 00372 case BELOW: 00373 a=This(lb(), o.lb()); 00374 b=This(o.lb(), ub()); 00375 c=This(ub(), o.ub()); 00376 break; 00377 case CONTAINS: 00378 a=This(lb, o.lb()); 00379 b=o; 00380 c=This(o.ub(), ub()); 00381 break; 00382 case CONTAINED: 00383 a=This(o.lb, lb()); 00384 b=*this; 00385 c=This(ub(), o.ub()); 00386 break; 00387 case ABOVE: 00388 a=This(o.lb(), lb()); 00389 b=This(lb(), o.ub()); 00390 c=This(o.ub(), ub()); 00391 break; 00392 case STRICTLY_BELOW: 00393 a=*this; 00394 b=This(ub(), o.lb()); 00395 c=o; 00396 break; 00397 case STRICTLY_ABOVE: 00398 a=o; 00399 b=This(o.ub(), lb()); 00400 c=*this; 00401 break; 00402 default: 00403 CGAL_error(); 00404 } 00405 CGAL_postcondition(a.ub()==b.lb()); 00406 CGAL_postcondition(b.ub()==c.lb()); 00407 }*/ 00408 00409 00410 bool operator<(const This &o) const 00411 { 00412 CGAL_Polynomial_assertion(lb() <= ub()); 00413 CGAL_Polynomial_assertion(o.lb() <= o.ub()); 00414 if (ub() < o.lb()) return true; 00415 return (ub() == o.lb() && (!is_singular() || !o.is_singular())); 00416 /* 00417 if (ub() == o.lb() && (!is_singular() || !o.is_singular())) return true; 00418 else return false; 00419 */ 00420 } 00421 bool operator>(const This &o) const 00422 { 00423 CGAL_Polynomial_assertion(lb() <= ub()); 00424 CGAL_Polynomial_assertion(o.lb() <= o.ub()); 00425 return o < *this; 00426 } 00427 bool operator>=(const This &o) const 00428 { 00429 CGAL_Polynomial_assertion(lb() <= ub()); 00430 CGAL_Polynomial_assertion(o.lb() <= o.ub()); 00431 return *this >0 || *this==o; 00432 } 00433 bool operator<=(const This &o) const 00434 { 00435 CGAL_Polynomial_assertion(lb() <= ub()); 00436 CGAL_Polynomial_assertion(o.lb() <= o.ub()); 00437 return *this < 0 || *this==o; 00438 } 00439 bool operator==(const This &o) const 00440 { 00441 CGAL_Polynomial_assertion(lb() <= ub()); 00442 CGAL_Polynomial_assertion(o.lb() <= o.ub()); 00443 return lb()==o.lb() && ub()==o.ub(); 00444 } 00445 bool operator!=(const This &o) const 00446 { 00447 CGAL_Polynomial_assertion(lb() <= ub()); 00448 CGAL_Polynomial_assertion(o.lb() <= o.ub()); 00449 return lb()!=o.lb() || ub()!=o.ub(); 00450 } 00451 00453 double approximate_width() const 00454 { 00455 CGAL_Polynomial_assertion(lb() <= ub()); 00456 return (std::max)(to_double(ub()) - to_double(lb()), 0.0); 00457 } 00458 00459 double approximate_relative_width() const 00460 { 00461 CGAL_Polynomial_assertion(lb() <= ub()); 00462 return approximate_width()/(std::max)(to_double(abs(ub())), to_double(abs(lb()))); 00463 } 00464 00465 bool contains(const This &o) { 00466 CGAL_Polynomial_assertion(lb() <= ub()); 00467 return lb() <= o.lb() && ub() >= o.ub(); 00468 } 00469 00470 bool contains(const NT &o) { 00471 return lb() <= o && ub() >= o; 00472 } 00473 00474 template <class OStream> 00475 void write(OStream &out) const 00476 { 00477 if (is_singular()) { 00478 out << lb(); 00479 } 00480 else { 00481 out << "(" << lb() << "..." << ub() << ")"; 00482 } 00483 if (0) print(); 00484 } 00485 void print() const ; 00486 00487 This operator-() const 00488 { 00489 CGAL_Polynomial_assertion(lb() <= ub()); 00490 return This(-ub(), -lb()); 00491 } 00492 00494 std::pair<double, double> double_interval() const 00495 { 00496 CGAL_Polynomial_assertion(lb() <= ub()); 00497 std::pair<double, double> 00498 lbi= CGAL_POLYNOMIAL_TO_INTERVAL(lb()), 00499 ubi= CGAL_POLYNOMIAL_TO_INTERVAL(ub()); 00500 return std::pair<double, double>(lbi.first, ubi.second); 00501 } 00502 00503 const NT& lower_bound() const 00504 { 00505 CGAL_Polynomial_assertion(lb() <= ub()); 00506 // bool not_recommended; 00507 return lb(); 00508 } 00509 const NT& upper_bound() const 00510 { 00511 CGAL_Polynomial_assertion(lb() <= ub()); 00512 // bool not_recommended; 00513 return ub(); 00514 } 00515 00516 void set_upper(const NT& u) { 00517 CGAL_Polynomial_assertion(lb() <= ub()); 00518 b_.second = u; 00519 } 00520 00521 void set_lower(const NT& l) { 00522 CGAL_Polynomial_assertion(lb() <= ub()); 00523 b_.first = l; 00524 } 00525 00526 /*std::pair<NT, NT> () const { 00527 return std::pair<NT,NT>(b_.first, b_.second); 00528 }*/ 00529 00531 /*This operator||(const This &o){ 00532 return This((std::min)(lb(), o.lb()), (std::max)(ub(), o.ub())); 00533 }*/ 00534 00536 This operator||(const This &o) const 00537 { 00538 CGAL_Polynomial_assertion(lb() <= ub()); 00539 return This((std::min)(lb(), o.lb()), (std::max)(ub(), o.ub())); 00540 } 00541 00542 NT middle() const 00543 { 00544 CGAL_Polynomial_assertion(lb() <= ub()); 00545 return NT(0.5)*(ub()+lb()); 00546 } 00547 00548 const std::pair<NT,NT>& to_pair() const { 00549 return b_; 00550 } 00551 00552 protected: 00553 std::pair<NT,NT> b_; 00554 00555 NT midpoint(const NT& a, const NT& b) const 00556 { 00557 return NT(0.5)*(a+b); 00558 } 00559 00560 const NT &lb() const 00561 { 00562 return b_.first; 00563 } 00564 const NT &ub() const 00565 { 00566 return b_.second; 00567 } 00568 00569 /*static NT infinity() { 00570 if (std::numeric_limits<NT>::has_infinity){ 00571 return std::numeric_limits<NT>::infinity(); 00572 } else if (std::numeric_limits<NT>::is_bounded){ 00573 return (std::numeric_limits<NT>::max)(); 00574 } else { 00575 return NT(1000000000); 00576 } 00577 }*/ 00578 }; 00579 00580 template <class NT> 00581 void Isolating_interval<NT>::print() const 00582 { 00583 write(std::cout); 00584 std::cout << std::endl; 00585 } 00586 00587 00588 template <class OStream, class NT> 00589 OStream &operator<<(OStream &out, const Isolating_interval<NT> &ii) 00590 { 00591 ii.write(out); 00592 return out; 00593 } 00594 00595 00596 /*template <class NT> 00597 std::pair<double, double> to_interval(const Isolating_interval<NT> &ii){ 00598 return ii.to_interval(); 00599 }*/ 00600 00601 CGAL_POLYNOMIAL_END_INTERNAL_NAMESPACE 00602 00603 #ifdef CGAL_POLYNOMIAL_USE_CGAL 00604 00605 CGAL_BEGIN_NAMESPACE 00606 template <class NT> 00607 std::pair<double, double> to_interval(const typename CGAL_POLYNOMIAL_NS::internal::Isolating_interval<NT> &ii) 00608 { 00609 return ii.double_interval(); 00610 } 00611 00612 00613 CGAL_END_NAMESPACE 00614 #endif 00615 #endif