BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Polynomial/internal/Sturm_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/Sturm_isolating_interval.h $
00016 // $Id: Sturm_isolating_interval.h 33371 2006-08-17 09:09:38Z afabri $
00017 // 
00018 //
00019 // Author(s)     : Daniel Russel <drussel@alumni.princeton.edu>
00020 
00021 #ifndef CGAL_POLYNOMIAL_STURM_ISOLATING_INTERVAL_H
00022 #define CGAL_POLYNOMIAL_STURM_ISOLATING_INTERVAL_H
00023 
00024 #include <CGAL/Polynomial/basic.h>
00025 #include <CGAL/Polynomial/internal/Filtered_number.h>
00026 
00027 CGAL_POLYNOMIAL_BEGIN_INTERNAL_NAMESPACE
00028 
00030 
00034 template <class FT_t>
00035 class Sturm_isolating_interval
00036 {
00037   typedef Sturm_isolating_interval<FT_t> This;
00038 public:
00039   typedef Filtered_number<FT_t> NT;
00040   Sturm_isolating_interval():b_(1, -1){}
00041   Sturm_isolating_interval(const NT &lbi)
00042     : b_(lbi, lbi) {}
00043   Sturm_isolating_interval(const NT &lbi, const NT &ubi)
00044     : b_(lbi, ubi) {
00045     if(0) print();                        // make sure it is instantiated
00046     if (lb() > ub()) {
00047       std::cerr << "b_.first=" << lb() << " and b_.second=" << ub() << std::endl;
00048     }
00049     CGAL_assertion(lb() <= ub());
00050   }
00051   bool is_valid() {
00052     return b_.first <= b_.second;
00053   }
00054 
00055   typedef enum Bound {UPPER, LOWER}
00056     Bound;
00057 
00058   template <class Function>
00059   typename Function::result_type
00060   apply_to_bound(Function &f, Bound b) const
00061   {
00062     CGAL_precondition(is_valid());
00063     if (b == UPPER) {
00064       return apply(f, ub());
00065     }
00066     else {
00067       return apply(f, lb());
00068     }
00069   }
00070 
00071   template <class Function>
00072   typename Function::result_type
00073   apply_to_interval(const Function &f) const
00074   {
00075     CGAL_precondition(is_valid());
00076     return apply(f, lb(), ub());
00077   }
00078 
00079   This collapse_to_bound(Bound b) const
00080   {
00081     CGAL_precondition(is_valid());
00082     if (b == UPPER) {
00083       return This(ub());
00084     }
00085     else {
00086       return This(lb());
00087     }
00088   }
00089 
00090   std::pair<This,This> split() const
00091   {
00092     CGAL_precondition(is_valid());
00093     NT mid = middle();
00094     return std::pair<This,This>(This(lb(), middle()),
00095                                 This(middle(), ub()));
00096   }
00097 
00098   This middle_half() const
00099   {
00100     CGAL_precondition(is_valid());
00101     NT mid = middle();
00102     NT mid_left = midpoint(lb(), middle());
00103     NT mid_right = midpoint(middle(), ub());
00104 
00105     return This(mid_left, mid_right);
00106   }
00107 
00108   This first_half() const
00109   {
00110     CGAL_precondition(is_valid());
00111     return This(lb(), middle());
00112   }
00113 
00114   This second_half() const
00115   {
00116     CGAL_precondition(is_valid());
00117     return This(middle(), ub());
00118   }
00119 
00120   bool is_singular() const { return lb() == ub(); }
00121 
00122 #if 0
00123   bool overlaps(const This &o) const
00124   {
00125     if (b_.first > o.b_.first && b_.first < o.b_.second) return true;
00126     else if (b_.second > o.b_.first && b_.first < o.b_.second) return true;
00127     else if (o.b_.second > b_.first && b_.first < b_.second) return true;
00128     else if (o.b_.first > b_.first && b_.first < b_.second) return true;
00129     else if (*this==o) return true;
00130     else return false;
00131   }
00132 
00133   typedef enum Relation {LESS, BELOW, CONTAINED, CONTAINS, EQUAL, ABOVE, GREATER}
00134     Relation;
00135 
00136   Relation relation(const This &o) const
00137   {
00138     CGAL_precondition(is_valid());
00139     if (*this < o) return LESS;
00140     else if (o < *this) return GREATER;
00141     else if (lb() <= o.lb() && ub() >= o.ub()) return CONTAINS;
00142     else if (o.lb() <= lb() && o.ub() >= ub()) return CONTAINED;
00143     else if (*this == o) return EQUAL;
00144     else if (lb() < o.lb()) return BELOW;
00145     else return ABOVE;
00146   }
00147 
00148   This chop(const This &o, Bound bd) const
00149   {
00150     CGAL_precondition(is_valid());
00151     if (bd== UPPER) {
00152       CGAL_assertion(lb()== o.lb() && ub() > o.ub());
00153       return This(o.ub(), ub());
00154     }
00155     else {
00156       CGAL_assertion(ub()== o.ub() && lb() < o.lb());
00157       return This(lb(),o.lb());
00158     }
00159   }
00160 
00161   void write() const
00162   {
00163     write(std::cout);
00164   }
00165 
00166   void split_on(const This &o, This &a, This &b, This &c) const
00167   {
00168     CGAL_precondition(is_valid());
00169     CGAL_precondition_code(Relation rel= relation(o));
00170     CGAL_precondition(rel== BELOW || rel == CONTAINS);
00171     a= This(lb(), o.lb());
00172     if (o.ub() <= ub()) {
00173       b= This(o);
00174       c= This(o.ub(), ub());
00175     }
00176     else {
00177       b= This(o.lb(), ub());
00178       c= This(ub(), o.ub());
00179     }
00180   }
00181 #endif
00182 
00183   std::pair<This,This> split_at(const NT& x) const
00184   {
00185     CGAL_precondition(is_valid());
00186     CGAL_precondition( !is_singular() &&
00187                        lower_bound() < x && x < upper_bound() );
00188     return std::pair<This,This>( This(lower_bound(), x),
00189                                  This(x, upper_bound()) );
00190   }
00191 
00192   This interval_around_bound(Bound b) const
00193   {
00194     CGAL_precondition(is_valid());
00195     NT mid = middle();
00196 
00197     if ( b == LOWER ) {
00198       return This(lower_bound().inf(), mid);
00199     }                                     // end-if
00200 
00201     // b == UPPER
00202     return This(mid, upper_bound().sup());
00203   }
00204 
00205   
00206   bool operator<(const This &o) const
00207   {
00208     if (ub() < o.lb()) return true;
00209     if (ub() == o.lb() && (!is_singular() || !o.is_singular())) return true;
00210     else return false;
00211   }
00212   bool operator>(const This &o) const
00213   {
00214     return o < *this;
00215   }
00216   bool operator>=(const This &o) const
00217   {
00218     return *this >0 || *this==o;
00219   }
00220   bool operator<=(const This &o) const
00221   {
00222     return *this < 0 || *this==o;
00223   }
00224   bool operator==(const This &o) const
00225   {
00226     return lb()==o.lb() && ub()==o.ub();
00227   }
00228 
00229   double approximate_width() const
00230   {
00231     return CGAL::to_double(ub()) - CGAL::to_double(lb());
00232   }
00233 
00234   NT width() const
00235   {
00236     CGAL_precondition(is_valid());
00237     return upper_bound().nt() - lower_bound().nt();
00238   }
00239 
00240 #if 0
00241   bool contains(const This &o) {
00242     return lb() <= o.lb() && ub() >= o.ub();
00243   }
00244 #endif
00245 
00246   template <class OStream>
00247   void write(OStream &out) const
00248   {
00249     if (is_singular()) {
00250       out << lb();
00251     }
00252     else {
00253       out << "(" << lb() << "..." << ub() << ")";
00254     }
00255   }
00256 
00257   void print() const
00258   {
00259     write(std::cout);
00260   }
00261 
00262   This operator-() const
00263   {
00264     return This(-ub(), -lb());
00265   }
00266 
00267   std::pair<double, double> compute_interval() const
00268   {
00269     CGAL_precondition(is_valid());
00270     std::pair<double, double> lbi =
00271       CGAL_POLYNOMIAL_TO_INTERVAL(lb()), ubi= CGAL_POLYNOMIAL_TO_INTERVAL(ub());
00272 
00273     return std::pair<double, double>(lbi.first, ubi.second);
00274   }
00275 
00276 #if 0
00277   //\todo to exact interval somehow
00278 
00279   This operator||(const This &o) {
00280     return This((std::min)(lb(), o.lb()), (std::max)(ub(), o.ub()));
00281   }
00282 #endif
00283 
00284   const NT &lower_bound() const
00285   {
00286     return b_.first;
00287   }
00288   const NT &upper_bound() const
00289   {
00290     return b_.second;
00291   }
00292 
00293   void set_upper(const NT& u) {
00294     b_.second = u;
00295   }
00296 
00297   void set_lower(const NT& l) {
00298     b_.first = l;
00299   }
00300 
00301   bool is_double() const
00302   {
00303     return lower_bound().is_double() && upper_bound().is_double();
00304   }
00305 
00306   NT middle() const
00307   {
00308     return midpoint(ub(),lb());
00309   }
00310 
00311   const std::pair<NT, NT>& to_pair() const {
00312     return b_;
00313   }
00314 
00315 protected:
00316   std::pair<NT, NT> b_;
00317 
00318   const NT &lb() const
00319   {
00320     return b_.first;
00321   }
00322   const NT &ub() const
00323   {
00324     return b_.second;
00325   }
00326 
00327 };
00328 
00329 template <class OStream, class NT>
00330 OStream &operator<<(OStream &out, const Sturm_isolating_interval<NT> &ii)
00331 {
00332   ii.write(out);
00333   return out;
00334 }
00335 
00336 
00337 template <class NT>
00338 std::pair<double, double> to_interval(const Sturm_isolating_interval<NT> &ii)
00339 {
00340   return ii.compute_interval();
00341 }
00342 
00343 
00344 CGAL_POLYNOMIAL_END_INTERNAL_NAMESPACE
00345 
00346 CGAL_BEGIN_NAMESPACE
00347 template <class NT>
00348 std::pair<double, double>
00349 to_interval(const CGAL_POLYNOMIAL_NS::internal::Sturm_isolating_interval<NT> &ii)
00350 {
00351   return ii.compute_interval();
00352 }
00353 
00354 
00355 CGAL_END_NAMESPACE
00356 #endif                                            // CGAL_POLYNOMIAL_STURM_ISOLATING_INTERVAL_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines