// TODO: Add licence // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // // Author(s) : Arno Eigenwillig // Michael Seel // Michael Hemmer // // ============================================================================ #ifndef CGAL_POLYNOMIAL_TRAITS_D_H #define CGAL_POLYNOMIAL_TRAITS_D_H #include CGAL_BEGIN_NAMESPACE // The Polynomial_traits_d_base template namespace CGALi { template< class Innermost_coefficient_ > class Polynomial_traits_d_base { typedef Innermost_coefficient_ ICoeff; public: static const int d = 0; typedef ICoeff Polynomial_d; typedef ICoeff Coefficient; typedef ICoeff Innermost_coefficient; struct Degree : public Unary_function< ICoeff , int > { int operator()(const ICoeff& c) const { return 0; } }; struct Total_degree : public Unary_function< ICoeff , int > { int operator()(const ICoeff& c) const { return 0; } }; typedef Null_functor Construct_polynomial_d; typedef Null_functor Degree; typedef Null_functor Total_degree; typedef Null_functor Leading_coefficient; typedef Null_functor Univariate_content; typedef Null_functor Multivariate_content; typedef Null_functor Shift; typedef Null_functor Negate; typedef Null_functor Invert; typedef Null_functor Translate; typedef Null_functor Translate_homogeneous; typedef Null_functor Scale_homogeneous; typedef Null_functor Differentiate; struct Make_square_free : public Unary_function< ICoeff, ICoeff>{ ICoeff operator()( const ICoeff& x ) const { if (CGAL::is_zero(x)) return x ; else return ICoeff(1); } }; typedef Null_functor Square_free_factorization; typedef Null_functor Pseudo_division; typedef Null_functor Pseudo_division_remainder; typedef Null_functor Pseudo_division_quotient; struct Gcd_up_to_constant_factor : public Binary_function< ICoeff, ICoeff, ICoeff >{ ICoeff operator()(const ICoeff& x, const ICoeff& y) const { if (CGAL::is_zero(x) && CGAL::is_zero(y)) return ICoeff(0); else return ICoeff(1); } }; typedef Null_functor Integral_division_up_to_constant_factor; struct Univariate_content_up_to_constant_factor : public Unary_function< ICoeff, ICoeff >{ ICoeff operator()(const ICoeff& ) const { return ICoeff(1); } }; typedef Null_functor Square_free_factorization_up_to_constant_factor; typedef Null_functor Evaluate; typedef Null_functor Evaluate_homogeneous; typedef Null_functor Resultant; typedef Null_functor Canonicalize; struct Innermost_leading_coefficient :public Unary_function { ICoeff operator()(const ICoeff& x){return x;} }; struct Degree_vector{ typedef std::vector result_type; typedef Coefficient argument_type; // returns the exponent vector of inner_most_lcoeff. result_type operator()(const Coefficient& constant){ return std::vector(); } }; }; } // namespace CGALi template < class T > class Polynomial_traits_d :public CGALi::Polynomial_traits_d_base {}; template < class Coefficient_ > class Polynomial_traits_d< Polynomial > :public CGALi::Polynomial_traits_d_base< Polynomial > { typedef Polynomial_traits_d< Coefficient_ > PTC; typedef Polynomial_traits_d< Polynomial< Coefficient_ > > PT; public: typedef Polynomial Polynomial_d; typedef Coefficient_ Coefficient; typedef typename PTC::Innermost_coefficient Innermost_coefficient; static const int d = PTC::d+1; private: typedef std::pair< Exponent_vector, Innermost_coefficient > Exponents_coeff_pair; typedef std::vector< Exponents_coeff_pair > Monom_rep; public: struct Construct_polynomial_d { typedef Polynomial_d result_type; Polynomial_d operator()() const { return Polynomial_d(0); } template Polynomial_d operator()( T a ) const { return Polynomial_d(a); } //! construct the constant polynomial a0 Polynomial_d operator() (const Coefficient& a0) const {return Polynomial_d(a0);} //! construct the polynomial a0 + a1*x Polynomial_d operator() ( const Coefficient& a0, const Coefficient& a1) const {return Polynomial_d(a0,a1);} //! construct the polynomial a0 + a1*x + a2*x^2 Polynomial_d operator() ( const Coefficient& a0, const Coefficient& a1, const Coefficient& a2) const {return Polynomial_d(a0,a1,a2);} //! construct the polynomial a0 + a1*x + ... + a3*x^3 Polynomial_d operator() ( const Coefficient& a0, const Coefficient& a1, const Coefficient& a2, const Coefficient& a3) const {return Polynomial_d(a0,a1,a2,a3);} //! construct the polynomial a0 + a1*x + ... + a4*x^4 Polynomial_d operator() ( const Coefficient& a0, const Coefficient& a1, const Coefficient& a2, const Coefficient& a3, const Coefficient& a4) const {return Polynomial_d(a0,a1,a2,a3,a4);} //! construct the polynomial a0 + a1*x + ... + a5*x^5 Polynomial_d operator() ( const Coefficient& a0, const Coefficient& a1, const Coefficient& a2, const Coefficient& a3, const Coefficient& a4, const Coefficient& a5) const {return Polynomial_d(a0,a1,a2,a3,a4,a5);} //! construct the polynomial a0 + a1*x + ... + a6*x^6 Polynomial_d operator() ( const Coefficient& a0, const Coefficient& a1, const Coefficient& a2, const Coefficient& a3, const Coefficient& a4, const Coefficient& a5, const Coefficient& a6) const {return Polynomial_d(a0,a1,a2,a3,a4,a5,a6);} //! construct the polynomial a0 + a1*x + ... + a7*x^7 Polynomial_d operator() ( const Coefficient& a0, const Coefficient& a1, const Coefficient& a2, const Coefficient& a3, const Coefficient& a4, const Coefficient& a5, const Coefficient& a6, const Coefficient& a7) const {return Polynomial_d(a0,a1,a2,a3,a4,a5,a6,a7);} //! construct the polynomial a0 + a1*x + ... + a8*x^8 Polynomial_d operator() ( const Coefficient& a0, const Coefficient& a1, const Coefficient& a2, const Coefficient& a3, const Coefficient& a4, const Coefficient& a5, const Coefficient& a6, const Coefficient& a7, const Coefficient& a8) const {return Polynomial_d(a0,a1,a2,a3,a4,a5,a6,a7,a8);} template< class Input_iterator > inline Polynomial_d construct( Input_iterator begin, Input_iterator end , Tag_true) const { return Polynomial_d(begin,end); } template< class Input_iterator > inline Polynomial_d construct( Input_iterator begin, Input_iterator end , Tag_false) const { std::sort(begin,end); return Create_polynomial_from_monom_rep< Coefficient >() ( begin, end ); } template< class Input_iterator > Polynomial_d operator()( Input_iterator begin, Input_iterator end ) const { if(begin == end ) return Polynomial_d(0); typedef typename Input_iterator::value_type value_type; typedef Boolean_tag::value> Is_coeff; return construct(begin,end,Is_coeff()); } private: template< class T > class Create_polynomial_from_monom_rep { public: template Polynomial_d operator()( Monom_rep_iterator begin, Monom_rep_iterator end) const { std::vector< Innermost_coefficient > coefficients; for(Monom_rep_iterator it = begin; it != end; it++){ while( it->first[0] > (int) coefficients.size() ){ coefficients.push_back(Innermost_coefficient(0)); } coefficients.push_back(it->second); } return Polynomial_d(coefficients.begin(),coefficients.end()); } }; template< class T > class Create_polynomial_from_monom_rep< Polynomial < T > > { public: template Polynomial_d operator()( Monom_rep_iterator begin, Monom_rep_iterator end) const { //std::cout << " ------\n " << std::endl; typedef Polynomial_traits_d PT; typename PT::Construct_polynomial_d construct; BOOST_STATIC_ASSERT(PT::d != 0); // Coefficient is a Polynomial std::vector coefficients; Monom_rep_iterator it = begin; while(it != end){ int current_exp = it->first[PT::d]; //std::cout <<"current_exp: " << current_exp << std::endl; // fill up with zeros until current exp is reached while( (int) coefficients.size() < current_exp){ coefficients.push_back(Coefficient(0)); //std::cout <<" insert "<< std::endl; } // collect all coeffs for this exp Monom_rep monoms; while( it != end && it->first[PT::d] == current_exp ){ Exponent_vector ev = it->first; ev.pop_back(); monoms.push_back( Exponents_coeff_pair(ev,it->second)); it++; } coefficients.push_back( construct(monoms.begin(), monoms.end())); } //std::cout << " ------\n " << std::endl; return Polynomial_d(coefficients.begin(),coefficients.end()); } }; }; struct Get_monom_representation { typedef std::pair< Exponent_vector, Innermost_coefficient > Exponents_coeff_pair; typedef std::vector< Exponents_coeff_pair > Monom_rep; template void operator()( const Polynomial_d& p, OutputIterator oit ) const { typedef Boolean_tag< d == 1 > Is_univariat; create_monom_representation( p, oit , Is_univariat()); } private: template void create_monom_representation ( const Polynomial_d& p, OutputIterator oit, Tag_true ) const{ for( int exponent = 0; exponent <= p.degree(); ++exponent ) { // std::cout << "p[exponent]: "< void create_monom_representation ( const Polynomial_d& p, OutputIterator oit, Tag_false ) const { for( int exponent = 0; exponent <= p.degree(); ++exponent ) { Monom_rep monom_rep; typedef Polynomial_traits_d< Coefficient > PT; typename PT::Get_monom_representation gmr; gmr( p[exponent], std::back_inserter( monom_rep ) ); for( typename Monom_rep::iterator it = monom_rep.begin(); it != monom_rep.end(); ++it ) { it->first.push_back( exponent ); } copy( monom_rep.begin(), monom_rep.end(), oit ); } } }; private: typedef CGAL::Recursive_const_flattening< d-1, typename CGAL::Polynomial::const_iterator > Coefficient_flattening; public: typedef typename Polynomial_d::iterator Coefficient_iterator; struct Coefficient_begin : public Unary_function< Polynomial_d, Coefficient_iterator > { Coefficient_iterator operator () (const Polynomial_d& p) { return p.begin(); } }; struct Coefficient_end : public Unary_function< Polynomial_d, Coefficient_iterator > { Coefficient_iterator operator () (const Polynomial_d& p) { return p.end(); } }; public: typedef typename Coefficient_flattening::Recursive_flattening_iterator Innermost_coefficient_iterator; struct Innermost_coefficient_begin : public Unary_function< Polynomial_d, Innermost_coefficient_iterator > { Innermost_coefficient_iterator operator () (const Polynomial_d& p) { return typename Coefficient_flattening::Flatten()(p.end(),p.begin()); } }; struct Innermost_coefficient_end : public Unary_function< Polynomial_d, Innermost_coefficient_iterator > { Innermost_coefficient_iterator operator () (const Polynomial_d& p) { return typename Coefficient_flattening::Flatten()(p.end(),p.end()); } }; // Swap variable x_i with x_j struct Swap { typedef Polynomial_d result_type; typedef Polynomial_d first_argument_type; typedef int second_argument_type; typedef int third_argument_type; typedef Arity_tag< 3 > Arity; Polynomial_d operator()(const Polynomial_d& p, int i, int j ) const { //std::cout << i <<" " << j << " : " ; CGAL_precondition(0 < i && i <= d); CGAL_precondition(0 < j && j <= d); typedef std::pair< Exponent_vector, Innermost_coefficient > Exponents_coeff_pair; typedef std::vector< Exponents_coeff_pair > Monom_rep; Get_monom_representation gmr; Construct_polynomial_d construct; Monom_rep mon_rep; gmr( p, std::back_inserter( mon_rep ) ); for( typename Monom_rep::iterator it = mon_rep.begin(); it != mon_rep.end(); ++it ) { std::swap(it->first[i-1],it->first[j-1]); // it->first.swap( i, j ); } std::sort( mon_rep.begin(), mon_rep.end() ); return construct( mon_rep.begin(), mon_rep.end() ); } }; // move variable x_i to position of x_j // order of other variables remains // default j = d makes x_i the othermost variable struct Move { typedef Polynomial_d result_type; typedef Polynomial_d first_argument_type; typedef int second_argument_type; typedef int third_argument_type; typedef Arity_tag< 3 > Arity; Polynomial_d operator()(const Polynomial_d& p, int i, int j = d ) const { //std::cout << x <<" " << y << " : " ; CGAL_precondition(0 < i && i <= d); CGAL_precondition(0 < j && j <= d); typedef std::pair< Exponent_vector, Innermost_coefficient > Exponents_coeff_pair; typedef std::vector< Exponents_coeff_pair > Monom_rep; Get_monom_representation gmr; Construct_polynomial_d construct; Monom_rep mon_rep; gmr( p, std::back_inserter( mon_rep ) ); for( typename Monom_rep::iterator it = mon_rep.begin(); it != mon_rep.end(); ++it ) { // this is as good as std::rotate since it uses swap also if (i < j) for( int k = i-1; k < j-1; k++ ) std::swap(it->first[k],it->first[k+1]); else for( int k = i-1; k > j-1; k-- ) std::swap(it->first[k],it->first[k-1]); } std::sort( mon_rep.begin(), mon_rep.end() ); return construct( mon_rep.begin(), mon_rep.end() ); } }; struct Degree : public Unary_function< Polynomial_d , int >{ int operator()(const Polynomial_d& p, int i = d) const { if (i == d) return p.degree(); else return Swap()(p,i,d).degree(); } }; // Total_degree; struct Total_degree : public Unary_function< Polynomial_d , int >{ int operator()(const Polynomial_d& p) const { typedef Polynomial_traits_d COEFF_POLY_TRAITS; typename COEFF_POLY_TRAITS::Total_degree total_degree; Degree degree; CGAL_precondition( degree(p) >= 0); int result = 0; for(int i = 0; i <= degree(p) ; i++){ if( ! CGAL::is_zero( p[i]) ) result = std::max(result , total_degree(p[i]) + i ); } return result; } }; // Leading_coefficient; struct Leading_coefficient : public Unary_function< Polynomial_d , Coefficient>{ Coefficient operator()(const Polynomial_d& p) const { return p.lcoeff(); } Coefficient operator()(Polynomial_d p, int i) const { return Swap()(p,i,PT::d).lcoeff(); } }; struct Innermost_leading_coefficient : public Unary_function< Polynomial_d , Innermost_coefficient>{ Innermost_coefficient operator()(const Polynomial_d& p) const { typename PTC::Innermost_leading_coefficient ilcoeff; typename PT::Leading_coefficient lcoeff; return ilcoeff(lcoeff(p)); } }; // returns the Exponten_vector of the innermost leading coefficient // TODO use Exponent vector // TODO document struct Degree_vector{ typedef std::vector result_type; typedef Polynomial_d argument_type; // returns the exponent vector of inner_most_lcoeff. result_type operator()(const Polynomial_d& polynomial){ typename PTC::Degree_vector degree_vector; std::vector result = degree_vector(polynomial.lcoeff()); result.insert(result.begin(),polynomial.degree()); return result; } }; // Univariate_content; struct Univariate_content : public Unary_function< Polynomial_d , Coefficient>{ Coefficient operator()(const Polynomial_d& p) const { return p.content(); } Coefficient operator()(Polynomial_d p, int i) const { return Swap()(p,i,PT::d).content(); } }; // Multivariate_content; struct Multivariate_content : public Unary_function< Polynomial_d , Innermost_coefficient >{ Innermost_coefficient operator()(const Polynomial_d& p) const { typedef Innermost_coefficient_iterator IT; Innermost_coefficient content(0); for (IT it = Innermost_coefficient_begin()(p); it != Innermost_coefficient_end()(p); it++){ content = CGAL::gcd(content, *it); if(CGAL::is_one(content)) break; } return content; } }; // Shift; struct Shift : public Unary_function< Polynomial_d, Polynomial_d >{ Polynomial_d operator()(const Polynomial_d& p, int e, int i = PT::d) const { Construct_polynomial_d construct; Get_monom_representation gmr; Monom_rep monom_rep; gmr(p,std::back_inserter(monom_rep)); for(typename Monom_rep::iterator it = monom_rep.begin(); it != monom_rep.end(); it++){ it->first[i-1]+=e; } return construct(monom_rep.begin(), monom_rep.end()); } }; // Negate; struct Negate : public Unary_function< Polynomial_d, Polynomial_d >{ Polynomial_d operator()(const Polynomial_d& p, int i = d) const { Construct_polynomial_d construct; Get_monom_representation gmr; Monom_rep monom_rep; gmr(p,std::back_inserter(monom_rep)); for(typename Monom_rep::iterator it = monom_rep.begin(); it != monom_rep.end(); it++){ if (it->first[i-1] % 2 != 0) it->second = - it->second; } return construct(monom_rep.begin(), monom_rep.end()); } }; // Invert; struct Invert : public Unary_function< Polynomial_d , Polynomial_d >{ Polynomial_d operator()(Polynomial_d p, int i = PT::d) const { if (i == d){ p.reversal(); }else{ p = Swap()(p,i,PT::d); p.reversal(); p = Swap()(p,i,PT::d); } return p ; } }; // Translate; struct Translate : public Binary_function< Polynomial_d , Polynomial_d, Innermost_coefficient >{ Polynomial_d operator()( Polynomial_d p, const Innermost_coefficient& c, int i = d) const { if (i == d ){ p.translate(Coefficient(c)); }else{ Swap swap; p = swap(p,i,d); p.translate(Coefficient(c)); p = swap(p,i,d); } return p; } }; // Translate_homogeneous; struct Translate_homogeneous{ typedef Polynomial_d result_type; typedef Polynomial_d first_argument_type; typedef Innermost_coefficient second_argument_type; typedef Innermost_coefficient third_argument_type; Polynomial_d operator()(Polynomial_d p, const Innermost_coefficient& a, const Innermost_coefficient& b, int i = d ) const { if (i == d ){ p.translate(Coefficient(a), Coefficient(b) ); }else{ Swap swap; p = swap(p,i,d); p.translate(Coefficient(a), Coefficient(b)); p = swap(p,i,d); } return p; } }; // Scale_homogeneous; struct Scale_homogeneous{ typedef Polynomial_d result_type; typedef Polynomial_d first_argument_type; typedef Innermost_coefficient second_argument_type; typedef Innermost_coefficient third_argument_type; Polynomial_d operator()( Polynomial_d p, const Innermost_coefficient& a, const Innermost_coefficient& b, int i = d ) const { CGAL_precondition( ! CGAL::is_zero(b) ); if (i == d ) p = Swap()(p,i,d); if(CGAL::is_one(b)) p.scale_up(Coefficient(a)); else if(CGAL::is_one(a)) p.scale_down(Coefficient(b)); else p.scale(Coefficient(a), Coefficient(b) ); if (i == d ) p = Swap()(p,i,d); return p; } }; // Differentiate; struct Differentiate : public Unary_function{ Polynomial_d operator()(Polynomial_d p, int i = d) const { if (i == d ){ p.diff(); }else{ Swap swap; p = swap(p,i,d); p.diff(); p = swap(p,i,d); } return p; } }; // Make_square_free; struct Make_square_free : public Unary_function< Polynomial_d, Polynomial_d >{ Polynomial_d operator()(const Polynomial_d& p) const { if (CGAL::is_zero(p)) return p; Univariate_content_up_to_constant_factor ucontent_utcf; Integral_division_up_to_constant_factor idiv_utcf; Differentiate diff; typename PTC::Make_square_free msf; Coefficient content = ucontent_utcf(p); Polynomial_d result = Polynomial_d(msf(content)); Polynomial_d regular_part = idiv_utcf(p,Polynomial_d(content)); Polynomial_d g = gcd_utcf(regular_part,diff(regular_part)); result *= idiv_utcf(regular_part,g); return Canonicalize()(result); #if 0 Square_free_factorization sqff_utcf; std::vector facs; std::vector mults; sqff_utcf(p,std::back_inserter(facs), std::back_inserter(mults)); for(typename std::vector::iterator it = facs.begin(); it != facs.end(); it++){ result *= *it; } return result; #endif } }; // Square_free_factorization; struct Square_free_factorization{ typedef int result_type; private: typedef Coefficient Coeff; typedef Innermost_coefficient ICoeff; // rsqff computes the sqff recursively for Coeff // end of recursion: ICoeff template < class OutputIterator1, class OutputIterator2 > int rsqff (ICoeff c, OutputIterator1 factors, OutputIterator2 mults) const{ return 0; } template < class OutputIterator1, class OutputIterator2 > int rsqff ( typename First_if_different::Type c, OutputIterator1 fit, OutputIterator2 mit) const { typename PTC::Square_free_factorization sqff; std::vector factors; int n = sqff(c, std::back_inserter(factors), mit); for(int i = 0; i < (int)factors.size(); i++){ *fit++=Polynomial_d(factors[i]); } return n; } public: template < class OutputIterator1, class OutputIterator2 > int operator()( const Polynomial_d& p, OutputIterator1 fit, OutputIterator2 mit) const { Coefficient c; int n = square_free_factorization(p,fit,mit,c); if (Total_degree()(c) > 0) return rsqff(c,fit,mit)+n; else return n; } }; // Pseudo_division; struct Pseudo_division { typedef Polynomial_d result_type; void operator()( const Polynomial_d& f, const Polynomial_d& g, Polynomial_d& q, Polynomial_d& r, Coefficient& D) const { Polynomial_d::pseudo_division(f,g,q,r,D); } }; // Pseudo_division_remainder; struct Pseudo_division_remainder :public Binary_function { Polynomial_d operator()(const Polynomial_d& f, const Polynomial_d& g) const { Polynomial_d q,r; Coefficient D; Polynomial_d::pseudo_division(f,g,q,r,D); return r; } }; // Pseudo_division_quotient; struct Pseudo_division_quotient :public Binary_function { Polynomial_d operator()(const Polynomial_d& f, const Polynomial_d& g) const { Polynomial_d q,r; Coefficient D; Polynomial_d::pseudo_division(f,g,q,r,D); return q; } }; // Gcd_up_to_constant_factor; struct Gcd_up_to_constant_factor :public Binary_function { Polynomial_d operator()(const Polynomial_d& p, const Polynomial_d& q) const { if (CGAL::is_zero(p) && CGAL::is_zero(q)) return Polynomial_d(0); return gcd_utcf(p,q); } }; // Integral_division_up_to_constant_factor; struct Integral_division_up_to_constant_factor :public Binary_function { Polynomial_d operator()(const Polynomial_d& p, const Polynomial_d& q) const { typedef Innermost_coefficient IC; typename PT::Construct_polynomial_d construct; typename PT::Innermost_leading_coefficient ilcoeff; typename PT::Innermost_coefficient_begin begin; typename PT::Innermost_coefficient_end end; typedef Algebraic_extension_traits AET; typename AET::Denominator_for_algebraic_integers dfai; typename AET::Normalization_factor nfac; IC ilcoeff_q = ilcoeff(q); // this factor is needed in case IC is an Algebraic extension IC dfai_q = dfai(begin(q), end(q)); // make dfai_q a 'scalar' ilcoeff_q *= dfai_q * nfac(dfai_q); Polynomial_d result = (p * construct(ilcoeff_q)) / q; return Canonicalize()(result); } }; // Univariate_content_up_to_constant_factor; struct Univariate_content_up_to_constant_factor :public Unary_function { Coefficient operator()(const Polynomial_d& p) const { typename PTC::Gcd_up_to_constant_factor gcd_utcf; if(CGAL::is_zero(p)) return Coefficient(0); if(PT::d == 1) return Coefficient(1); Coefficient result(0); for(typename Polynomial_d::const_iterator it = p.begin(); it != p.end(); it++){ result = gcd_utcf(*it,result); } return result; } }; // Square_free_factorization_up_to_constant_factor; struct Square_free_factorization_up_to_constant_factor { typedef int result_type; private: typedef Coefficient Coeff; typedef Innermost_coefficient ICoeff; // rsqff_utcf computes the sqff recursively for Coeff // end of recursion: ICoeff template < class OutputIterator1, class OutputIterator2 > int rsqff_utcf (ICoeff c, OutputIterator1 factors, OutputIterator2 mults) const{ return 0; } template < class OutputIterator1, class OutputIterator2 > int rsqff_utcf ( typename First_if_different::Type c, OutputIterator1 fit, OutputIterator2 mit) const { typename PTC::Square_free_factorization sqff; std::vector factors; int n = sqff(c, std::back_inserter(factors), mit); for(int i = 0; i < (int)factors.size(); i++){ *fit++=Polynomial_d(factors[i]); } return n; } public: template < class OutputIterator1, class OutputIterator2 > int operator()( Polynomial_d p, OutputIterator1 fit, OutputIterator2 mit) const { if (CGAL::is_zero(p)) return 0; Univariate_content_up_to_constant_factor ucontent_utcf; Integral_division_up_to_constant_factor idiv_utcf; Coefficient c = ucontent_utcf(p); p = idiv_utcf( p , Polynomial_d(c)); int n = square_free_factorization_utcf(p,fit,mit); if (Total_degree()(c) > 0) return rsqff_utcf(c,fit,mit)+n; else return n; } }; // Evaluate; struct Evaluate :public Binary_function{ Coefficient operator()(const Polynomial_d& p, Innermost_coefficient x, int i = d) const { if(i == d ) return p.evaluate(x); else{ return Move()(p,i).evaluate(x); } } }; // Evaluate_homogeneous; struct Evaluate_homogeneous{ typedef Coefficient result_type; typedef Polynomial_d first_argument_type; typedef Innermost_coefficient second_argument_type; typedef Innermost_coefficient third_argument_type; typedef Arity_tag< 3 > Arity; Coefficient operator()( const Polynomial_d& p, Innermost_coefficient a, Innermost_coefficient b) const { return p.evaluate_homogeneous(a,b); } Coefficient operator()( const Polynomial_d& p, Innermost_coefficient a, Innermost_coefficient b, int hdegree , int i = PT::d ) const { if (i == d ) return p.evaluate_homogeneous(a,b,hdegree); else return Move()(p,i,PT::d).evaluate_homogeneous(a,b,hdegree); } }; // Resultant; struct Resultant : public Binary_function{ Coefficient operator()( const Polynomial_d& p, const Polynomial_d& q, int i = d ) const { if(i == d ) return prs_resultant(p,q); else return prs_resultant(Move()(p,i),Move()(q,i)); } }; // Canonicalize; struct Canonicalize : public Unary_function{ Polynomial_d operator()( const Polynomial_d& p ) const { return CGAL::canonicalize_polynomial(p); } }; }; CGAL_END_NAMESPACE #endif // CGAL_POLYNOMIAL_TRAITS_D_H