mirror of https://github.com/CGAL/cgal
181 lines
6.2 KiB
C++
181 lines
6.2 KiB
C++
#include <iostream>
|
|
#include <CGAL/basic.h>
|
|
#include <cassert>
|
|
|
|
#include <CGAL/Arithmetic_kernel.h>
|
|
#include <CGAL/Modular.h>
|
|
#include <CGAL/Polynomial.h>
|
|
#include <CGAL/Polynomial_traits_d.h>
|
|
#include <CGAL/Random.h>
|
|
#include <CGAL/Timer.h>
|
|
|
|
static CGAL::Random my_rnd(346); // some seed
|
|
|
|
#define CGAL_SNAP_CGALi_TRAITS_D(T) \
|
|
typedef T PT; \
|
|
typedef typename PT::Polynomial_d Polynomial_d; \
|
|
typedef typename PT::Coefficient Coeff; \
|
|
typedef typename PT::Innermost_coefficient ICoeff; \
|
|
typedef CGAL::Polynomial_traits_d<Coeff> PTC; \
|
|
typedef CGAL::Exponent_vector Exponent_vector; \
|
|
typedef std::pair< CGAL::Exponent_vector , ICoeff > Monom; \
|
|
typedef std::vector< Monom > Monom_rep;
|
|
|
|
template <class Polynomial_d_>
|
|
Polynomial_d_
|
|
generate_sparse_random_polynomial(int max_degree = 6){
|
|
typedef CGAL::Polynomial_traits_d<Polynomial_d_> PT;
|
|
CGAL_SNAP_CGALi_TRAITS_D(PT);
|
|
typename PT::Construct_polynomial construct;
|
|
|
|
|
|
typedef CGAL::Exponent_vector Exponent_vector;
|
|
typedef std::pair< CGAL::Exponent_vector , ICoeff > Monom;
|
|
typedef std::vector< Monom > Monom_rep;
|
|
|
|
int range = 20;
|
|
int number_of_variables = PT::d;
|
|
int number_of_coeffs =
|
|
CGAL::min(number_of_variables * (int)ceil(log(max_degree+1))+1,4);
|
|
|
|
Polynomial_d result;
|
|
for(int i = 0; i < number_of_coeffs; i++){
|
|
CGAL::Exponent_vector exps(PT::d);
|
|
for(int j = 0; j < PT::d; j++){
|
|
exps[j]=my_rnd.get_int(0,max_degree);
|
|
}
|
|
ICoeff c = ICoeff(my_rnd.get_int(-range,range));
|
|
Monom_rep monom_rep;
|
|
monom_rep.push_back(Monom(exps,c));
|
|
result += construct(monom_rep.begin(), monom_rep.end());
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template<class IC>
|
|
inline IC interpolate_resultant(CGAL::Polynomial<IC> F1, CGAL::Polynomial<IC> F2){
|
|
typedef CGAL::Polynomial_traits_d<CGAL::Polynomial<IC> > PT;
|
|
|
|
//std::cout << "F1 " << F1 << std::endl;
|
|
//std::cout << "F2 " << F2 << std::endl;
|
|
//std::cout << typename PT::Resultant()(F1,F2) << std::endl;
|
|
return typename PT::Resultant()(F1,F2);
|
|
}
|
|
|
|
|
|
template<class T>
|
|
inline
|
|
CGAL::Polynomial<T> interpolate_resultant(
|
|
const CGAL::Polynomial<CGAL::Polynomial<T> >& F1,
|
|
const CGAL::Polynomial<CGAL::Polynomial<T> >& F2){
|
|
|
|
typedef CGAL::Polynomial<CGAL::Polynomial<T> > POLY_d;
|
|
typedef CGAL::Polynomial_traits_d<CGAL::Polynomial<CGAL::Polynomial<T> > > PT_d;
|
|
typedef typename PT_d::Innermost_coefficient IC;
|
|
|
|
typedef CGAL::Polynomial<IC> POLY_1;
|
|
|
|
CGAL::Polynomial<T> result_pq(0);
|
|
POLY_1 pq(1);
|
|
int i = 0;
|
|
CGAL::Timer evaluate_timer;
|
|
CGAL::Timer interpolate_resultant_timer;
|
|
CGAL::Timer interpolate_timer;
|
|
|
|
while(true){
|
|
i++;
|
|
POLY_1 p(-IC(i),IC(1));
|
|
evaluate_timer.start();
|
|
CGAL::Polynomial<T> F1_at_i = typename PT_d::Evaluate()(F1,i);
|
|
CGAL::Polynomial<T> F2_at_i = typename PT_d::Evaluate()(F2,i);
|
|
evaluate_timer.stop();
|
|
|
|
interpolate_resultant_timer.start();
|
|
CGAL::Polynomial<T> result_p= interpolate_resultant(F1_at_i, F2_at_i);
|
|
interpolate_resultant_timer.stop();
|
|
POLY_1 q(pq);
|
|
CGAL::Polynomial<T> result_q= result_pq;
|
|
interpolate_timer.start();
|
|
typename CGAL::Polynomial_traits_d<CGAL::Polynomial<T> >::Interpolate()(
|
|
p, result_p,
|
|
q, result_q,
|
|
pq, result_pq);
|
|
interpolate_timer.stop();
|
|
if(result_pq == result_q) break;
|
|
else{
|
|
q = pq;
|
|
result_q = result_pq;
|
|
}
|
|
}
|
|
return result_pq;
|
|
}
|
|
|
|
|
|
template <class Coeff>
|
|
inline
|
|
Coeff my_resultant(CGAL::Polynomial<Coeff> F1, CGAL::Polynomial<Coeff> F2){
|
|
typedef CGAL::Polynomial<Coeff> POLY;
|
|
typedef CGAL::Polynomial_traits_d<POLY> PT;
|
|
POLY F1_ = typename PT::Move()(F1,PT::d-1, 0);
|
|
POLY F2_ = typename PT::Move()(F2,PT::d-1, 0);
|
|
return interpolate_resultant(F1_,F2_);
|
|
}
|
|
|
|
|
|
|
|
int main(){
|
|
|
|
CGAL::set_pretty_mode(std::cout);
|
|
|
|
typedef CGAL::CORE_arithmetic_kernel AK;
|
|
typedef AK::Integer Integer;
|
|
typedef CGAL::Polynomial<Integer> Polynomial_1;
|
|
typedef CGAL::Polynomial<Polynomial_1> Polynomial_2;
|
|
typedef CGAL::Polynomial<Polynomial_2> Polynomial_3;
|
|
Polynomial_3 F = generate_sparse_random_polynomial<Polynomial_3>();
|
|
|
|
|
|
|
|
typedef CGAL::Polynomial<CGAL::Modular> MPolynomial_1;
|
|
typedef CGAL::Polynomial<MPolynomial_1> MPolynomial_2;
|
|
typedef CGAL::Polynomial<MPolynomial_2> MPolynomial_3;
|
|
|
|
{
|
|
MPolynomial_2 F1 = CGAL::modular_image(generate_sparse_random_polynomial<Polynomial_2>(2));
|
|
MPolynomial_2 F2 = CGAL::modular_image(generate_sparse_random_polynomial<Polynomial_2>(2));
|
|
std::cout << "start gcd "<< std::endl;
|
|
std::cout << F1 << std::endl;
|
|
std::cout << F2 << std::endl;
|
|
MPolynomial_2 G = CGAL::gcd(F1,F2);
|
|
std::cout << "end gcd "<< std::endl;
|
|
F1 = CGAL::integral_division(F1,G);
|
|
F2 = CGAL::integral_division(F2,G);
|
|
|
|
//assert(CGAL::is_one(CGAL::gcd(F1,F2)));
|
|
// std::cout << CGAL::Modular_traits<Polynomial_2>::Modular_image_inv()(my_resultant(F1,F2)) << std::endl;
|
|
// assert(CGAL::Polynomial_traits_d<MPolynomial_2>::Resultant()(F1,F2) == my_resultant(F1,F2));
|
|
}
|
|
{
|
|
MPolynomial_3 F1 = CGAL::modular_image(generate_sparse_random_polynomial<Polynomial_3>(2));
|
|
MPolynomial_3 F2 = CGAL::modular_image(generate_sparse_random_polynomial<Polynomial_3>(2));
|
|
std::cout << "start gcd "<< std::endl;
|
|
//std::cout << F1 << std::endl;
|
|
//std::cout << F2 << std::endl;
|
|
MPolynomial_3 G = CGAL::gcd(F1,F2);
|
|
std::cout << "end gcd "<< std::endl;
|
|
F1 = CGAL::integral_division(F1,G);
|
|
F2 = CGAL::integral_division(F2,G);
|
|
|
|
assert(CGAL::is_one(CGAL::gcd(F1,F2)));
|
|
// std::cout << CGAL::Modular_traits<Polynomial_3>::Modular_image_inv()(my_resultant(F1,F2)) << std::endl;
|
|
assert(CGAL::Polynomial_traits_d<MPolynomial_3>::Resultant()(F1,F2) == my_resultant(F1,F2));
|
|
}
|
|
std::cout << " DONE " << std::endl;
|
|
}
|
|
|