BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Polynomial/internal/Isolating_interval.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines