diff --git a/Polynomial/test/Polynomial/include/CGAL/new_resultant.h b/Polynomial/test/Polynomial/include/CGAL/new_resultant.h index 61f231a20e9..0d7f9d7e2f8 100644 --- a/Polynomial/test/Polynomial/include/CGAL/new_resultant.h +++ b/Polynomial/test/Polynomial/include/CGAL/new_resultant.h @@ -10,21 +10,21 @@ CGAL_BEGIN_NAMESPACE template -inline Coeff new_resultant( CGAL::Polynomial, CGAL::Polynomial, int); +inline Coeff new_resultant( const CGAL::Polynomial&, const CGAL::Polynomial&, int); namespace CGALi{ template -inline Coeff new_resultant_interpolate( CGAL::Polynomial, CGAL::Polynomial ); +inline Coeff new_resultant_interpolate( const CGAL::Polynomial&, const CGAL::Polynomial& ); template -inline Coeff new_resultant_modularize( CGAL::Polynomial, CGAL::Polynomial, CGAL::Tag_true); +inline Coeff new_resultant_modularize( const CGAL::Polynomial&, const CGAL::Polynomial&, CGAL::Tag_true); template -inline Coeff new_resultant_modularize( CGAL::Polynomial, CGAL::Polynomial, CGAL::Tag_false); +inline Coeff new_resultant_modularize( const CGAL::Polynomial&, const CGAL::Polynomial&, CGAL::Tag_false); template -inline Coeff new_resultant_decompose( CGAL::Polynomial, CGAL::Polynomial, CGAL::Tag_true); +inline Coeff new_resultant_decompose( const CGAL::Polynomial&, const CGAL::Polynomial&, CGAL::Tag_true); template -inline Coeff new_resultant_decompose( CGAL::Polynomial, CGAL::Polynomial, CGAL::Tag_false); +inline Coeff new_resultant_decompose( const CGAL::Polynomial&, const CGAL::Polynomial&, CGAL::Tag_false); template -inline Coeff new_resultant_( CGAL::Polynomial, CGAL::Polynomial); +inline Coeff new_resultant_( const CGAL::Polynomial&, const CGAL::Polynomial&); } // namespace CGALi @@ -32,7 +32,7 @@ namespace CGALi{ template inline IC -new_resultant_interpolate( CGAL::Polynomial F, CGAL::Polynomial G){ +new_resultant_interpolate( const CGAL::Polynomial& F, const CGAL::Polynomial& G){ CGAL_precondition(CGAL::Polynomial_traits_d >::d == 1); return CGALi::resultant(F,G); } @@ -40,9 +40,8 @@ new_resultant_interpolate( CGAL::Polynomial F, CGAL::Polynomial G){ template inline CGAL::Polynomial new_resultant_interpolate( - CGAL::Polynomial > F, - CGAL::Polynomial > G, - int index = 0 ){ + const CGAL::Polynomial >& F, + const CGAL::Polynomial >& G){ typedef CGAL::Polynomial Coeff_1; typedef CGAL::Polynomial POLY; @@ -50,59 +49,65 @@ CGAL::Polynomial new_resultant_interpolate( typedef typename PT::Innermost_coefficient IC; CGAL_precondition(PT::d >= 2); - - CGAL_precondition(index >= 0); - CGAL_precondition(index < PT::d); - - POLY F_ = typename PT::Move()(F, index, 0); - POLY G_ = typename PT::Move()(G, index, 0); - CGAL_postcondition(index != 0 || F_ == F); typename PT::Degree degree; - int maxdegree = degree(F_,0)*degree(G_,PT::d-1) + degree(F_,PT::d-1)*degree(G_,0); + typename CGAL::Polynomial_traits_d::Degree_vector degree_vector; + + int maxdegree = degree(F,0)*degree(G,PT::d-1) + degree(F,PT::d-1)*degree(G,0); typedef std::pair Point; std::vector points; // interpolation points - - typename CGAL::Polynomial_traits_d::Degree_vector degree_vector; - + + int i(0); CGAL::Exponent_vector ev_f(degree_vector(Coeff_1())); CGAL::Exponent_vector ev_g(degree_vector(Coeff_1())); + + while((int) points.size() <= maxdegree + 1){ i++; - Coeff_1 F_at_i = typename PT::Evaluate()(F_,IC(i)); - Coeff_1 G_at_i = typename PT::Evaluate()(G_,IC(i)); - if(degree_vector(F_at_i) > ev_f || degree_vector(G_at_i) > ev_g){ + // timer1.start(); + Coeff_1 Fat_i = F.evaluate(Coeff_1(i)); + Coeff_1 Gat_i = G.evaluate(Coeff_1(i)); + // timer1.stop(); + + if(degree_vector(Fat_i) > ev_f || degree_vector(Gat_i) > ev_g){ points.clear(); - ev_f = degree_vector(F_at_i); - ev_g = degree_vector(G_at_i); + ev_f = degree_vector(Fat_i); + ev_g = degree_vector(Gat_i); CGAL_postcondition(points.size() == 0); } - if(degree_vector(F_at_i) == ev_f && degree_vector(G_at_i) == ev_g){ - Coeff_2 res_at_i = new_resultant(F_at_i, G_at_i, 0); + if(degree_vector(Fat_i) == ev_f && degree_vector(Gat_i) == ev_g){ + // timer2.start(); + Coeff_2 res_at_i = new_resultant_interpolate(Fat_i, Gat_i); + // timer2.stop(); points.push_back(Point(IC(i),res_at_i)); - } + } } - Coeff_1 result = CGAL::Interpolator(points.begin(),points.end()).get_interpolant(); - + + // timer3.start(); + CGAL::Interpolator interpolator(points.begin(),points.end()); + Coeff_1 result = interpolator.get_interpolant(); + // timer3.stop(); + #ifndef CGAL_NDEBUG while((int) points.size() <= maxdegree + 3){ i++; - Coeff_1 F_at_i = typename PT::Evaluate()(F_,IC(i)); - Coeff_1 G_at_i = typename PT::Evaluate()(G_,IC(i)); + Coeff_1 Fat_i = typename PT::Evaluate()(F,IC(i)); + Coeff_1 Gat_i = typename PT::Evaluate()(G,IC(i)); - assert(degree_vector(F_at_i) <= ev_f); - assert(degree_vector(G_at_i) <= ev_g); + assert(degree_vector(Fat_i) <= ev_f); + assert(degree_vector(Gat_i) <= ev_g); - if(degree_vector(F_at_i) == ev_f && degree_vector(G_at_i) == ev_g){ - Coeff_2 res_at_i = new_resultant(F_at_i, G_at_i, 0); + if(degree_vector(Fat_i) == ev_f && degree_vector(Gat_i) == ev_g){ + Coeff_2 res_at_i = new_resultant(Fat_i, Gat_i, 0); points.push_back(Point(IC(i), res_at_i)); } } + CGAL::Interpolator interpolator_(points.begin(),points.end()); + Coeff_1 result_= interpolator_.get_interpolant(); - Coeff_1 result_ = CGAL::Interpolator(points.begin(), points.end()).get_interpolant(); - // the interpolate polynomial has to be stable ! + // the interpolate polynomial has to be stable ! assert(result_ == result); #endif return result; @@ -112,31 +117,119 @@ CGAL::Polynomial new_resultant_interpolate( template inline Coeff new_resultant_modularize( - CGAL::Polynomial F, CGAL::Polynomial G, CGAL::Tag_false){ + const CGAL::Polynomial& F, const CGAL::Polynomial& G, CGAL::Tag_false){ return new_resultant_interpolate(F,G); -} +}; template inline Coeff new_resultant_modularize( - CGAL::Polynomial F, CGAL::Polynomial G, CGAL::Tag_true){ - return new_resultant_interpolate(F,G); + const CGAL::Polynomial& F, const CGAL::Polynomial& G, CGAL::Tag_true){ + + typedef Polynomial_traits_d > PT; + typedef typename PT::Polynomial_d Polynomial; + typedef typename PT::Innermost_coefficient IC; + + + typedef Chinese_remainder_traits CRT; + typedef typename CRT::Scalar_type Scalar; + + + typedef typename CGAL::Modular_traits::Modular_NT MPolynomial; + typedef typename CGAL::Modular_traits::Modular_NT MCoeff; + typedef typename CGAL::Modular_traits::Modular_NT MScalar; + + typename CRT::Chinese_remainder chinese_remainder; + typename CGAL::Modular_traits::Modular_image_inv inv_map; + + + typename PT::Degree_vector degree_vector; + typename CGAL::Polynomial_traits_d::Degree_vector mdegree_vector; + + bool solved = false; + int prime_index = 0; + int n = 0; + Scalar p,q,pq,s,t; + Coeff R, R_old; + + CGAL::Timer timer_evaluate, timer_resultant, timer_cr; + + do{ + MPolynomial mF, mG; + MCoeff mR; + timer_evaluate.start(); + do{ + // select a prime number + int current_prime = -1; + prime_index++; + if(prime_index >= 2000){ + std::cerr<<"primes in the array exhausted"< ceea; + ceea(q,p,s,t); + pq =p*q; + chinese_remainder(q,p,pq,s,t,R_old,inv_map(mR),R); + q=pq; + } + solved = (R==R_old); + timer_cr.stop(); + } while(!solved); + + std::cout << "Time Evaluate : " << timer_evaluate.time() << std::endl; + std::cout << "Time Resultant : " << timer_resultant.time() << std::endl; + std::cout << "Time Chinese R : " << timer_cr.time() << std::endl; + // CGAL_postcondition(R == new_resultant_interpolate(F,G)); + return R; + // return new_resultant_interpolate(F,G); } template inline Coeff new_resultant_decompose( - CGAL::Polynomial F, CGAL::Polynomial G, CGAL::Tag_false){ + const CGAL::Polynomial& F, const CGAL::Polynomial& G, CGAL::Tag_false){ +#ifdef CGAL_RESULTANT_NUSE_MODULAR_ARITHMETIC + return new_resultant_modularize(F,G,CGAL::Tag_false()); +#else typedef CGAL::Polynomial Polynomial; typedef typename Modular_traits::Is_modularizable Is_modularizable; return new_resultant_modularize(F,G,Is_modularizable()); +#endif } template inline Coeff new_resultant_decompose( - CGAL::Polynomial F, CGAL::Polynomial G, CGAL::Tag_true){ + const CGAL::Polynomial& F, const CGAL::Polynomial& G, CGAL::Tag_true){ typedef Polynomial POLY; typedef typename Fraction_traits::Numerator_type Numerator; @@ -163,7 +256,7 @@ Coeff new_resultant_decompose( template inline Coeff new_resultant_( - CGAL::Polynomial F, CGAL::Polynomial G){ + const CGAL::Polynomial& F, const CGAL::Polynomial& G){ typedef CGAL::Fraction_traits > FT; typedef typename FT::Is_fraction Is_fraction; return new_resultant_decompose(F,G,Is_fraction()); @@ -175,13 +268,13 @@ Coeff new_resultant_( template inline Coeff new_resultant( - CGAL::Polynomial F, - CGAL::Polynomial G, + const CGAL::Polynomial& F_, + const CGAL::Polynomial& G_, int index = CGAL::Polynomial_traits_d< CGAL::Polynomial >::d-1){ typedef CGAL::Polynomial_traits_d > PT; - CGAL::Polynomial F_ = typename PT::Move()(F, index, 0); - CGAL::Polynomial G_ = typename PT::Move()(G, index, 0); - return CGALi::new_resultant_(F_,G_); + CGAL::Polynomial F = typename PT::Move()(F_, index, 0); + CGAL::Polynomial G = typename PT::Move()(G_, index, 0); + return CGALi::new_resultant_(F,G); } CGAL_END_NAMESPACE diff --git a/Polynomial/test/Polynomial/resultant.cpp b/Polynomial/test/Polynomial/resultant.cpp new file mode 100644 index 00000000000..bc62327857d --- /dev/null +++ b/Polynomial/test/Polynomial/resultant.cpp @@ -0,0 +1,130 @@ + +// #define CGAL_RESULTANT_NUSE_MODULAR_ARITHMETIC 1 + +#include + +#include +CGAL::Timer timer1, timer2, timer3; + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + + +static CGAL::Random my_rnd(346); // some seed + +template +void test_resultant(){ + + typedef typename CGAL::Polynomial_traits_d PT; + typedef typename PT::Coefficient Coeff; + for (int k = 0; k < 1; k++){ + Polynomial_d F2 = + CGAL::generate_sparse_random_polynomial(my_rnd,12); + Polynomial_d F1 = + CGAL::generate_sparse_random_polynomial(my_rnd,12); + Polynomial_d G1 = typename PT::Move()(F1,PT::d-1,0); + Polynomial_d G2 = typename PT::Move()(F2,PT::d-1,0); + + CGAL::Timer timer_new; + timer_new.start(); + Coeff F = CGAL::new_resultant(F1,F2,PT::d-1); + // Coeff G = CGAL::new_resultant(G1,G2,0); + timer_new.stop(); + + assert(F==F); + std::cout <<"timer1: "<< timer1.time() << std::endl; + std::cout <<"timer2: "<< timer2.time() << std::endl; + std::cout <<"timer3: "<< timer3.time() << std::endl; + timer1.reset(); + timer2.reset(); + timer3.reset(); + std::cout <<"new time: "<< timer_new.time() << std::endl; + } + std::cout << "end resultant: " << PT::d << std::endl; +} + + +template +void test_multi_resultant(){ + + typedef CGAL::Polynomial Polynomial_1; + typedef CGAL::Polynomial Polynomial_2; + typedef CGAL::Polynomial Polynomial_3; + + Polynomial_3 Q = + CGAL::generate_polynomial_degree_each(my_rnd,4,100); + Polynomial_2 B1 = + CGAL::generate_polynomial_degree_each(my_rnd,6,80); + Polynomial_2 B2 = + CGAL::generate_polynomial_degree_each(my_rnd,6,80); + std::cout << "Q: "<< Q << std::endl; + std::cout << "B1: "<< B1 << std::endl; + std::cout << "B2: "<< B2 < Polynomial_1; + typedef CGAL::Polynomial Polynomial_2; + typedef CGAL::Polynomial Polynomial_3; + + test_multi_resultant(); + + // test_resultant(); + // test_resultant(); + //test_resultant(); + + + typedef CGAL::Polynomial MPolynomial_1; + typedef CGAL::Polynomial MPolynomial_2; + typedef CGAL::Polynomial MPolynomial_3; + + //test_resultant(); + //test_resultant(); + //test_resultant(); + + typedef CGAL::Polynomial RPolynomial_1; + typedef CGAL::Polynomial RPolynomial_2; + typedef CGAL::Polynomial RPolynomial_3; + + //test_resultant(); + //test_resultant(); + //test_resultant(); +} + + +