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