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/Filtered_number.h $ 00016 // $Id: Filtered_number.h 28567 2006-02-16 14:30:13Z lsaboret $ 00017 // 00018 // 00019 // Author(s) : Daniel Russel <drussel@alumni.princeton.edu> 00020 00021 #ifndef CGAL_POLYNOMIAL_INTERNAL_FILTERED_NUMBER_H 00022 #define CGAL_POLYNOMIAL_INTERNAL_FILTERED_NUMBER_H 00023 00024 #include <CGAL/Polynomial/basic.h> 00025 #include <CGAL/FPU.h> 00026 00027 CGAL_POLYNOMIAL_BEGIN_NAMESPACE 00028 00029 template <class NT_t> 00030 class Filtered_number 00031 { 00032 typedef Filtered_number<NT_t> This; 00033 public: 00034 typedef NT_t NT; 00035 Filtered_number(NT_t nt):nt_(nt) { 00036 double_=false; 00037 } 00038 Filtered_number(double d):d_(d) { 00039 double_=true; 00040 } 00041 Filtered_number(){} 00042 void set(NT_t nt) { 00043 nt_=nt; 00044 double_=false; 00045 } 00046 void set(double d) { 00047 d_=d; 00048 if (!double_) { 00049 nt_=NT_t(); 00050 double_=true; 00051 } 00052 } 00053 NT_t nt() const 00054 { 00055 if (double_) return NT_t(d_); 00056 return nt_; 00057 } 00058 double d() const 00059 { 00060 if (!double_) return CGAL_POLYNOMIAL_TO_DOUBLE(nt_); 00061 return d_; 00062 } 00063 const std::pair<double, double> &it() const 00064 { 00065 if (!double_) return CGAL_POLYNOMIAL_TO_INTERVAL(nt_); 00066 return std::pair<double,double>(d_, d_); 00067 } 00068 This operator-() const 00069 { 00070 if (double_) { 00071 return This(-d_); 00072 } 00073 else { 00074 return This(-nt_); 00075 } 00076 } 00077 00078 This inf() const 00079 { 00080 if ( double_ ) { 00081 double dbl = d_ - 1.0; 00082 if ( dbl < d_ && CGAL::is_finite(dbl) ) { 00083 return This(dbl); 00084 } 00085 else { 00086 return This( NT(d_) - NT(1) ); 00087 } 00088 } 00089 00090 return This(nt_ - NT(1)); 00091 } 00092 00093 This sup() const 00094 { 00095 if ( double_ ) { 00096 double dbl = d_ + 1.0; 00097 if ( dbl > d_ && CGAL::is_finite(dbl) ) { 00098 return This(dbl); 00099 } 00100 else { 00101 return This( NT(d_) + NT(1) ); 00102 } 00103 } 00104 00105 return This(nt_ + NT(1)); 00106 } 00107 00108 bool is_double() const { return double_; } 00109 00110 bool operator<(const This &o) const 00111 { 00112 return compare(o) == CGAL::SMALLER; 00113 } 00114 bool operator>(const This &o) const 00115 { 00116 return compare(o) == CGAL::LARGER; 00117 } 00118 bool operator<=(const This &o) const 00119 { 00120 return compare(o) != CGAL::LARGER; 00121 } 00122 bool operator>=(const This &o) const 00123 { 00124 return compare(o) != CGAL::SMALLER; 00125 } 00126 bool operator==(const This &o) const 00127 { 00128 return compare(o) == CGAL::EQUAL; 00129 } 00130 bool operator!=(const This &o) const 00131 { 00132 return compare(o) != CGAL::EQUAL; 00133 } 00134 00135 static This midpoint(const This &a, const This &b) { 00136 CGAL_precondition( a != b ); 00137 00138 if (a.double_ && b.double_) { 00139 double mid = (a.d_ + b.d_) * 0.5; 00140 double dmin, dmax; 00141 00142 // gcc in x86 has register with bigger size than memory 00143 // as a result although we have underflow this is not 00144 // detected; remedy: copy variable to memory and retrieve it; 00145 // this is what the following macro does; 00146 // many thanks to Sylvain for pointing this out and providing a 00147 // solution 00148 mid = CGAL_IA_FORCE_TO_DOUBLE(mid); 00149 00150 if ( a.d_ < b.d_ ) { 00151 dmin = a.d_; 00152 dmax = b.d_; 00153 } 00154 else { 00155 dmin = b.d_; 00156 dmax = a.d_; 00157 } 00158 if ( dmin < mid && mid < dmax ) { 00159 return This(mid); 00160 } 00161 else { 00162 return This(NT(.5)*(a.nt() + b.nt())); 00163 } 00164 } 00165 else { 00166 return This(NT(.5)*(a.nt() + b.nt())); 00167 } 00168 } 00169 double compute_double() const 00170 { 00171 return d(); 00172 } 00173 std::pair<double, double> compute_interval() const 00174 { 00175 if (double_) { 00176 return std::pair<double, double>(d(), d()); 00177 } 00178 else { 00179 return CGAL_POLYNOMIAL_TO_INTERVAL(nt()); 00180 } 00181 } 00182 void write(std::ostream &out) const 00183 { 00184 if (double_) { 00185 out << d_; 00186 } 00187 else { 00188 out << nt_; 00189 } 00190 } 00191 template <class Functor> 00192 static typename Functor::result_type apply(const Functor &f, const This &a) { 00193 if (a.double_) { 00194 return f(a.d_); 00195 } 00196 else { 00197 return f(a.nt_); 00198 } 00199 } 00200 template <class Functor> 00201 static typename Functor::result_type apply(const Functor &f, const This &a, const This &b) { 00202 if (a.double_ && b.double_) { 00203 return f(a.d_, b.d_); 00204 } 00205 else { 00206 return f(a.nt(), b.nt()); 00207 } 00208 } 00209 00210 template <class Functor, class Data> 00211 static typename Functor::result_type apply(const Functor &f, const This &a, const This &b, 00212 const Data &da, const Data &db) { 00213 if (a.double_ && b.double_) { 00214 return f(a.d_, b.d_, da, db); 00215 } 00216 else { 00217 return f(a.nt(), b.nt(), da, db); 00218 } 00219 } 00220 00221 template <class Functor, class Data> 00222 static typename Functor::result_type apply(const Functor &f, 00223 const This &a, 00224 const This &b, 00225 const Data& data) { 00226 if (a.double_ && b.double_) { 00227 return f(a.d_, b.d_, data); 00228 } 00229 else { 00230 return f(a.nt(), b.nt(), data); 00231 } 00232 } 00233 00234 protected: 00235 NT nt_; 00236 double d_; 00237 bool double_; 00238 00239 template <class NT> 00240 static CGAL::Comparison_result compare(const NT &a, const NT &b) { 00241 if (a < b) return CGAL::SMALLER; 00242 else if (a==b) return CGAL::EQUAL; 00243 else return CGAL::LARGER; 00244 } 00245 00246 CGAL::Comparison_result compare(const This &o) const 00247 { 00248 if (double_ && o.double_) { 00249 return compare(d_, o.d_); 00250 } 00251 else { 00252 return compare(nt(), o.nt()); 00253 } 00254 } 00255 }; 00256 00257 template <class NT> 00258 Filtered_number<NT> midpoint(const Filtered_number<NT> &a, const Filtered_number<NT> &b) 00259 { 00260 return Filtered_number<NT>::midpoint(a,b); 00261 } 00262 00263 00264 template <class NT, class Functor> 00265 typename Functor::result_type apply(const Functor &f, const Filtered_number<NT> &a) 00266 { 00267 return Filtered_number<NT>::apply(f, a); 00268 } 00269 00270 00271 template <class NT, class Functor> 00272 typename Functor::result_type apply(const Functor &f, const Filtered_number<NT> &a, 00273 const Filtered_number<NT> &b) 00274 { 00275 return Filtered_number<NT>::apply(f, a, b); 00276 } 00277 00278 00279 template <class NT, class Functor, class Data> 00280 typename Functor::result_type apply(const Functor &f, const Filtered_number<NT> &a, 00281 const Filtered_number<NT> &b, const Data &da, const Data &db) 00282 { 00283 return Filtered_number<NT>::apply(f, a, b, da, db); 00284 } 00285 00286 00287 template <class NT> 00288 double to_double(const Filtered_number<NT> &a) 00289 { 00290 return a.to_double(); 00291 } 00292 00293 00294 template <class NT> 00295 std::pair<double, double> to_interval(const Filtered_number<NT> &a) 00296 { 00297 return a.compute_interval(); 00298 } 00299 00300 00301 template <class NT> 00302 std::ostream &operator<<(std::ostream &out, const Filtered_number<NT> &a) 00303 { 00304 a.write(out); 00305 return out; 00306 } 00307 00308 00309 CGAL_POLYNOMIAL_END_NAMESPACE 00310 00311 CGAL_BEGIN_NAMESPACE 00312 template <class NT> 00313 double to_double(const CGAL_POLYNOMIAL_NS::Filtered_number<NT> &a) 00314 { 00315 return a.compute_double(); 00316 } 00317 00318 00319 template <class NT> 00320 std::pair<double, double> to_interval(const CGAL_POLYNOMIAL_NS::Filtered_number<NT> &a) 00321 { 00322 return a.to_interval(); 00323 } 00324 00325 00326 CGAL_END_NAMESPACE 00327 00328 template <class NT> 00329 std::ostream &operator<<(std::ostream &out, const CGAL_POLYNOMIAL_NS::Filtered_number<NT> &a) 00330 { 00331 a.write(out); 00332 return out; 00333 } 00334 #endif