BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Polynomial/internal/Filtered_number.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/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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines