mirror of https://github.com/CGAL/cgal
content moved in CGAL/Polynomial/resultant.h
This commit is contained in:
parent
6c14aba3be
commit
4a45b97fa2
|
|
@ -1,285 +0,0 @@
|
||||||
#ifndef CGAL_NEW_RESULTANT_H
|
|
||||||
#define CGAL_NEW_RESULTANT_H
|
|
||||||
|
|
||||||
#include <CGAL/basic.h>
|
|
||||||
#include <CGAL/Polynomial.h>
|
|
||||||
#include <CGAL/Polynomial_traits_d.h>
|
|
||||||
#include <CGAL/Interpolator.h>
|
|
||||||
#include <CGAL/Polynomial/resultant.h>
|
|
||||||
|
|
||||||
CGAL_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
template <class Coeff>
|
|
||||||
inline Coeff new_resultant( const CGAL::Polynomial<Coeff>&, const CGAL::Polynomial<Coeff>&, int);
|
|
||||||
namespace CGALi{
|
|
||||||
|
|
||||||
template <class Coeff>
|
|
||||||
inline Coeff new_resultant_interpolate( const CGAL::Polynomial<Coeff>&, const CGAL::Polynomial<Coeff>& );
|
|
||||||
template <class Coeff>
|
|
||||||
inline Coeff new_resultant_modularize( const CGAL::Polynomial<Coeff>&, const CGAL::Polynomial<Coeff>&, CGAL::Tag_true);
|
|
||||||
template <class Coeff>
|
|
||||||
inline Coeff new_resultant_modularize( const CGAL::Polynomial<Coeff>&, const CGAL::Polynomial<Coeff>&, CGAL::Tag_false);
|
|
||||||
template <class Coeff>
|
|
||||||
inline Coeff new_resultant_decompose( const CGAL::Polynomial<Coeff>&, const CGAL::Polynomial<Coeff>&, CGAL::Tag_true);
|
|
||||||
template <class Coeff>
|
|
||||||
inline Coeff new_resultant_decompose( const CGAL::Polynomial<Coeff>&, const CGAL::Polynomial<Coeff>&, CGAL::Tag_false);
|
|
||||||
template <class Coeff>
|
|
||||||
inline Coeff new_resultant_( const CGAL::Polynomial<Coeff>&, const CGAL::Polynomial<Coeff>&);
|
|
||||||
|
|
||||||
} // namespace CGALi
|
|
||||||
|
|
||||||
namespace CGALi{
|
|
||||||
|
|
||||||
template <class IC>
|
|
||||||
inline IC
|
|
||||||
new_resultant_interpolate( const CGAL::Polynomial<IC>& F, const CGAL::Polynomial<IC>& G){
|
|
||||||
CGAL_precondition(CGAL::Polynomial_traits_d<CGAL::Polynomial<IC> >::d == 1);
|
|
||||||
return CGALi::resultant(F,G);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Coeff_2>
|
|
||||||
inline
|
|
||||||
CGAL::Polynomial<Coeff_2> new_resultant_interpolate(
|
|
||||||
const CGAL::Polynomial<CGAL::Polynomial<Coeff_2> >& F,
|
|
||||||
const CGAL::Polynomial<CGAL::Polynomial<Coeff_2> >& G){
|
|
||||||
|
|
||||||
typedef CGAL::Polynomial<Coeff_2> Coeff_1;
|
|
||||||
typedef CGAL::Polynomial<Coeff_1> POLY;
|
|
||||||
typedef CGAL::Polynomial_traits_d<POLY> PT;
|
|
||||||
typedef typename PT::Innermost_coefficient IC;
|
|
||||||
|
|
||||||
CGAL_precondition(PT::d >= 2);
|
|
||||||
|
|
||||||
typename PT::Degree degree;
|
|
||||||
typename CGAL::Polynomial_traits_d<Coeff_1>::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<IC,Coeff_2> Point;
|
|
||||||
std::vector<Point> points; // interpolation points
|
|
||||||
|
|
||||||
|
|
||||||
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++;
|
|
||||||
// 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(Fat_i);
|
|
||||||
ev_g = degree_vector(Gat_i);
|
|
||||||
CGAL_postcondition(points.size() == 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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// timer3.start();
|
|
||||||
CGAL::Interpolator<Coeff_1> 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 Fat_i = typename PT::Evaluate()(F,IC(i));
|
|
||||||
Coeff_1 Gat_i = typename PT::Evaluate()(G,IC(i));
|
|
||||||
|
|
||||||
assert(degree_vector(Fat_i) <= ev_f);
|
|
||||||
assert(degree_vector(Gat_i) <= ev_g);
|
|
||||||
|
|
||||||
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<Coeff_1> interpolator_(points.begin(),points.end());
|
|
||||||
Coeff_1 result_= interpolator_.get_interpolant();
|
|
||||||
|
|
||||||
// the interpolate polynomial has to be stable !
|
|
||||||
assert(result_ == result);
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Coeff>
|
|
||||||
inline
|
|
||||||
Coeff new_resultant_modularize(
|
|
||||||
const CGAL::Polynomial<Coeff>& F, const CGAL::Polynomial<Coeff>& G, CGAL::Tag_false){
|
|
||||||
return new_resultant_interpolate(F,G);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Coeff>
|
|
||||||
inline
|
|
||||||
Coeff new_resultant_modularize(
|
|
||||||
const CGAL::Polynomial<Coeff>& F, const CGAL::Polynomial<Coeff>& G, CGAL::Tag_true){
|
|
||||||
|
|
||||||
typedef Polynomial_traits_d<CGAL::Polynomial<Coeff> > PT;
|
|
||||||
typedef typename PT::Polynomial_d Polynomial;
|
|
||||||
typedef typename PT::Innermost_coefficient IC;
|
|
||||||
|
|
||||||
|
|
||||||
typedef Chinese_remainder_traits<Coeff> CRT;
|
|
||||||
typedef typename CRT::Scalar_type Scalar;
|
|
||||||
|
|
||||||
|
|
||||||
typedef typename CGAL::Modular_traits<Polynomial>::Modular_NT MPolynomial;
|
|
||||||
typedef typename CGAL::Modular_traits<Coeff>::Modular_NT MCoeff;
|
|
||||||
typedef typename CGAL::Modular_traits<Scalar>::Modular_NT MScalar;
|
|
||||||
|
|
||||||
typename CRT::Chinese_remainder chinese_remainder;
|
|
||||||
typename CGAL::Modular_traits<Coeff>::Modular_image_inv inv_map;
|
|
||||||
|
|
||||||
|
|
||||||
typename PT::Degree_vector degree_vector;
|
|
||||||
typename CGAL::Polynomial_traits_d<MPolynomial>::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"<<std::endl;
|
|
||||||
assert(false);
|
|
||||||
current_prime = CGALi::get_next_lower_prime(current_prime);
|
|
||||||
} else{
|
|
||||||
current_prime = CGALi::primes[prime_index];
|
|
||||||
}
|
|
||||||
CGAL::Modular::set_current_prime(current_prime);
|
|
||||||
|
|
||||||
mF = CGAL::modular_image(F);
|
|
||||||
mG = CGAL::modular_image(G);
|
|
||||||
|
|
||||||
}while( degree_vector(F) != mdegree_vector(mF) ||
|
|
||||||
degree_vector(G) != mdegree_vector(mG));
|
|
||||||
timer_evaluate.stop();
|
|
||||||
|
|
||||||
timer_resultant.start();
|
|
||||||
n++;
|
|
||||||
mR = new_resultant_interpolate(mF,mG);
|
|
||||||
timer_resultant.stop();
|
|
||||||
timer_cr.start();
|
|
||||||
if(n == 1){
|
|
||||||
// init chinese remainder
|
|
||||||
q = CGAL::Modular::get_current_prime(); // implicit !
|
|
||||||
R = inv_map(mR);
|
|
||||||
}else{
|
|
||||||
// continue chinese remainder
|
|
||||||
p = CGAL::Modular::get_current_prime(); // implicit!
|
|
||||||
R_old = R ;
|
|
||||||
// chinese_remainder(q,Gs ,p,inv_map(mG_),pq,Gs);
|
|
||||||
// cached_extended_euclidean_algorithm(q,p,s,t);
|
|
||||||
CGALi_algorithm_M::Cached_extended_euclidean_algorithm
|
|
||||||
<typename CRT::Scalar_type> 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 <class Coeff>
|
|
||||||
inline
|
|
||||||
Coeff new_resultant_decompose(
|
|
||||||
const CGAL::Polynomial<Coeff>& F, const CGAL::Polynomial<Coeff>& G, CGAL::Tag_false){
|
|
||||||
#ifdef CGAL_RESULTANT_NUSE_MODULAR_ARITHMETIC
|
|
||||||
return new_resultant_modularize(F,G,CGAL::Tag_false());
|
|
||||||
#else
|
|
||||||
typedef CGAL::Polynomial<Coeff> Polynomial;
|
|
||||||
typedef typename Modular_traits<Polynomial>::Is_modularizable Is_modularizable;
|
|
||||||
return new_resultant_modularize(F,G,Is_modularizable());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Coeff>
|
|
||||||
inline
|
|
||||||
Coeff new_resultant_decompose(
|
|
||||||
const CGAL::Polynomial<Coeff>& F, const CGAL::Polynomial<Coeff>& G, CGAL::Tag_true){
|
|
||||||
|
|
||||||
typedef Polynomial<Coeff> POLY;
|
|
||||||
typedef typename Fraction_traits<POLY>::Numerator_type Numerator;
|
|
||||||
typedef typename Fraction_traits<POLY>::Denominator_type Denominator;
|
|
||||||
typename Fraction_traits<POLY>::Decompose decompose;
|
|
||||||
typedef typename Numerator::NT RES;
|
|
||||||
|
|
||||||
Denominator a, b;
|
|
||||||
// F.simplify_coefficients(); not const
|
|
||||||
// G.simplify_coefficients(); not const
|
|
||||||
Numerator F0; decompose(F,F0,a);
|
|
||||||
Numerator G0; decompose(G,G0,b);
|
|
||||||
Denominator c = CGAL::ipower(a, G.degree()) * CGAL::ipower(b, F.degree());
|
|
||||||
typedef typename Algebraic_structure_traits<RES>::Algebraic_category Algebraic_category;
|
|
||||||
RES res0 = CGAL::CGALi::new_resultant_(F0, G0);
|
|
||||||
typename Fraction_traits<Coeff>::Compose comp_frac;
|
|
||||||
Coeff res = comp_frac(res0, c);
|
|
||||||
typename Algebraic_structure_traits<Coeff>::Simplify simplify;
|
|
||||||
simplify(res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Coeff>
|
|
||||||
inline
|
|
||||||
Coeff new_resultant_(
|
|
||||||
const CGAL::Polynomial<Coeff>& F, const CGAL::Polynomial<Coeff>& G){
|
|
||||||
typedef CGAL::Fraction_traits<Polynomial<Coeff > > FT;
|
|
||||||
typedef typename FT::Is_fraction Is_fraction;
|
|
||||||
return new_resultant_decompose(F,G,Is_fraction());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace CGALi
|
|
||||||
|
|
||||||
template <class Coeff>
|
|
||||||
inline
|
|
||||||
Coeff new_resultant(
|
|
||||||
const CGAL::Polynomial<Coeff>& F_,
|
|
||||||
const CGAL::Polynomial<Coeff>& G_,
|
|
||||||
int index = CGAL::Polynomial_traits_d< CGAL::Polynomial<Coeff> >::d-1){
|
|
||||||
typedef CGAL::Polynomial_traits_d<CGAL::Polynomial<Coeff> > PT;
|
|
||||||
CGAL::Polynomial<Coeff> F = typename PT::Move()(F_, index, 0);
|
|
||||||
CGAL::Polynomial<Coeff> G = typename PT::Move()(G_, index, 0);
|
|
||||||
return CGALi::new_resultant_(F,G);
|
|
||||||
}
|
|
||||||
|
|
||||||
CGAL_END_NAMESPACE
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // CGAL_NEW_RESULTANT_H
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue