// Copyright (c) 2007-2008 Inria Lorraine (France). All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; version 2.1 of the License. // See the file LICENSE.LGPL distributed with CGAL. // // 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. // // $URL$ // $Id$ // // Author: Luis Peņaranda #ifndef CGAL_RS_POLYNOMIAL_FUNCTORS #define CGAL_RS_POLYNOMIAL_FUNCTORS #include #include #include #include #include #include namespace CGAL{ struct RSPolynomialFunctors{ typedef Gmpz Coefficient; typedef Gmpz Innermost_coefficient; typedef RS_polynomial_1 Polynomial_1; typedef RS_polynomial_1 Type; static const int d=1; // TODO: do this in a clean way... struct Construct_polynomial{ Polynomial_1 operator()(){ Polynomial_1 p(2); p.set_coef_ui(0,0); p.force_degree(0); return p; }; Polynomial_1 operator()(int i){ Polynomial_1 p(2); p.set_coef_si(0,i); p.force_degree(0); return p; }; template inline Polynomial_1 operator()( InputIterator begin,InputIterator end)const{ return Polynomial_1(begin,end); }; //-------------------------------------------------- // template // Polynomial_1 operator() // (InputIterator1 fst_coef,InputIterator1 lst_coef, // InputIterator2 deg)const{ // // the degree of the polynomial will be // // the greatest degree // unsigned greater=0; // InputIterator1 c; // InputIterator2 d=deg; // for(c=fst_coef;c!=lst_coef;++c) // if(d>greater) // greater=d++; // // now, construct the polynomial of degree d // Polynomial_1 p(d); // for(c=fst_coef;c!=lst_coef;++c) // p.set_coef(deg++,*c); // return p; // }; //-------------------------------------------------- template Polynomial_1 operator() (InputIterator begin,InputIterator end,bool is_sorted)const{ // the degree of the polynomial will be // the greatest degree int degree; if(is_sorted) degree=*((end-1)->first.begin()); else{ degree=0; for(InputIterator i=begin;i!=end;++i) if(*(i->first.begin())>degree) degree=*(i->first.begin()); } Polynomial_1 p(degree); for(InputIterator i=begin;i!=end;++i) p.set_coef(*(i->first.begin()),i->second); return p; }; }; // Construct_polynomial struct Get_coefficient: public std::binary_function{ inline Coefficient operator() (const Polynomial_1 &p,int i)const{ return Coefficient(p.coef(i)); }; }; struct Get_innermost_coefficient: public std::binary_function{ inline Coefficient operator()( const Polynomial_1 &p,Exponent_vector v)const{ CGAL_precondition(v.size()==1); return Coefficient(p.coef(v[0])); }; }; // this is an in-place swap struct Swap{ inline Polynomial_1 operator()(Polynomial_1 &p,int i,int j)const{ mpz_t temp; CGAL_precondition(i<=d&&j<=d); mpz_init_set(temp,p.coef(j)); p.set_coef(j,p.coef(i)); p.set_coef(i,temp); mpz_clear(temp); return p; }; }; struct Move{ inline Polynomial_1& operator()(Polynomial_1 &p,int i,int j)const{ CGAL_precondition(i<=d&&j<=d); p.set_coef(j,p.coef(i)); p.set_coef_ui(i,0); return p; }; }; struct Degree{ inline int operator()(const Polynomial_1 &p)const{ return p.get_degree(); }; inline int operator()(const Polynomial_1 &p,int i)const{ CGAL_precondition(!d); return p.get_degree(); }; }; struct Total_degree: public std::unary_function{ inline int operator()(const Polynomial_1 &p)const{ return p.get_degree(); }; }; struct Degree_vector: public std::unary_function{ inline Exponent_vector operator()(const Polynomial_1 &p){ Exponent_vector v(1); v[1]=p.get_degree(); return v; // why the hell this doesn't work? //return Exponent_vector(1,p.get_degree()); }; }; struct Leading_coefficient{ inline Coefficient operator()(const Polynomial_1 &p)const{ return Coefficient(p.leading_coefficient()); }; inline Coefficient operator() (const Polynomial_1 &p,int i)const{ CGAL_precondition(!i); return Coefficient(p.leading_coefficient()); }; }; struct Innermost_leading_coefficient: public std::unary_function{ inline Innermost_coefficient operator()(const Polynomial_1 &p)const{ return Innermost_coefficient(p.leading_coefficient()); }; }; struct Canonicalize: public std::unary_function{ Polynomial_1& operator()(Polynomial_1 &f)const{ mpz_t temp; mpz_init(temp); Cont()(temp,f); f/=temp; mpz_clear(temp); return f; }; }; struct Derive{ inline Polynomial_1 operator()(const Polynomial_1 &p)const{ return p.derive(); }; inline Polynomial_1 operator()(const Polynomial_1 &p,int i)const{ CGAL_precondition(!i); return p.derive(); }; }; struct Evaluate{ inline Coefficient operator()( const Polynomial_1 &p, const Innermost_coefficient x)const{ return p(x); }; inline Coefficient operator()( const Polynomial_1 &p, Innermost_coefficient c, int i)const{ CGAL_precondition(!i); return p(c); }; }; typedef Null_functor Evaluate_homogeneous; struct Is_zero_at{ template inline bool operator()( const Polynomial_1 &p, InputIterator begin, InputIterator end)const{ CGAL_assertion(end=begin+1); return(p(*begin)==0); }; }; typedef Null_functor Is_zero_at_homogeneous; struct Sign_at{ template inline Sign operator()( const Polynomial_1 &p, InputIterator begin, InputIterator end)const{ return p.sign_at(*begin); }; }; typedef Null_functor Sign_at_homogeneous; struct Compare: public std::binary_function{ Comparison_result operator()( const Polynomial_1 &f, const Polynomial_1 &g){ if(f.get_degree()>g.get_degree()) return LARGER; if(f.get_degree_static()=0;--i){ if((c=mpz_cmp(f.coef(i),g.coef(i)))>0) return LARGER; if(c<0) return SMALLER; } return EQUAL; }; }; // Compare // now, we define five functors which are needed by the algebraic kernel, // but they are related to polynomials (I think this is the best place // to do it) template struct Is_square_free_1: public std::unary_function{ typedef _Gcd_policy Gcd; inline bool operator()(const Polynomial_1 &p){ return(!(Gcd()(p,p.derive()).get_degree_static())); }; }; // Is_square_free_1 template struct Make_square_free_1: public std::unary_function{ typedef _Gcd_policy Gcd; inline Polynomial_1 operator()(const Polynomial_1 &p){ return sfpart_1(p); }; }; // Make_square_free_1 // this function is not well defined in algebraic kernel concepts; we // don't care, we do it correctly template struct Square_free_factorize_1{ template int operator()(const Polynomial_1 &p,OutputIterator oi){ typedef _Gcd_policy Gcd; sqfrvec factorization(sqfr_1(p)); std::copy(factorization.begin(),factorization.end(),oi); return factorization.size(); }; }; // Square_free_factorize_1 template struct Is_coprime_1: public std::binary_function{ inline bool operator() (const Polynomial_1 &p1,const Polynomial_1 &p2){ typedef _Gcd_policy Gcd; return(!Gcd()(p1,p2).get_degree_static()); }; }; // Is_coprime_1 template struct Make_coprime_1{ typedef bool result_type; typedef Polynomial_1 P; bool operator()(const P &p1,const P &p2,P &g,P &q1,P &q2){ typedef _Gcd_policy Gcd; g=Gcd()(p1,p2); // we don't calculate q1 and q2 when g==1, shall we? if(!(g.get_degree_static())) return true; q1=*Ediv_1()(p1,g); q2=*Ediv_1()(p2,g); return false; }; }; // Make_coprime_1 struct IntegralDivision: public std::binary_function{ inline Polynomial_1 operator()( const Polynomial_1 &p1, const Polynomial_1 &p2){ return *Ediv_1()(p1,p2); }; }; // IntegralDivision typedef IntegralDivision IntegralDivisionUpToConstantFactor; }; // RSPolynomialFunctors } // namespace CGAL #endif // CGAL_RS_POLYNOMIAL_FUNCTORS // vim: tabstop=8: softtabstop=8: smarttab: shiftwidth=8: expandtab