BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/leda_rational.h
Go to the documentation of this file.
00001 // Copyright (c) 1999,2007  Utrecht University (The Netherlands),
00002 // ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
00003 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
00004 // (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria),
00005 // and Tel-Aviv University (Israel).  All rights reserved.
00006 //
00007 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public License as
00009 // published by the Free Software Foundation; version 2.1 of the License.
00010 // See the file LICENSE.LGPL distributed with CGAL.
00011 //
00012 // Licensees holding a valid commercial license may use this file in
00013 // accordance with the commercial license agreement provided with the software.
00014 //
00015 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 //
00018 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Number_types/include/CGAL/leda_rational.h $
00019 // $Id: leda_rational.h 46851 2008-11-12 16:53:12Z lrineau $
00020 //
00021 //
00022 // Author(s)     : Andreas Fabri, Michael Hemmer
00023 
00024 #ifndef CGAL_LEDA_RATIONAL_H
00025 #define CGAL_LEDA_RATIONAL_H
00026 
00027 #include <CGAL/number_type_basic.h>
00028 
00029 #ifdef CGAL_USE_LEDA
00030 
00031 #include <CGAL/leda_coercion_traits.h>
00032 #include <CGAL/Interval_nt.h>
00033 
00034 #include <CGAL/Needs_parens_as_product.h>
00035 
00036 #include <utility>
00037 
00038 #include <CGAL/LEDA_basic.h>
00039 #if CGAL_LEDA_VERSION < 500
00040 #  include <LEDA/rational.h>
00041 #  include <LEDA/interval.h>
00042 #else
00043 #  include <LEDA/numbers/rational.h>
00044 #  if defined(  _MSC_VER )
00045 #    pragma push_macro("ERROR")  
00046 #    undef ERROR
00047 #  endif // _MSC_VER
00048 #  include <LEDA/numbers/interval.h>
00049 #  if defined(  _MSC_VER )
00050 #    pragma pop_macro("ERROR")  
00051 #  endif
00052 #endif
00053 
00054 #include <CGAL/leda_integer.h> // for GCD in Fraction_traits
00055 
00056 CGAL_BEGIN_NAMESPACE
00057 
00058 template <> class Algebraic_structure_traits< leda_rational >
00059   : public Algebraic_structure_traits_base< leda_rational,
00060                                             Field_tag >  {
00061   public:
00062     typedef Tag_true            Is_exact;
00063     typedef Tag_false           Is_numerical_sensitive;
00064 
00065 //    TODO: How to implement this without having sqrt?
00066 //    typedef INTERN_AST::Is_square_per_sqrt< Type >
00067 //                                                                 Is_square;
00068 
00069     class Simplify
00070       : public std::unary_function< Type&, void > {
00071       public:
00072         void operator()( Type& x) const {
00073             x.normalize();
00074         }
00075     };
00076 
00077 };
00078 
00079 template <> class Real_embeddable_traits< leda_rational >
00080   : public INTERN_RET::Real_embeddable_traits_base< leda_rational , CGAL::Tag_true > {
00081   public:
00082   
00083     class Abs
00084       : public std::unary_function< Type, Type > {
00085       public:
00086         Type operator()( const Type& x ) const {
00087             return CGAL_LEDA_SCOPE::abs( x );
00088         }
00089     };
00090 
00091     class Sgn
00092       : public std::unary_function< Type, ::CGAL::Sign > {
00093       public:
00094         ::CGAL::Sign operator()( const Type& x ) const {
00095             return (::CGAL::Sign) CGAL_LEDA_SCOPE::sign( x );
00096         }
00097     };
00098 
00099     class Compare
00100       : public std::binary_function< Type, Type,
00101                                 Comparison_result > {
00102       public:
00103         Comparison_result operator()( const Type& x,
00104                                       const Type& y ) const {
00105           return (Comparison_result) CGAL_LEDA_SCOPE::compare( x, y );
00106         }
00107         CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR_WITH_RT(Type,Comparison_result)
00108     };
00109 
00110     class To_double
00111       : public std::unary_function< Type, double > {
00112       public:
00113         double operator()( const Type& x ) const {
00114           return x.to_double();
00115         }
00116     };
00117 
00118     class To_interval
00119       : public std::unary_function< Type, std::pair< double, double > > {
00120       public:
00121         std::pair<double, double> operator()( const Type& x ) const {
00122 
00123 #if CGAL_LEDA_VERSION >= 501
00124           CGAL_LEDA_SCOPE::interval temp(x);
00125           std::pair<double, double> result(temp.lower_bound(),temp.upper_bound());
00126           CGAL_postcondition(Type(result.first)<=x);
00127           CGAL_postcondition(Type(result.second)>=x);
00128           return result;
00129 #else
00130           CGAL_LEDA_SCOPE::bigfloat xnum = x.numerator();
00131           CGAL_LEDA_SCOPE::bigfloat xden = x.denominator();
00132           CGAL_LEDA_SCOPE::bigfloat xupp =
00133                                     div(xnum,xden,53,CGAL_LEDA_SCOPE::TO_P_INF);
00134           CGAL_LEDA_SCOPE::bigfloat xlow =
00135                                     div(xnum,xden,53,CGAL_LEDA_SCOPE::TO_N_INF);
00136 
00137           // really smallest positive double
00138           double MinDbl = CGAL_LEDA_SCOPE::fp::compose_parts(0,0,0,1);
00139 
00140           double low = xlow.to_double();
00141           while(Type(low) > x) low = low - MinDbl;
00142 
00143           double upp = xupp.to_double();
00144           while(Type(upp) < x) upp = upp + MinDbl;
00145 
00146           std::pair<double, double> result(low,upp);
00147           CGAL_postcondition(Type(result.first)<=x);
00148           CGAL_postcondition(Type(result.second)>=x);
00149           return result;
00150 #endif
00151           // Original CGAL to_interval (seemed to be inferior)
00152           //  // There's no guarantee about the error of to_double(), so I add
00153           //  //  3 ulps...
00154           //  Protect_FPU_rounding<true> P (CGAL_FE_TONEAREST);
00155           //  Interval_nt_advanced approx (z.to_double());
00156           //  FPU_set_cw(CGAL_FE_UPWARD);
00157           //
00158           //  approx += Interval_nt<false>::smallest();
00159           //  approx += Interval_nt<false>::smallest();
00160           //  approx += Interval_nt<false>::smallest();
00161           //  return approx.pair();
00162 
00163         }
00164     };
00165 };
00166 
00170 template <>
00171 class Fraction_traits< leda_rational > {
00172 public:
00173     typedef leda_rational Type;
00174     typedef ::CGAL::Tag_true Is_fraction;
00175     typedef leda_integer Numerator_type;
00176     typedef Numerator_type Denominator_type;
00177 
00178     typedef Algebraic_structure_traits< Numerator_type >::Gcd Common_factor;
00179 
00180     class Decompose {
00181     public:
00182         typedef Type first_argument_type;
00183         typedef Numerator_type& second_argument_type;
00184         typedef Numerator_type& third_argument_type;
00185         void operator () (
00186                 const Type& rat,
00187                 Numerator_type& num,
00188                 Numerator_type& den) {
00189             num = rat.numerator();
00190             den = rat.denominator();
00191         }
00192     };
00193 
00194     class Compose {
00195     public:
00196         typedef Numerator_type first_argument_type;
00197         typedef Numerator_type second_argument_type;
00198         typedef Type result_type;
00199         Type operator ()(
00200                 const Numerator_type& num ,
00201                 const Numerator_type& den ) {
00202             Type result(num, den);
00203             result.normalize();
00204             return result;
00205         }
00206     };
00207 };
00208 
00209 template <class F>
00210 class Output_rep< leda_rational, F> {
00211     const leda_rational& t;
00212 public:
00214     Output_rep( const leda_rational& tt) : t(tt) {}
00216     std::ostream& operator()( std::ostream& out) const {
00217         switch (get_mode(out)) {
00218         case IO::PRETTY:{
00219             if(t.denominator() == leda_integer(1))
00220                 return out <<t.numerator();
00221             else
00222                 return out << t.numerator()
00223                            << "/"
00224                            << t.denominator();
00225             break;
00226         }
00227 
00228         default:
00229             return out << t.numerator()
00230                        << "/"
00231                        << t.denominator();
00232         }
00233     }
00234 };
00235 
00236 template <>
00237 struct Needs_parens_as_product< leda_rational >{
00238     bool operator()( leda_rational t){
00239         if (t.denominator() != 1 )
00240             return true;
00241         else
00242             return needs_parens_as_product(t.numerator()) ;
00243     }
00244 };
00245 
00246 template <>
00247 class Output_rep< leda_rational, Parens_as_product_tag > {
00248     const leda_rational& t;
00249 public:
00250     // Constructor
00251     Output_rep( const leda_rational& tt) : t(tt) {}
00252     // operator
00253     std::ostream& operator()( std::ostream& out) const {
00254         Needs_parens_as_product< leda_rational > needs_parens_as_product;
00255         if (needs_parens_as_product(t))
00256             return out <<"("<< oformat(t) <<")";
00257         else
00258             return out << oformat(t);
00259     }
00260 };
00261 
00262 template < >
00263 class Benchmark_rep< leda_rational > {
00264     const leda_rational& t;
00265 public:
00267     Benchmark_rep( const leda_rational& tt) : t(tt) {}
00269     std::ostream& operator()( std::ostream& out) const { 
00270             return 
00271                 out << "Rational(" << t.numerator() << "," 
00272                     << t.denominator() << ")";
00273     }
00274 
00275     static std::string get_benchmark_name() {
00276         return "Rational";
00277     }
00278 
00279 };
00280 
00281 
00282 CGAL_END_NAMESPACE
00283 
00284 // Unary + is missing for leda::rational
00285 namespace leda{
00286 inline rational operator+( const rational& i) { return i; }
00287 }
00288 
00289 //since types are included by leda_coercion_traits.h:
00290 #include <CGAL/leda_integer.h>
00291 #include <CGAL/leda_rational.h>
00292 #include <CGAL/leda_bigfloat.h>
00293 #include <CGAL/leda_real.h>
00294 
00295 #endif // CGAL_USE_LEDA
00296 
00297 #endif  // CGAL_LEDA_RATIONAL_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines