BWAPI
|
00001 // Copyright (c) 2006-2008 Max-Planck-Institute Saarbruecken (Germany), 00002 // INRIA Sophia-Antipolis (France). 00003 // All rights reserved. 00004 // 00005 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public License as 00007 // published by the Free Software Foundation; version 2.1 of the License. 00008 // See the file LICENSE.LGPL distributed with CGAL. 00009 // 00010 // Licensees holding a valid commercial license may use this file in 00011 // accordance with the commercial license agreement provided with the software. 00012 // 00013 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00014 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00015 // 00016 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Number_types/include/CGAL/Gmpz.h $ 00017 // $Id: Gmpz.h 47264 2008-12-08 06:25:14Z hemmer $ 00018 // 00019 // 00020 // Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de> 00021 // Sylvain Pion 00022 00023 #ifndef CGAL_GMPZ_H 00024 #define CGAL_GMPZ_H 00025 00026 #include <CGAL/config.h> 00027 #if defined(BOOST_MSVC) 00028 # pragma warning(push) 00029 # pragma warning(disable:4800) // complaint about performance in std::map where we can't do anything 00030 #endif 00031 00032 #include <CGAL/number_type_basic.h> 00033 #include <CGAL/Gmp_coercion_traits.h> 00034 #include <CGAL/Quotient.h> // spec of AST for Quotient<Gmpz> 00035 00036 #include <string> 00037 #include <locale> 00038 00039 #include <CGAL/Root_of_traits.h> 00040 #include <CGAL/Modular_traits.h> 00041 00042 CGAL_BEGIN_NAMESPACE 00043 00044 class Gmpq; 00045 00046 template<> 00047 struct Root_of_traits<Gmpz>: public CGALi::Root_of_traits_helper<Gmpz, 00048 Euclidean_ring_tag>{ 00049 typedef Gmpq RootOf_1; 00050 typedef Gmpq Root_of_1; 00051 }; 00052 00053 00054 // Algebraic structure traits 00055 template <> class Algebraic_structure_traits< Gmpz > 00056 : public Algebraic_structure_traits_base< Gmpz, 00057 Euclidean_ring_tag > { 00058 public: 00059 typedef Tag_true Is_exact; 00060 typedef Tag_false Is_numerical_sensitive; 00061 00062 typedef INTERN_AST::Is_square_per_sqrt< Type > 00063 Is_square; 00064 class Integral_division 00065 : public std::binary_function< Type, Type, 00066 Type > { 00067 public: 00068 Type operator()( const Type& x, 00069 const Type& y ) const { 00070 Gmpz result; 00071 mpz_divexact(result.mpz(), x.mpz(), y.mpz()); 00072 CGAL_postcondition_msg(result * y == x, "exact_division failed\n"); 00073 return result; 00074 } 00075 }; 00076 00077 class Gcd 00078 : public std::binary_function< Type, Type, 00079 Type > { 00080 public: 00081 Type operator()( const Type& x, 00082 const Type& y ) const { 00083 Gmpz result; 00084 mpz_gcd(result.mpz(), x.mpz(), y.mpz()); 00085 return result; 00086 00087 } 00088 00089 Type operator()( const Type& x, 00090 const int& y ) const { 00091 if (y > 0) 00092 { 00093 Gmpz Res; 00094 mpz_gcd_ui(Res.mpz(), x.mpz(), y); 00095 return Res; 00096 } 00097 return CGAL_NTS gcd(x, Gmpz(y)); 00098 } 00099 00100 Type operator()( const int& x, 00101 const Type& y ) const { 00102 return CGAL_NTS gcd(Gmpz(x), y ); 00103 } 00104 }; 00105 00106 typedef INTERN_AST::Div_per_operator< Type > Div; 00107 typedef INTERN_AST::Mod_per_operator< Type > Mod; 00108 00109 class Sqrt 00110 : public std::unary_function< Type, Type > { 00111 public: 00112 Type operator()( const Type& x ) const { 00113 Gmpz result; 00114 mpz_sqrt(result.mpz(), x.mpz()); 00115 return result; 00116 } 00117 }; 00118 }; 00119 00120 template <> class Real_embeddable_traits< Gmpz > 00121 : public INTERN_RET::Real_embeddable_traits_base< Gmpz , CGAL::Tag_true > { 00122 public: 00123 00124 class Sgn 00125 : public std::unary_function< Type, ::CGAL::Sign > { 00126 public: 00127 ::CGAL::Sign operator()( const Type& x ) const { 00128 return x.sign(); 00129 } 00130 }; 00131 00132 class To_double 00133 : public std::unary_function< Type, double > { 00134 public: 00135 double operator()( const Type& x ) const { 00136 return x.to_double(); 00137 } 00138 }; 00139 00140 class To_interval 00141 : public std::unary_function< Type, std::pair< double, double > > { 00142 public: 00143 std::pair<double, double> operator()( const Type& x ) const { 00144 00145 mpfr_t y; 00146 mpfr_init2 (y, 53); /* Assume IEEE-754 */ 00147 mpfr_set_z (y, x.mpz(), GMP_RNDD); 00148 double i = mpfr_get_d (y, GMP_RNDD); /* EXACT but can overflow */ 00149 mpfr_set_z (y, x.mpz(), GMP_RNDU); 00150 double s = mpfr_get_d (y, GMP_RNDU); /* EXACT but can overflow */ 00151 mpfr_clear (y); 00152 return std::pair<double, double>(i, s); 00153 } 00154 }; 00155 }; 00156 00157 template<> class Algebraic_structure_traits< Quotient<Gmpz> > 00158 : public INTERN_QUOTIENT::Algebraic_structure_traits_quotient_base<Quotient<Gmpz> >{ 00159 // specialization of to double functor 00160 public: 00161 typedef Quotient<Gmpz> Type; 00162 00163 struct To_double: public std::unary_function<Quotient<Gmpz>, double>{ 00164 double operator()(const Quotient<Gmpz>& quot){ 00165 mpq_t mpQ; 00166 mpq_init(mpQ); 00167 const Gmpz& n = quot.numerator(); 00168 const Gmpz& d = quot.denominator(); 00169 mpz_set(mpq_numref(mpQ), n.mpz()); 00170 mpz_set(mpq_denref(mpQ), d.mpz()); 00171 00172 mpq_canonicalize(mpQ); 00173 00174 double ret = mpq_get_d(mpQ); 00175 mpq_clear(mpQ); 00176 return ret; 00177 } 00178 }; 00179 }; 00180 00181 // 00182 // Needs_parens_as_product 00183 // 00184 template <> 00185 struct Needs_parens_as_product<Gmpz> { 00186 bool operator()(const Gmpz& x) { 00187 return CGAL_NTS is_negative(x); 00188 } 00189 }; 00190 00191 00196 template<> 00197 class Modular_traits< Gmpz > { 00198 typedef Residue RES; 00199 public: 00200 typedef Gmpz NT; 00201 typedef CGAL::Tag_true Is_modularizable; 00202 typedef Residue Residue_type; 00203 00204 struct Modular_image{ 00205 Residue_type operator()(const NT& a){ 00206 NT tmp_1(a % NT(RES::get_current_prime())); 00207 return CGAL::Residue(int(mpz_get_si(tmp_1.mpz()))); 00208 } 00209 }; 00210 struct Modular_image_representative{ 00211 NT operator()(const Residue_type& x){ 00212 return NT(x.get_value()); 00213 } 00214 }; 00215 }; 00216 00217 CGAL_END_NAMESPACE 00218 00219 #if defined(BOOST_MSVC) 00220 # pragma warning(pop) 00221 #endif 00222 00223 00224 //since types are included by Gmp_coercion_traits.h: 00225 #include <CGAL/Gmpz.h> 00226 #include <CGAL/Gmpq.h> 00227 #include <CGAL/Gmpzf.h> 00228 00229 #endif // CGAL_GMPZ_H