diff --git a/.gitattributes b/.gitattributes index b9a34de8715..d218c354878 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1724,6 +1724,7 @@ Polynomial/doc_tex/Polynomial_ref/Polynomial_1.tex -text Polynomial/include/CGAL/Polynomial/Coercion_traits.h -text Polynomial/include/CGAL/Polynomial/hgdelta_update.h -text Polynomial/include/CGAL/Polynomial/ipower.h -text +Polynomial/include/CGAL/Polynomial/univariate_polynomial_utils.h -text Polytope_distance_d/test/Polytope_distance_d/create_test_PD_cin -text Polytope_distance_d/test/Polytope_distance_d/test_PD.cin -text Polytope_distance_d/test/Polytope_distance_d/test_PD_data/intersecting_segments.data -text diff --git a/Polynomial/include/CGAL/Polynomial/univariate_polynomial_utils.h b/Polynomial/include/CGAL/Polynomial/univariate_polynomial_utils.h new file mode 100644 index 00000000000..38e21ecf15a --- /dev/null +++ b/Polynomial/include/CGAL/Polynomial/univariate_polynomial_utils.h @@ -0,0 +1,75 @@ +// 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) : +// +// ============================================================================ + +// TODO: The comments are all original EXACUS comments and aren't adapted. So +// they may be wrong now. + +#ifndef CGAL_POLYNOMIAL_UNIVARIATE_POLYNOMIAL_UTILS_H +#define CGAL_POLYNOMIAL_UNIVARIATE_POLYNOMIAL_UTILS_H + +#include + +CGAL_BEGIN_NAMESPACE + +//! return an upper bound on the absolute value of all real roots of \c P. +/*! The upper bound is a power of two. Only works for univariate polynomials. + * \pre \c NT must be \c RealComparable. + * \relates NiX::Polynomial + */ +template +NT weak_upper_root_bound(const Polynomial& P) { + // code comes from Kurt Mehlhorn + // see [Mignotte, 1992], p.144 for a proof + CGAL_precondition(Polynomial_traits_d::d == 0); + typename Real_embeddable_traits::Abs abs; + const int n = P.degree(); + NT x(1); + NT val; + for (;;) { + val = -abs(P[n]); + for (int i = n-1; i >= 0; i--) { + val = val*x + abs(P[i]); + } + if (val < NT(0)) return x; + x *= NT(2); + } +} + +//! return the number of sign variations in the coefficient sequence of \c P. +/*! This is the number of sign changes (+ to - or - to +) in the + * coefficient sequence of the polynomial, ignoring zeroes. + * Only meaningful for univariate polynomials. + * \pre \c NT must be \c RealComparable. + * \relates NiX::Polynomial + */ +template +int sign_variations(const Polynomial& P) { + typename Real_embeddable_traits::Sign sign; + const int n = P.degree(); + int variations = 0; + int old_sign = sign(P[n]); // never zero unless P is zero + for (int i = n-1; i >= 0; i--) { + int s = sign(P[i]); + if (s == 0) continue; + if (old_sign != s) { + old_sign = s; + variations++; + } + } + return variations; +} + +CGAL_END_NAMESPACE + + +#endif // CGAL_POLYNOMIAL_UNIVARIATE_POLYNOMIAL_UTILS_H