From 5089db3e37431e9aafff0f0359a3b6c8168fb39d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Pe=C3=B1aranda?= Date: Fri, 12 Aug 2016 15:44:37 -0300 Subject: [PATCH 1/8] Add assertions in refiners. The assertions check that the endpoints of the interval to refine have different evaluation signs, or they are the same point and its evaluation is zero. --- .../include/CGAL/RS/bisection_refiner_1.h | 8 ++--- .../include/CGAL/RS/rs3_k_refiner_1.h | 29 ++++++++++++++++--- .../include/CGAL/RS/rs3_refiner_1.h | 29 ++++++++++++++++--- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/Algebraic_kernel_d/include/CGAL/RS/bisection_refiner_1.h b/Algebraic_kernel_d/include/CGAL/RS/bisection_refiner_1.h index cfb5554f3db..bf41418b323 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/bisection_refiner_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/bisection_refiner_1.h @@ -47,7 +47,7 @@ operator()(const Polynomial_&,Bound_&,Bound_&,int){ // This works with any type of polynomial, but only for Gmpfr bounds. // TODO: Beyond writing generically, optimize this function. This would -// remove the need for the next function, which essentially the same. +// remove the need for the next function, which is essentially the same. template<> void Bisection_refiner_1,Gmpfr>:: @@ -58,8 +58,6 @@ operator()(const Polynomial &pol,Gmpfr &left,Gmpfr &right,int prec){ typedef CGAL::RS_AK1::Signat_1 Signat; CGAL_precondition(left<=right); - // TODO: add precondition to check whether the interval is a point - // or the evaluations on its endpoints have different signs //std::cout<<"refining ["< &pol,Gmpfr &left,Gmpfr &right,int prec){ mpfr_t center; sl=signof(left); + CGAL_precondition(sl!=signof(right)||(left==right&&sl==ZERO)); if(sl==ZERO) return; pl=left.get_precision(); @@ -120,8 +119,6 @@ operator()(const Polynomial &pol,Gmpfr &left,Gmpfr &right,int prec){ typedef CGAL::RS_AK1::Signat_1 Signat; CGAL_precondition(left<=right); - // TODO: add precondition to check whether the interval is a point - // or the evaluations on its endpoints have different signs //std::cout<<"refining ["< &pol,Gmpfr &left,Gmpfr &right,int prec){ mpfr_t center; sl=signof(left); + CGAL_precondition(sl!=signof(right)||(left==right&&sl==ZERO)); if(sl==ZERO) return; pl=left.get_precision(); diff --git a/Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h b/Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h index e00d4eccb4e..91e5d859bb9 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h @@ -26,6 +26,11 @@ #include #include "Gmpfr_make_unique.h" +// If we want assertions, we need to evaluate. +#ifndef CGAL_NO_ASSERTIONS +#include "signat_1.h" +#endif + namespace CGAL{ namespace RS3{ @@ -51,8 +56,15 @@ operator() typedef Polynomial_traits_d Ptraits; typedef Ptraits::Degree Degree; CGAL_precondition(left<=right); - // TODO: add precondition to check whether the interval is a point - // or the evaluations on its endpoints have different signs +#ifndef CGAL_NO_ASSERTIONS + typedef Ptraits::Make_square_free Sfpart; + typedef CGAL::RS_AK1::Signat_1 + Signat; + Polynomial sfpp=Sfpart()(pol); + Signat signof(sfpp); + CGAL::Sign sl=signof(left); + CGAL_precondition(sl!=signof(right)||(left==right&&sl==ZERO)); +#endif //std::cout<<"refining ["< ZPtraits; typedef ZPtraits::Degree ZDegree; CGAL_precondition(left<=right); - // TODO: add precondition to check whether the interval is a point - // or the evaluations on its endpoints have different signs +#ifndef CGAL_NO_ASSERTIONS + typedef ZPtraits::Make_square_free ZSfpart; + typedef CGAL::RS_AK1::Signat_1 + Signat; +#endif //std::cout<<"refining ["< zpol=CGAL::RS_AK1::Polynomial_converter_1< CGAL::Polynomial, CGAL::Polynomial >()(qpol); +#ifndef CGAL_NO_ASSERTIONS + ZPolynomial zsfpp=ZSfpart()(zpol); + Signat signof(zsfpp); + CGAL::Sign sl=signof(left); + CGAL_precondition(sl!=signof(right)||(left==right&&sl==ZERO)); +#endif int deg=ZDegree()(zpol); mpz_t* coefficients=(mpz_t*)malloc((deg+1)*sizeof(mpz_t)); __mpfi_struct interval; diff --git a/Algebraic_kernel_d/include/CGAL/RS/rs3_refiner_1.h b/Algebraic_kernel_d/include/CGAL/RS/rs3_refiner_1.h index 9755484b080..62fdcaae1fe 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/rs3_refiner_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/rs3_refiner_1.h @@ -26,6 +26,11 @@ #include #include "Gmpfr_make_unique.h" +// If we want assertions, we need to evaluate. +#ifndef CGAL_NO_ASSERTIONS +#include "signat_1.h" +#endif + namespace CGAL{ namespace RS3{ @@ -51,8 +56,15 @@ operator() typedef Polynomial_traits_d Ptraits; typedef Ptraits::Degree Degree; CGAL_precondition(left<=right); - // TODO: add precondition to check whether the interval is a point - // or the evaluations on its endpoints have different signs +#ifndef CGAL_NO_ASSERTIONS + typedef Ptraits::Make_square_free Sfpart; + typedef CGAL::RS_AK1::Signat_1 + Signat; + Polynomial sfpp=Sfpart()(pol); + Signat signof(sfpp); + CGAL::Sign sl=signof(left); + CGAL_precondition(sl!=signof(right)||(left==right&&sl==ZERO)); +#endif //std::cout<<"refining ["< ZPtraits; typedef ZPtraits::Degree ZDegree; CGAL_precondition(left<=right); - // TODO: add precondition to check whether the interval is a point - // or the evaluations on its endpoints have different signs +#ifndef CGAL_NO_ASSERTIONS + typedef ZPtraits::Make_square_free ZSfpart; + typedef CGAL::RS_AK1::Signat_1 + Signat; +#endif //std::cout<<"refining ["< zpol=CGAL::RS_AK1::Polynomial_converter_1< CGAL::Polynomial, CGAL::Polynomial >()(qpol); +#ifndef CGAL_NO_ASSERTIONS + ZPolynomial zsfpp=ZSfpart()(zpol); + Signat signof(zsfpp); + CGAL::Sign sl=signof(left); + CGAL_precondition(sl!=signof(right)||(left==right&&sl==ZERO)); +#endif int deg=ZDegree()(zpol); mpz_t* coefficients=(mpz_t*)malloc((deg+1)*sizeof(mpz_t)); __mpfi_struct interval; From c2fc680dbde4338e86bdc3ce2594bf46aa9e334a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Pe=C3=B1aranda?= Date: Fri, 12 Aug 2016 17:00:04 -0300 Subject: [PATCH 2/8] Forgot an include. It's to convert a polynomial to an integer polynomial with the same roots. --- Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h b/Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h index 91e5d859bb9..195e5bb9c15 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h @@ -22,6 +22,7 @@ #define CGAL_RS_RS3_K_REFINER_1_H #include +#include "polynomial_converter_1.h" #include "rs2_calls.h" #include #include "Gmpfr_make_unique.h" From c21a198a931e73d081c66e0b34b579c58731f620 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Pe=C3=B1aranda?= Date: Fri, 12 Aug 2016 17:01:01 -0300 Subject: [PATCH 3/8] Added assertion in RS2 calls. When the isolator calls the function to add roots to the output, it is checked that the roots are well formed (left<=right). --- Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h b/Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h index 381d28ad8a5..6db73d51467 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h +++ b/Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h @@ -120,6 +120,7 @@ struct RS2_calls{ // Construct Gmpfr's with pointers to endpoints. Gmpfr left(&(root_pointer->left),root_prec); Gmpfr right(&(root_pointer->right),root_prec); + CGAL_assertion(left<=right); // Copy them, to have the data out of RS memory. *x++=Gmpfi(left,right,root_prec+1); ident_node=rs_export_list_vect_ibfr_nextnode From ab322e764c9820b01da2232a9de035d2ec61904d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Pe=C3=B1aranda?= Date: Fri, 12 Aug 2016 17:03:26 -0300 Subject: [PATCH 4/8] Add assertion to the K-isolator. After RS isolates the roots and before RS3 refines them, it is asserted that they are well formed (left<=right). --- Algebraic_kernel_d/include/CGAL/RS/rs23_k_isolator_1.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Algebraic_kernel_d/include/CGAL/RS/rs23_k_isolator_1.h b/Algebraic_kernel_d/include/CGAL/RS/rs23_k_isolator_1.h index ac98576e287..ffb89c7ad4c 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/rs23_k_isolator_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/rs23_k_isolator_1.h @@ -80,6 +80,7 @@ RS23_k_isolator_1(const CGAL::Polynomial &p):_polynomial(p){ for(int j=0;j Date: Wed, 17 Aug 2016 15:00:51 -0300 Subject: [PATCH 5/8] Enforced const-correctness in algebraic numbers. Since the endpoints are mutable, functions that refine algebraic numbers must be const. --- Algebraic_kernel_d/include/CGAL/RS/algebraic_1.h | 11 ++++++----- Algebraic_kernel_d/include/CGAL/RS/algebraic_z_1.h | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Algebraic_kernel_d/include/CGAL/RS/algebraic_1.h b/Algebraic_kernel_d/include/CGAL/RS/algebraic_1.h index fa8a1e81c07..94219ca1d02 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/algebraic_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/algebraic_1.h @@ -192,12 +192,13 @@ boost::totally_ordered RT; typedef typename RT::To_double TD; - Refiner()(get_pol(),get_left(),get_right(),CGAL_RS_DBL_PREC); - CGAL_assertion(TD()(get_left())==TD()(get_right())); - return TD()(get_left()); + Refiner()(pol,left,right,CGAL_RS_DBL_PREC); + CGAL_assertion(TD()(left)==TD()(right)); + return TD()(left); } std::pair to_interval()const{ typedef Real_embeddable_traits RT; @@ -266,7 +267,7 @@ public INTERN_RET::Real_embeddable_traits_base< class To_double:public std::unary_function{ public: - double operator()(Type a)const{return a.to_double();} + double operator()(const Type &a)const{return a.to_double();} }; class To_interval: diff --git a/Algebraic_kernel_d/include/CGAL/RS/algebraic_z_1.h b/Algebraic_kernel_d/include/CGAL/RS/algebraic_z_1.h index 3cea711c24c..9e105a2c146 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/algebraic_z_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/algebraic_z_1.h @@ -184,7 +184,7 @@ boost::totally_ordered RT; typedef typename RT::To_double TD; ZRefiner()(get_zpol(), @@ -258,7 +258,7 @@ public INTERN_RET::Real_embeddable_traits_base< class To_double:public std::unary_function{ public: - double operator()(Type a)const{return a.to_double();} + double operator()(const Type &a)const{return a.to_double();} }; class To_interval: From 07fb6dd2a44a53b747696c989272a57be10b40ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Pe=C3=B1aranda?= Date: Wed, 12 Oct 2016 18:36:01 -0300 Subject: [PATCH 6/8] Abort compilation if MPFR is 3.1.4 or 3.1.5. Those two versions have a bug in memory allocation. The bug appears when changing the allocation functions back and forth. In the beginning, MPFR 3.1.4 and 3.1.5 gather the GMP allocation functions and always use them. If they are changed, MPFR does never notice that. This behavior was removed in a patch to 3.1.5, what means that everything should be OK with MPFR 3.2.0. --- Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h b/Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h index 6db73d51467..c4778be938f 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h +++ b/Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h @@ -33,6 +33,16 @@ #define CGALRS_PTR(a) void *a #endif +// RS does not work with MPFR 3.1.4 and 3.1.5. In case the version of MPFR +// is one of those buggy versions, ask the user to update and abort the +// compilation. +#include +BOOST_STATIC_ASSERT_MSG( + MPFR_VERSION_MAJOR!=3 || \ + MPFR_VERSION_MINOR!=1 || \ + (MPFR_VERSION_PATCHLEVEL!=4 && MPFR_VERSION_PATCHLEVEL!=5), \ + "RS does not work with MPFR 3.1.4 and 3.1.5. Please update MPFR."); + namespace CGAL{ namespace RS2{ From bceff2255ff80d6549a6d1f0e7997fe9cc963531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Pe=C3=B1aranda?= Date: Thu, 13 Oct 2016 10:17:59 -0300 Subject: [PATCH 7/8] Avoid also MPFR 3.1.3. Improve error message. --- Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h b/Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h index c4778be938f..e9424448a20 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h +++ b/Algebraic_kernel_d/include/CGAL/RS/rs2_calls.h @@ -33,15 +33,18 @@ #define CGALRS_PTR(a) void *a #endif -// RS does not work with MPFR 3.1.4 and 3.1.5. In case the version of MPFR -// is one of those buggy versions, ask the user to update and abort the -// compilation. +// RS3 does not work with MPFR 3.1.3 to 3.1.5. In case RS3 is enabled and +// the version of MPFR is one of those buggy versions, abort the compilation +// and instruct the user to update MPFR or don't use RS3. +#ifdef CGAL_USE_RS3 #include BOOST_STATIC_ASSERT_MSG( - MPFR_VERSION_MAJOR!=3 || \ - MPFR_VERSION_MINOR!=1 || \ - (MPFR_VERSION_PATCHLEVEL!=4 && MPFR_VERSION_PATCHLEVEL!=5), \ - "RS does not work with MPFR 3.1.4 and 3.1.5. Please update MPFR."); + MPFR_VERSION_MAJOR!=3 || + MPFR_VERSION_MINOR!=1 || + MPFR_VERSION_PATCHLEVEL<3 || MPFR_VERSION_PATCHLEVEL>5, + "RS3 does not work with MPFR versions 3.1.3 to 3.1.5. "# + "Please update MPFR or disable RS3."); +#endif // CGAL_USE_RS3 namespace CGAL{ namespace RS2{ From 275581537b51db6272e43ac86908d23a1b46ed59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Pe=C3=B1aranda?= Date: Tue, 18 Oct 2016 12:57:49 -0300 Subject: [PATCH 8/8] CGAL_NO_ASSERTIONS -> CGAL_NO_PRECONDITIONS --- Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h | 8 ++++---- Algebraic_kernel_d/include/CGAL/RS/rs3_refiner_1.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h b/Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h index 195e5bb9c15..e9d6457ca30 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/rs3_k_refiner_1.h @@ -28,7 +28,7 @@ #include "Gmpfr_make_unique.h" // If we want assertions, we need to evaluate. -#ifndef CGAL_NO_ASSERTIONS +#ifndef CGAL_NO_PRECONDITIONS #include "signat_1.h" #endif @@ -57,7 +57,7 @@ operator() typedef Polynomial_traits_d Ptraits; typedef Ptraits::Degree Degree; CGAL_precondition(left<=right); -#ifndef CGAL_NO_ASSERTIONS +#ifndef CGAL_NO_PRECONDITIONS typedef Ptraits::Make_square_free Sfpart; typedef CGAL::RS_AK1::Signat_1 Signat; @@ -111,7 +111,7 @@ operator() typedef Polynomial_traits_d ZPtraits; typedef ZPtraits::Degree ZDegree; CGAL_precondition(left<=right); -#ifndef CGAL_NO_ASSERTIONS +#ifndef CGAL_NO_PRECONDITIONS typedef ZPtraits::Make_square_free ZSfpart; typedef CGAL::RS_AK1::Signat_1 Signat; @@ -120,7 +120,7 @@ operator() Polynomial zpol=CGAL::RS_AK1::Polynomial_converter_1< CGAL::Polynomial, CGAL::Polynomial >()(qpol); -#ifndef CGAL_NO_ASSERTIONS +#ifndef CGAL_NO_PRECONDITIONS ZPolynomial zsfpp=ZSfpart()(zpol); Signat signof(zsfpp); CGAL::Sign sl=signof(left); diff --git a/Algebraic_kernel_d/include/CGAL/RS/rs3_refiner_1.h b/Algebraic_kernel_d/include/CGAL/RS/rs3_refiner_1.h index 62fdcaae1fe..29d3756543d 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/rs3_refiner_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/rs3_refiner_1.h @@ -27,7 +27,7 @@ #include "Gmpfr_make_unique.h" // If we want assertions, we need to evaluate. -#ifndef CGAL_NO_ASSERTIONS +#ifndef CGAL_NO_PRECONDITIONS #include "signat_1.h" #endif @@ -56,7 +56,7 @@ operator() typedef Polynomial_traits_d Ptraits; typedef Ptraits::Degree Degree; CGAL_precondition(left<=right); -#ifndef CGAL_NO_ASSERTIONS +#ifndef CGAL_NO_PRECONDITIONS typedef Ptraits::Make_square_free Sfpart; typedef CGAL::RS_AK1::Signat_1 Signat; @@ -116,7 +116,7 @@ operator() typedef Polynomial_traits_d ZPtraits; typedef ZPtraits::Degree ZDegree; CGAL_precondition(left<=right); -#ifndef CGAL_NO_ASSERTIONS +#ifndef CGAL_NO_PRECONDITIONS typedef ZPtraits::Make_square_free ZSfpart; typedef CGAL::RS_AK1::Signat_1 Signat; @@ -126,7 +126,7 @@ operator() Polynomial zpol=CGAL::RS_AK1::Polynomial_converter_1< CGAL::Polynomial, CGAL::Polynomial >()(qpol); -#ifndef CGAL_NO_ASSERTIONS +#ifndef CGAL_NO_PRECONDITIONS ZPolynomial zsfpp=ZSfpart()(zpol); Signat signof(zsfpp); CGAL::Sign sl=signof(left);