diff --git a/Modular_arithmetic/test/Modular_arithmetic/Modular_traits.cpp b/Modular_arithmetic/test/Modular_arithmetic/Modular_traits.cpp index 1918898da6a..cd025a302e3 100644 --- a/Modular_arithmetic/test/Modular_arithmetic/Modular_traits.cpp +++ b/Modular_arithmetic/test/Modular_arithmetic/Modular_traits.cpp @@ -10,21 +10,35 @@ #include #include #include +#include +#include +#include +//#include + #ifdef CGAL_USE_LEDA #include #include #endif // CGAL_USE_LEDA + #ifdef CGAL_USE_CORE #include #include #endif // CGAL_USE_CORE +#ifdef CGAL_USE_GMP +#include +#include +#include +#include +#endif // CGAL_USE_GMP + + + #include #include - template void test_modular_traits(){ @@ -32,35 +46,91 @@ void test_modular_traits(){ typedef CGAL::Modular_traits MT; typedef typename MT::Residue_type Residue_type; typedef typename MT::Modular_image Modular_image; + typedef typename MT::Modular_image_inv Modular_image_inv; typedef typename MT::Is_modularizable Is_modularizable; typedef typename MT::NT NT; assert( - !(::boost::is_same::value)); + !(::boost::is_same::value)); assert( - (::boost::is_same::value)); + !(::boost::is_same::value)); assert( - (::boost::is_same::value)); + (::boost::is_same::value)); + assert( + (::boost::is_same::value)); Residue::set_current_prime(7); Modular_image modular_image; + assert(modular_image(TESTT(10)+TESTT(10)) == Residue_type(-1)); + assert(modular_image(TESTT(2) *TESTT(10)) == Residue_type(-1)); + assert(modular_image(TESTT(20)) == Residue_type(-1)); + assert(modular_image(TESTT(20)) == Residue_type(6)); assert(modular_image(TESTT(21)) == Residue_type(0)); assert(modular_image(TESTT(22)) == Residue_type(1)); assert(modular_image(TESTT(777777722)) == Residue_type(1)); + + Modular_image_inv modular_image_inv; + assert(modular_image_inv(modular_image(TESTT(20))) + == TESTT(-1)); } int main() { test_modular_traits(); + #ifdef CGAL_USE_LEDA test_modular_traits(); test_modular_traits(); - test_modular_traits >(); + test_modular_traits >(); + test_modular_traits >(); + test_modular_traits >(); + test_modular_traits >(); + test_modular_traits >(); #endif #ifdef CGAL_USE_CORE test_modular_traits(); test_modular_traits(); - test_modular_traits >(); + test_modular_traits >(); + test_modular_traits >(); + test_modular_traits >(); + test_modular_traits >(); + test_modular_traits >(); #endif +#ifdef CGAL_USE_GMP + test_modular_traits(); + test_modular_traits(); + test_modular_traits< mpz_class >(); + test_modular_traits< mpq_class >(); +#endif + + // test Sqrt_extension + test_modular_traits >(); + assert( + (!CGAL::Modular_traits > + ::Is_modularizable::value)); + + // test Polynomial + test_modular_traits >(); + assert( + !CGAL::Modular_traits > + ::Is_modularizable::value); + + // test Quotient + test_modular_traits >(); + assert( + !CGAL::Modular_traits > + ::Is_modularizable::value); + assert( + !CGAL::Modular_traits > > + ::Is_modularizable::value); + + // test_modular_traits(); + + test_modular_traits< CGAL::Lazy_exact_nt >(); + assert( + !CGAL::Modular_traits > + ::Is_modularizable::value); + + } diff --git a/Number_types/include/CGAL/CORE_BigRat.h b/Number_types/include/CGAL/CORE_BigRat.h index 952a4079eb5..6cea75761e1 100644 --- a/Number_types/include/CGAL/CORE_BigRat.h +++ b/Number_types/include/CGAL/CORE_BigRat.h @@ -161,20 +161,25 @@ public: */ template<> class Modular_traits< ::CORE::BigRat > { - typedef ::CORE::BigInt Integer; - typedef Modular_traits MT_int; + typedef ::CORE::BigInt Integer; + typedef Modular_traits MT_int; public: - typedef ::CORE::BigRat NT; - typedef ::CGAL::Tag_true Is_modularizable; - typedef CGAL::Residue Residue_type; - struct Modular_image{ - Residue_type operator()(const NT& rat){ - MT_int::Modular_image int_mod; - Residue_type num = int_mod(CGAL_CORE_NUMERATOR(rat)); - Residue_type den = int_mod(CGAL_CORE_DENOMINATOR(rat)); - return num/den; - } - }; + typedef ::CORE::BigRat NT; + typedef ::CGAL::Tag_true Is_modularizable; + typedef CGAL::Residue Residue_type; + struct Modular_image{ + Residue_type operator()(const NT& rat){ + MT_int::Modular_image int_mod; + Residue_type num = int_mod(CGAL_CORE_NUMERATOR(rat)); + Residue_type den = int_mod(CGAL_CORE_DENOMINATOR(rat)); + return num/den; + } + }; + struct Modular_image_inv{ + NT operator()(const Residue_type& x){ + return NT(x.get_value()); + } + }; }; diff --git a/Number_types/include/CGAL/Gmpq.h b/Number_types/include/CGAL/Gmpq.h index 85fecbd717d..d6509a67373 100644 --- a/Number_types/include/CGAL/Gmpq.h +++ b/Number_types/include/CGAL/Gmpq.h @@ -24,6 +24,7 @@ #include #include #include +#include CGAL_BEGIN_NAMESPACE @@ -132,6 +133,33 @@ public: }; }; +/*! \ingroup NiX_Modular_traits_spec + * \brief a model of concept ModularTraits, + * specialization of NiX::Modular_traits. + */ +template<> +class Modular_traits< Gmpq > { +public: + typedef Gmpq NT; + typedef CGAL::Tag_true Is_modularizable; + typedef Residue Residue_type; + + struct Modular_image{ + Residue_type operator()(const NT& a){ + Gmpz num(a.numerator() % Residue::get_current_prime() ); + Gmpz den(a.denominator() % Residue::get_current_prime() ); + Residue num_m (CGAL::Residue(int(mpz_get_si(num.mpz())))); + Residue den_m (CGAL::Residue(int(mpz_get_si(den.mpz())))); + return num_m / den_m; + } + }; + struct Modular_image_inv{ + NT operator()(const Residue_type& x){ + return NT(x.get_value()); + } + }; +}; + CGAL_END_NAMESPACE //since types are included by Gmp_coercion_traits.h: diff --git a/Number_types/include/CGAL/Gmpz.h b/Number_types/include/CGAL/Gmpz.h index b597802b2a3..c0990eb10d6 100644 --- a/Number_types/include/CGAL/Gmpz.h +++ b/Number_types/include/CGAL/Gmpz.h @@ -37,6 +37,7 @@ #include #include +#include CGAL_BEGIN_NAMESPACE @@ -187,6 +188,32 @@ struct Needs_parens_as_product { } }; + +/*! \ingroup NiX_Modular_traits_spec + * \brief a model of concept ModularTraits, + * specialization of NiX::Modular_traits. + */ +template<> +class Modular_traits< Gmpz > { + typedef Residue RES; + public: + typedef Gmpz NT; + typedef CGAL::Tag_true Is_modularizable; + typedef Residue Residue_type; + + struct Modular_image{ + Residue_type operator()(const NT& a){ + NT tmp_1(a % NT(RES::get_current_prime())); + return CGAL::Residue(int(mpz_get_si(tmp_1.mpz()))); + } + }; + struct Modular_image_inv{ + NT operator()(const Residue_type& x){ + return NT(x.get_value()); + } + }; +}; + CGAL_END_NAMESPACE #if defined(BOOST_MSVC) diff --git a/Number_types/include/CGAL/Lazy_exact_nt.h b/Number_types/include/CGAL/Lazy_exact_nt.h index 35ece0937a9..b1e4174a582 100644 --- a/Number_types/include/CGAL/Lazy_exact_nt.h +++ b/Number_types/include/CGAL/Lazy_exact_nt.h @@ -1354,6 +1354,46 @@ print(std::ostream &os, const CGAL::Lazy_exact_nt< Root_of_2 > &r) print(os,r.exact()); } +namespace INTERN_LAZY_EXACT_NT { +template< typename ET , typename Tag> +class Modular_traits_base{ +public: + typedef Lazy_exact_nt NT; + typedef ::CGAL::Tag_false Is_modularizable; + typedef ::CGAL::Null_functor Residue_type; + typedef ::CGAL::Null_functor Modular_image; + typedef ::CGAL::Null_functor Modular_image_inv; +}; + +template< typename ET > +class Modular_traits_base{ + typedef Modular_traits MT_ET; +public: + typedef Lazy_exact_nt NT; + typedef CGAL::Tag_true Is_modularizable; + typedef typename MT_ET::Residue_type Residue_type; + + struct Modular_image{ + Residue_type operator()(const NT& a){ + typename MT_ET::Modular_image modular_image; + return modular_image(a.exact()); + } + }; + struct Modular_image_inv{ + NT operator()(const Residue_type& x){ + typename MT_ET::Modular_image_inv modular_image_inv; + return NT(modular_image_inv(x)); + } + }; +}; +} // namespace INTERN_LAZY_EXACT_NT + +template < typename ET > +class Modular_traits > + :public INTERN_LAZY_EXACT_NT::Modular_traits_base +::Is_modularizable>{}; + + #undef CGAL_double #undef CGAL_int #undef CGAL_To_interval diff --git a/Number_types/include/CGAL/Quotient.h b/Number_types/include/CGAL/Quotient.h index e43e8800f05..be6d9a3946a 100644 --- a/Number_types/include/CGAL/Quotient.h +++ b/Number_types/include/CGAL/Quotient.h @@ -29,6 +29,7 @@ // The include is done before the protect macro on purpose, because // of a cyclic dependency. + #include #ifndef CGAL_QUOTIENT_H @@ -41,6 +42,7 @@ #include #include +#include CGAL_BEGIN_NAMESPACE @@ -867,6 +869,61 @@ public: }; }; +//fwd +class Residue; + +namespace CGALi{ + +template +struct Quotient_modular_traits_base{ + typedef Quotient NT; + typedef ::CGAL::Tag_false Is_modularizable; + typedef ::CGAL::Null_functor Residue_type; + typedef ::CGAL::Null_functor Modular_image; + typedef ::CGAL::Null_functor Modular_image_inv; +}; + +template +class Quotient_modular_traits_base{ +public: + typedef Quotient NT; + typedef CGAL::Tag_true Is_modularizable; + typedef Residue Residue_type; + + struct Modular_image{ + Residue_type operator()(const NT& a){ + typedef CGAL::Modular_traits MT_RT; + typename MT_RT::Modular_image modular_image; + typename MT_RT::Residue_type num(modular_image(a.numerator())); + typename MT_RT::Residue_type den(modular_image(a.denominator())); + return num / den; + } + }; + struct Modular_image_inv{ + NT operator()(const Residue_type& x){ + return NT(x.get_value()); + } + }; +}; + +template +struct Quotient_is_modularizable{ +private: + typedef typename Modular_traits::Residue_type Residue_type; + typedef Algebraic_structure_traits AST; + typedef typename AST::Algebraic_category Algebraic_category; + typedef CGAL::is_same_or_derived Is_field; +public: + typedef CGAL::Boolean_tag Type; +}; + +} // namespace CGALi + +template +class Modular_traits > + :public CGALi::Quotient_modular_traits_base + ::Type>{}; + CGAL_END_NAMESPACE #endif // CGAL_QUOTIENT_H diff --git a/Number_types/include/CGAL/leda_rational.h b/Number_types/include/CGAL/leda_rational.h index 9db3876316e..3e96ce0113d 100644 --- a/Number_types/include/CGAL/leda_rational.h +++ b/Number_types/include/CGAL/leda_rational.h @@ -205,21 +205,26 @@ public: // Modular_traits template<> class Modular_traits< ::leda::rational > { - typedef ::leda::integer Integer; - typedef CGAL::Modular_traits MT_int; + typedef ::leda::integer Integer; + typedef CGAL::Modular_traits MT_int; public: - typedef ::leda::rational NT; - typedef ::CGAL::Tag_true Is_modularizable; - typedef CGAL::Residue Residue_type; + typedef ::leda::rational NT; + typedef ::CGAL::Tag_true Is_modularizable; + typedef CGAL::Residue Residue_type; - struct Modular_image{ - Residue_type operator()(const NT& rat){ - MT_int::Modular_image int_mod; - Residue_type num = int_mod(rat.numerator()); - Residue_type den = int_mod(rat.denominator()); - return num/den; - } - }; + struct Modular_image{ + Residue_type operator()(const NT& rat){ + MT_int::Modular_image int_mod; + Residue_type num = int_mod(rat.numerator()); + Residue_type den = int_mod(rat.denominator()); + return num/den; + } + }; + struct Modular_image_inv{ + NT operator()(const Residue_type& x){ + return NT(x.get_value()); + } + }; }; diff --git a/Number_types/include/CGAL/mpq_class.h b/Number_types/include/CGAL/mpq_class.h index d9466408941..1854e7360ff 100644 --- a/Number_types/include/CGAL/mpq_class.h +++ b/Number_types/include/CGAL/mpq_class.h @@ -284,6 +284,31 @@ public: }; }; +template<> +class Modular_traits< mpq_class > { +public: + typedef mpq_class NT; + typedef CGAL::Tag_true Is_modularizable; + typedef Residue Residue_type; + + struct Modular_image{ + Residue_type operator()(const mpq_class& a){ + typedef Fraction_traits FT; + mpz_class num, den; + FT::Decompose()(a,num,den); + mpz_class prime(Residue::get_current_prime()); + CGAL::Residue num_m(int(mpz_get_si(CGAL::mod(num,prime).get_mpz_t()))); + CGAL::Residue den_m(int(mpz_get_si(CGAL::mod(den,prime).get_mpz_t()))); + return num_m/den_m; + } + }; + struct Modular_image_inv{ + NT operator()(const Residue_type& x){ + return NT(x.get_value()); + } + }; +}; + CGAL_END_NAMESPACE #undef CGAL_CHECK_GMP_EXPR diff --git a/Number_types/include/CGAL/mpz_class.h b/Number_types/include/CGAL/mpz_class.h index 37c2f94781e..ac8b0763e03 100644 --- a/Number_types/include/CGAL/mpz_class.h +++ b/Number_types/include/CGAL/mpz_class.h @@ -26,6 +26,7 @@ #include #include +#include // This file gathers the necessary adaptors so that the following @@ -293,6 +294,30 @@ public: }; }; +/*! \ingroup NiX_Modular_traits_spec + * \brief a model of concept ModularTraits, + * specialization of NiX::Modular_traits. + */ +template<> +class Modular_traits< mpz_class > { +public: + typedef mpz_class NT; + typedef CGAL::Tag_true Is_modularizable; + typedef Residue Residue_type; + + struct Modular_image{ + Residue_type operator()(const mpz_class& a){ + NT tmp(CGAL::mod(a,NT(Residue::get_current_prime()))); + return CGAL::Residue(int(mpz_get_si(tmp.get_mpz_t()))); + } + }; + struct Modular_image_inv{ + NT operator()(const Residue_type& x){ + return NT(x.get_value()); + } + }; +}; + template <> struct Split_double