|
BWAPI
|
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
1.7.6.1