// Copyright (c) 2006-2009 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; either version 3 of the License, // or (at your option) any later version. // // 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_1_MEMBER_H #define CGAL_RS_POLYNOMIAL_1_MEMBER_H namespace CGAL{ ////////////////////// // private functions inline void RS_polynomial_1::create_storage(int size){ _coef=(mpz_t*)(*_allocf)(sizeof(mpz_t)*size); _capacity=size; } inline void RS_polynomial_1::free_storage(){ void *(*af)(size_t); void *(*rf)(void*,size_t,size_t); void (*ff)(void*,size_t); mp_get_memory_functions(&af,&rf,&ff); mp_set_memory_functions(_allocf,_reallocf,_freef); for(int i=0;i<_degree+1;++i) mpz_clear(coef(i)); mp_set_memory_functions(af,rf,ff); (*_freef)(_coef,sizeof(mpz_t)*_capacity); _capacity=0; } inline void RS_polynomial_1::fetch_gmp_functions(){ mp_get_memory_functions(&_allocf,&_reallocf,&_freef); } ////////////////////// // private functions // dangerous function! this will erase the coefficients if the new coefficients // don't fit in the previously allocated space; otherwise, it will set to zero // the new coefficients inline void RS_polynomial_1::set_degree(int d){ if(d+1>_capacity){ free_storage(); _degree=d; ++d; create_storage(d); for(int i=0;i<=_degree;++i) mpz_init(coef(i)); }else{ _degree=d; for(int i=_degree+1;i<=d;++i) mpz_init(coef(i)); } return; } inline void RS_polynomial_1::force_degree(int n){ _degree=n; } // to change the storage capacity of a polynomial object inline int RS_polynomial_1::resize(int newcap){ if(newcap<=_capacity) return -1; int i; mpz_t *newcoef=(mpz_t*)(*_allocf)(newcap*sizeof(mpz_t)); for(i=0;i<=_degree;++i){ mpz_init_set(newcoef[i],_coef[i]); mpz_clear(_coef[i]); } for(i=_degree+1;icoef(x),coef(x+1),x+1); return *derivative; } inline RS_polynomial_1& RS_polynomial_1::minusx()const{ int d=get_degree(); RS_polynomial_1 *mx=new RS_polynomial_1(d); for(int x=0;x<=d;++x){ if(x%2==1) mpz_set(mx->coef(x),coef(x)); else mpz_neg(mx->coef(x),coef(x)); } return *mx; } // This function copies into lb a number which is less than all roots. It just // looks for the coefficient with the greatest absolute value. This is useful // when evaluating curves in the infinite. We can refine this, but it makes no // sense since it will be slower. inline void RS_polynomial_1::get_lower_bound(mpfr_ptr lb)const{ int d=get_degree(); mpz_t temp; mpz_init(temp); mpz_abs(temp,leading_coefficient()); for(int i=0;i0) mpz_abs(temp,coef(i)); mpz_add_ui(temp,temp,1); mpz_neg(temp,temp); mpfr_set_z(lb,temp,GMP_RNDD); mpz_clear(temp); } // the same that above, but the copied value is the upper bound of the roots inline void RS_polynomial_1::get_upper_bound(mpfr_ptr ub)const{ int d=get_degree(); mpz_t temp; mpz_init(temp); mpz_abs(temp,leading_coefficient()); for(int i=0;i0) mpz_abs(temp,coef(i)); mpz_add_ui(temp,temp,1); mpfr_set_z(ub,temp,GMP_RNDU); mpz_clear(temp); } // returns this polynomial times c*x^p inline RS_polynomial_1 RS_polynomial_1::times_monomial(mpz_srcptr c,int p)const{ int dr=get_degree()+p; RS_polynomial_1 r(dr); for(int i=p;i<=dr;++i) mpz_mul(r.coef(i),coef(i-p),c); return r; } } // namespace CGAL #endif // CGAL_RS_POLYNOMIAL_1_MEMBER_H