cgal/Algebraic_foundations/test/Algebraic_foundations/Chinese_remainder_traits.cpp

180 lines
5.5 KiB
C++
Raw Blame History

// ============================================================================
//
// Copyright (c) 2001-2006 Max-Planck-Institut Saarbruecken (Germany).
// All rights reserved.
//
// This file is part of EXACUS (http://www.mpi-inf.mpg.de/projects/EXACUS/).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// ----------------------------------------------------------------------------
//
// Library : CGAL
// File : test/Chinese_remaminder_test.C
// CGAL_release : $Name: $
// Revision : $Revision$
// Revision_date : $Date$
//
// Author(s) : Dominik H<>lse <dominik.huelse@gmx.de>
// Michael Hemmer <hemmer@mpi-inf.mpg.de>
//
// ============================================================================
#undef NDEBUG
#include <CGAL/basic.h>
#include <CGAL/Chinese_remainder_traits.h>
#include <CGAL/Arithmetic_kernel.h>
#include <CGAL/CORE_arithmetic_kernel.h>
#include <CGAL/LEDA_arithmetic_kernel.h>
#include <CGAL/Polynomial.h>
#include <CGAL/Residue.h>
#include <CGAL/Sqrt_extension.h>
#include <CGAL/primes.h>
#include <CGAL/use.h>
#include <cassert>
//#define WITH_OUTPUT 1
template <class NT>
struct Get_max_coefficient{
typedef NT result_type;
result_type operator () (const NT& a) {
return CGAL::abs(a);
}
};
template <class NT, class Root,class ACDE_TAG, class FP_TAG>
struct Get_max_coefficient<CGAL::Sqrt_extension<NT, Root, ACDE_TAG, FP_TAG> >{
typedef Get_max_coefficient<NT> GMC;
typedef typename GMC::result_type result_type;
result_type operator () (const CGAL::Sqrt_extension<NT, Root, ACDE_TAG, FP_TAG>& a) {
GMC gmc;
return (std::max)((std::max)(gmc(a.a0()), gmc(a.a1())), gmc(NT(a.root())));
}
};
template <class NT>
struct Get_max_coefficient<CGAL::Polynomial<NT> >{
typedef Get_max_coefficient<NT> GMC;
typedef typename GMC::result_type result_type;
result_type operator () (const CGAL::Polynomial<NT>& a) {
GMC gmc;
result_type m=0;
for(int i=0; i<=a.degree(); i++){
m = (std::max)(gmc(a[i]),m);
}
return m;
}
};
template<class NT>
void test_CR_for(const NT& f){
// Enforce IEEE double precision before using modular arithmetic
CGAL::Set_ieee_double_precision pfr;
typedef CGAL::Modular_traits<NT> MT;
CGAL_USE_TYPE(typename CGAL::Modular_traits<NT>::Residue_type);
typename MT::Modular_image modular_image;
typename MT::Modular_image_representative modular_image_representative;
typedef CGAL::Chinese_remainder_traits<NT> CRT;
typedef typename CRT::Scalar_type Scalar_type;
typename CRT::Chinese_remainder chinese_remainder;
Scalar_type max_coeff = Get_max_coefficient<NT>()(f);
NT g, g_old;
Scalar_type p,q,pq;
int prime_index, current_prime;
bool test = true;
prime_index = 0;
// init chinese remainder
q = current_prime = CGAL::internal::primes[prime_index];
CGAL::Residue::set_current_prime(current_prime);
g_old = modular_image_representative(modular_image(f));
pq= p = q;
// try chinese remainder
do{
// chinese remainder failed if q > 2*max_coeff(f)
CGAL_postcondition_msg(pq < p*(2*max_coeff), " chinese remainder failed ");
prime_index++;
if(prime_index < 1000){
current_prime = CGAL::internal::primes[prime_index];
}
else{
std::cerr<<"primes in the array exhausted"<<std::endl;
current_prime = CGAL::internal::get_next_lower_prime(current_prime);
}
CGAL::Residue::set_current_prime(current_prime);
p = current_prime;
chinese_remainder(q,g_old,p,modular_image_representative(modular_image(f)),pq,g);
try{
test = g != g_old;
}catch(...){}
q = pq;
g_old = g;
}while(test);
assert( g == f );
}
template<class AT>
void test_CR() {
typedef typename AT::Integer Integer;
typedef CGAL::Sqrt_extension<Integer,Integer> EXT;
typedef CGAL::Polynomial<Integer> Poly;
test_CR_for(Integer("13472398473248763214987"));
test_CR_for(EXT(
Integer("13472398473248763214987"),
Integer("43857430987524589"),
Integer("84397984359843")));
test_CR_for(EXT(
Integer("13472398473248763214987"),
Integer("0"),
Integer("84397984359843")));
test_CR_for(Poly(
Integer("13472398473248763214987"),
Integer("-43857430987524589"),
Integer("84397984359843")));
}
int main(){
#ifdef CGAL_USE_LEDA
test_CR<CGAL::LEDA_arithmetic_kernel>();
#endif // CGAL_USE_LEDA
#ifdef CGAL_USE_CORE
test_CR<CGAL::CORE_arithmetic_kernel>();
#endif // Lis_HAVE_CORE
return 0;
}
// EOF