diff --git a/Number_types/include/CGAL/Lazy_exact_nt.h b/Number_types/include/CGAL/Lazy_exact_nt.h index 831f1ad5101..a5abb5984c5 100644 --- a/Number_types/include/CGAL/Lazy_exact_nt.h +++ b/Number_types/include/CGAL/Lazy_exact_nt.h @@ -1246,7 +1246,7 @@ class Is_valid< Lazy_exact_nt > : public Unary_function< Lazy_exact_nt, bool > { public : bool operator()( const Lazy_exact_nt& x ) const { - return is_valid(x.approx()) || is_valid(x.exact()); + return is_valid(x.approx()); } }; @@ -1268,7 +1268,6 @@ fit_in_double(const Lazy_exact_nt& l, double& r) // We create a type of new node in Lazy_exact_nt's DAG // for the make_root_of_2() operation. -#if 0 // To be finished template struct Lazy_exact_ro2 : public Lazy_exact_nt_rep< typename Root_of_traits::RootOf_2 > @@ -1314,27 +1313,48 @@ struct Lazy_exact_ro2 } }; -template < typename ET > -inline -Lazy_exact_nt< typename Root_of_traits::RootOf_2 > -make_root_of_2( const Lazy_exact_nt &a, - const Lazy_exact_nt &b, - const Lazy_exact_nt &c, bool d) -{ - return new Lazy_exact_ro2(a, b, c, d); -} - template struct Root_of_traits< Lazy_exact_nt < NT > > { private: typedef Root_of_traits T; public: + typedef Root_of_traits< Lazy_exact_nt < NT > > Base; typedef Lazy_exact_nt< typename T::RootOf_1 > RootOf_1; typedef Lazy_exact_nt< typename T::RootOf_2 > RootOf_2; + typedef RootOf_2 Root_of_2; + typedef RootOf_1 Root_of_1; + struct Make_root_of_2{ + typedef RootOf_2 result_type; + Root_of_2 + operator()(const Lazy_exact_nt& a, const Lazy_exact_nt& b, const Lazy_exact_nt& c) const{ + return new Lazy_exact_ro2(a, b, c, true); + }; + RootOf_2 + operator()(const Lazy_exact_nt& a, const Lazy_exact_nt& b, const Lazy_exact_nt& c, bool smaller) const{ + return new Lazy_exact_ro2(a, b, c, smaller); + }; + }; + }; -#endif // 0 + +//these two functions for test suite requirement +template < typename RT > +typename CGAL::Root_of_traits >::RootOf_2 make_sqrt(const CGAL::Lazy_exact_nt< RT> & r) +{ + typedef Lazy_exact_nt< RT> TT; + CGAL_assertion(r >= 0); + if(CGAL_NTS is_zero(r)) return make_root_of_2((TT) 1,(TT) 0,(TT) 0); + return make_root_of_2((TT) 1,(TT) 0,-r,false); +} + +template < typename RT > +void +print(std::ostream &os, const CGAL::Lazy_exact_nt< Root_of_2 > &r) +{ + print(os,r.exact()); +} #undef CGAL_double #undef CGAL_int diff --git a/Number_types/include/CGAL/Root_of_2.h b/Number_types/include/CGAL/Root_of_2.h index ae41092c344..f21385931e8 100644 --- a/Number_types/include/CGAL/Root_of_2.h +++ b/Number_types/include/CGAL/Root_of_2.h @@ -992,7 +992,7 @@ Root_of_2 make_sqrt(const RT& r) } template < typename RT > -Root_of_2 make_sqrt(const typename Root_of_traits< RT >::RootOf_1 r) +Root_of_2 make_sqrt(const typename Root_of_traits< RT >::RootOf_1& r) { CGAL_assertion(r >= 0); if(CGAL_NTS is_zero(r)) return Root_of_2(); diff --git a/Number_types/test/Number_types/Root_of_traits.C b/Number_types/test/Number_types/Root_of_traits.C index 70131de6d32..7c2db2628f4 100644 --- a/Number_types/test/Number_types/Root_of_traits.C +++ b/Number_types/test/Number_types/Root_of_traits.C @@ -57,11 +57,10 @@ int main(){ test_root_of_traits(); test_root_of_traits(); }{ - typedef CGAL::Lazy_exact_nt RT; - typedef CGAL::Quotient > Root_of_1; - typedef CGAL::Root_of_2 > Root_of_2; - - test_root_of_traits(); + typedef CGAL::Lazy_exact_nt RT; + typedef CGAL::Lazy_exact_nt Root_of_1; + typedef CGAL::Lazy_exact_nt > Root_of_2; + test_root_of_traits(); test_root_of_traits(); } #endif diff --git a/Number_types/test/Number_types/root_of_2.C b/Number_types/test/Number_types/root_of_2.C index e7c20508ba9..fb965d90a69 100644 --- a/Number_types/test/Number_types/root_of_2.C +++ b/Number_types/test/Number_types/root_of_2.C @@ -58,26 +58,84 @@ NT my_rand() return rnd.get_int(-64, 63); } + +//---------------------- + +template +bool is_RO2_class(const typename CGAL::Root_of_2& ){ return true;} +template +bool is_RO2_class(const T& ){ return false;} + +template +CGAL::Root_of_2 conjugate(const typename CGAL::Root_of_2& R){ + return R.conjugate(); +} + +template +T conjugate(const T& R){ return T(); } + + +template +T inverse_helper(const T& R){ return (T) 1/R; } + +template +CGAL::Root_of_2 inverse_helper(const typename CGAL::Root_of_2& R){ + return inverse(R); +} + +template +bool is_smaller_helper(const T& R){ return R.exact().is_smaller(); } + +template +bool is_smaller_helper(const typename CGAL::Root_of_2& R){ return R.is_smaller();} + +template +RT bracket(const T& R,int i){ return R.exact()[i]; } + +template +RT bracket(const typename CGAL::Root_of_2& R,int i){ + return R[i]; +} + + + +//---------------------------- +template < class Root, class RT > +Root create_root_helper(RT a, RT b, Root *) +{ + return Root(a)/b; +} + +template < class T, class RT > +CGAL::Root_of_2 create_root_helper(RT a, RT b, typename CGAL::Root_of_2 *) +{ + return CGAL::Root_of_2(a, b); +} + +template < class Root, class RT > +Root create_root(RT a, RT b) +{ + return create_root_helper(a, b, (Root*) 0); +} + // Generate random Root_of_2 of degree 1 -template < typename Root > +template < typename Root,typename RT > Root my_rand_root_1() { - typedef typename Root::RT RT; Root r; do { RT a = my_rand(); if (a == 0) continue; - r = Root(my_rand(), a); + r = create_root(my_rand(), a); } while (! is_valid(r)); return r; } // Generate random Root_of_2 of degree 2 -template < typename Root > +template < typename Root,typename RT > Root my_rand_root() { - typedef typename Root::RT RT; do { RT a = my_rand(); RT b = my_rand(); @@ -85,9 +143,9 @@ Root my_rand_root() if (a == 0 && b == 0) return Root(c); if (a == 0) - return Root(c, b); + return create_root(c, b); if (b*b-4*a*c >= 0) - return Root(a, b, c, rnd.get_bool()); + return CGAL::make_root_of_2(a, b, c, rnd.get_bool()); } while (true); } @@ -111,13 +169,13 @@ test_compare(const Root &r1, const Root &r2) return false; } -template < typename Root > +template < typename RT, typename Root > bool test_to_interval(const Root &r1) { std::pair the_interval = CGAL_NTS to_interval(r1); if(!((to_double(r1) >= the_interval.first) && (to_double(r1) <= the_interval.second))) { - std::cout << r1[2] << " " << r1[1] << " " << r1[0] << " " << r1.is_smaller() << std::endl; + std::cout << bracket(r1,2) << " " << bracket(r1,1) << " " << bracket(r1,0) << " " << is_smaller_helper(r1) << std::endl; std::cout << setprecision (18) << to_double(r1) << std::endl; std::cout << "[" << setprecision (18) << the_interval.first << "," << setprecision (18) << the_interval.second << "]"; } @@ -126,30 +184,30 @@ test_to_interval(const Root &r1) -template < typename Root > + +template < typename Root,typename RT,typename FT > bool -test_root_of() +test_root_of_g() { - typedef typename Root::RT RT; CGAL::test_real_embeddable(); std::cout << " Testing zeros" << std::endl; - Root zero1(1, 0, 0, true); - Root zero2(1, 0, 0, false); + Root zero1=CGAL::make_root_of_2((RT) 1,(RT)0,(RT)0, true); + Root zero2=CGAL::make_root_of_2((RT)1,(RT)0,(RT)0, false); Root zero3(0); - assert(zero1.conjugate() == zero2); - assert(zero2.conjugate() == zero1); - assert(zero3.conjugate() == zero3); + if (is_RO2_class(zero1)) assert(conjugate(zero1) == zero2); + if (is_RO2_class(zero2)) assert(conjugate(zero2) == zero1); + if (is_RO2_class(zero3)) assert(conjugate(zero3) == zero3); assert(is_valid(zero1)); assert(is_valid(zero2)); assert(is_valid(zero3)); assert(CGAL_NTS to_double(zero1) == 0.0); assert(CGAL_NTS to_double(zero2) == 0.0); assert(CGAL_NTS to_double(zero3) == 0.0); - assert(test_to_interval(zero1)); - assert(test_to_interval(zero2)); - assert(test_to_interval(zero3)); + assert(test_to_interval(zero1)); + assert(test_to_interval(zero2)); + assert(test_to_interval(zero3)); assert(CGAL_NTS sign(zero1) == 0); assert(CGAL_NTS sign(zero2) == 0); assert(CGAL_NTS sign(zero3) == 0); @@ -183,15 +241,15 @@ test_root_of() assert(CGAL_NTS compare(zero2, zero3) == 0); std::cout << " Testing ones" << std::endl; - Root one1 (-1, 0, 1, false); - Root mone1(-1, 0, 1, true); + Root one1=CGAL::make_root_of_2 ((RT)-1,(RT) 0,(RT) 1, false); + Root mone1=CGAL::make_root_of_2((RT)-1,(RT) 0,(RT) 1, true); Root one2 = Root(1); Root mone2 = Root(-1); - Root one3 = Root(1, 1); - Root mone3 = Root(-1, 1); + Root one3 = create_root((RT) 1,(RT) 1); + Root mone3 = create_root(-1, 1); - assert(one1.conjugate() == mone1); - + if (is_RO2_class(one1)) assert(conjugate(one1) == mone1); + //It is not true that those must hold //assert(one2.conjugate() == mone2); //assert(one3.conjugate() == mone3); @@ -203,12 +261,12 @@ test_root_of() assert(CGAL_NTS to_double(mone1) == -1.0); assert(CGAL_NTS to_double(one2) == 1.0); assert(CGAL_NTS to_double(mone2) == -1.0); - assert(test_to_interval(one1)); - assert(test_to_interval(mone1)); - assert(test_to_interval(one2)); - assert(test_to_interval(mone2)); - assert(test_to_interval(one3)); - assert(test_to_interval(mone3)); + assert(test_to_interval(one1)); + assert(test_to_interval(mone1)); + assert(test_to_interval(one2)); + assert(test_to_interval(mone2)); + assert(test_to_interval(one3)); + assert(test_to_interval(mone3)); assert(CGAL_NTS sign( one1) > 0); assert(CGAL_NTS sign( one2) > 0); @@ -261,16 +319,16 @@ test_root_of() assert(CGAL_NTS compare( Root(0), Root(1)) < 0); assert(CGAL_NTS compare( Root(1), Root(-1)) > 0); - assert(CGAL_NTS compare( Root(-4, 2), Root(-2)) == 0); - assert(CGAL_NTS compare( Root(-4, 2), Root(-1)) < 0); - assert(CGAL_NTS compare( Root(-4, 2), Root(-3)) > 0); + assert(CGAL_NTS compare( create_root(-4, 2), Root(-2)) == 0); + assert(CGAL_NTS compare( create_root(-4, 2), Root(-1)) < 0); + assert(CGAL_NTS compare( create_root(-4, 2), Root(-3)) > 0); std::cout << " Testing degree 1 and 2" << std::endl; - Root rone(1, 0, -1, false); - Root rmone(1, 0, -1, true); - assert(rone.conjugate() == rmone); - assert(test_to_interval(rone)); - assert(test_to_interval(rmone)); + Root rone=CGAL::make_root_of_2((RT)1, (RT)0, (RT)-1, false); + Root rmone=CGAL::make_root_of_2((RT)1, (RT)0,(RT) -1, true); + if (is_RO2_class(rone)) assert(conjugate(rone) == rmone); + assert(test_to_interval(rone)); + assert(test_to_interval(rmone)); // Compare the two roots of the above polynomial (-1 and 1), // succesively with -2, -1, 0, 1, 2. assert(CGAL_NTS compare(Root(-2), rmone) < 0); @@ -302,55 +360,55 @@ test_root_of() Root r1 = Root(my_rand()); Root r2 = Root(my_rand()); assert(r1 == r1); - assert(test_to_interval(r1)); + assert(test_to_interval(r1)); assert(r2 == r2); - assert(test_to_interval(r2)); + assert(test_to_interval(r2)); // assert(test_compare(r1, r2)); } std::cout << " Testing random roots of degree 1" << std::endl; for (int i = 0; i < test_loops; ++i) { - Root r1 = my_rand_root_1(); - Root r2 = my_rand_root_1(); + Root r1 = my_rand_root_1(); + Root r2 = my_rand_root_1(); assert(r1 == r1); - assert(test_to_interval(r1)); + assert(test_to_interval(r1)); assert(r2 == r2); - assert(test_to_interval(r2)); + assert(test_to_interval(r2)); // assert(test_compare(r1, r2)); } std::cout << " Testing random roots of degree 2" << std::endl; for (int i = 0; i < test_loops; ++i) { - Root r1 = my_rand_root(); - Root r2 = my_rand_root(); + Root r1 = my_rand_root(); + Root r2 = my_rand_root(); assert(r1 == r1); - assert(test_to_interval(r1)); + assert(test_to_interval(r1)); assert(r2 == r2); - assert(test_to_interval(r2)); + assert(test_to_interval(r2)); // assert(test_compare(r1, r2)); } std::cout << " Testing random roots of degree 1 and 2" << std::endl; for (int i = 0; i < test_loops; ++i) { - Root r1 = my_rand_root_1(); - Root r2 = my_rand_root(); + Root r1 = my_rand_root_1(); + Root r2 = my_rand_root(); assert(r1 == r1); - assert(test_to_interval(r1)); + assert(test_to_interval(r1)); assert(r2 == r2); - assert(test_to_interval(r2)); + assert(test_to_interval(r2)); // assert(test_compare(r1, r2)); } std::cout << " Testing squares of random roots of degree 2" << std::endl; for (int i = 0; i < test_loops; ++i) { - Root r1 = my_rand_root(); - Root r2 = my_rand_root(); + Root r1 = my_rand_root(); + Root r2 = my_rand_root(); Root r1_sqr = CGAL_NTS square(r1); Root r2_sqr = CGAL_NTS square(r2); - assert(test_to_interval(r1)); - assert(test_to_interval(r2)); - assert(test_to_interval(r1_sqr)); - assert(test_to_interval(r2_sqr)); + assert(test_to_interval(r1)); + assert(test_to_interval(r2)); + assert(test_to_interval(r1_sqr)); + assert(test_to_interval(r2_sqr)); // double dr1 = to_double(r1); // double dr2 = to_double(r2); // assert(CGAL_NTS compare(r1_sqr, r2_sqr) == compare(dr1*dr1, dr2*dr2)); @@ -360,7 +418,7 @@ test_root_of() << std::endl; for (int i = 0; i < test_loops; ++i) { RT r = my_rand(); - Root r1 = my_rand_root(); + Root r1 = my_rand_root(); Root r2 = r1 - r; Root r3 = r1 + r; Root r4 = r - r1; @@ -370,11 +428,11 @@ test_root_of() assert(r3 == r3); assert(r4 == r4); assert(r5 == r5); - assert(test_to_interval(r1)); - assert(test_to_interval(r2)); - assert(test_to_interval(r3)); - assert(test_to_interval(r4)); - assert(test_to_interval(r5)); + assert(test_to_interval(r1)); + assert(test_to_interval(r2)); + assert(test_to_interval(r3)); + assert(test_to_interval(r4)); + assert(test_to_interval(r5)); // assert(test_compare(r1, r2)); // assert(test_compare(r1, r3)); // assert(test_compare(r1, r4)); @@ -388,31 +446,31 @@ test_root_of() std::cout << " Testing multiplication of Root_of_2 with NT" << std::endl; for (int i = 0; i < test_loops; ++i) { RT r = my_rand(); - Root r1 = my_rand_root(); + Root r1 = my_rand_root(); Root r2 = r1 * r; Root r3 = r * r1; int n = rnd.get_int(0, 63); - typename Root::FT rn(n); + FT rn(n); if (r != 0){ Root r4 = r2 / r; assert(r4 == r4); - assert(test_to_interval(r4)); + assert(test_to_interval(r4)); assert(r4 == r1); } if (n != 0){ - Root r5 = my_rand_root(); + Root r5 = my_rand_root(); Root r6 = r5 * rn; Root r4 = r6 / rn; assert(r4 == r4); - assert(test_to_interval(r4)); + assert(test_to_interval(r4)); assert(r4 == r5); } assert(r1 == r1); assert(r2 == r2); assert(r3 == r3); - assert(test_to_interval(r1)); - assert(test_to_interval(r2)); - assert(test_to_interval(r3)); + assert(test_to_interval(r1)); + assert(test_to_interval(r2)); + assert(test_to_interval(r3)); // assert(test_compare(r1, r2)); // assert(test_compare(r1, r3)); // assert(test_compare(r2, r3)); @@ -431,16 +489,16 @@ test_root_of() std::cout << " Testing the inverse of random roots of degree 2" << std::endl; for (int i = 0; i < test_loops; ++i) { - Root r1 = my_rand_root(); - Root r2 = my_rand_root(); - while(r1 == 0) r1 = my_rand_root(); - while(r2 == 0) r2 = my_rand_root(); - Root r1_inv = inverse(r1); - Root r2_inv = inverse(r2); - assert(test_to_interval(r1)); - assert(test_to_interval(r2)); - assert(test_to_interval(r1_inv)); - assert(test_to_interval(r2_inv)); + Root r1 = my_rand_root(); + Root r2 = my_rand_root(); + while(r1 == 0) r1 = my_rand_root(); + while(r2 == 0) r2 = my_rand_root(); + Root r1_inv = inverse_helper(r1); + Root r2_inv = inverse_helper(r2); + assert(test_to_interval(r1)); + assert(test_to_interval(r2)); + assert(test_to_interval(r1_inv)); + assert(test_to_interval(r2_inv)); // double dr1 = to_double(r1); // double dr2 = to_double(r2); // assert(CGAL_NTS compare(r1_inv, r2_inv) == compare(1.0/dr1, 1.0/dr2)); @@ -454,8 +512,8 @@ test_root_of() while(r2 < 0) r2 = my_rand(); Root sqr_r1 = CGAL::make_sqrt(r1); Root sqr_r2 = CGAL::make_sqrt(r2); - assert(test_to_interval(sqr_r1)); - assert(test_to_interval(sqr_r2)); + assert(test_to_interval(sqr_r1)); + assert(test_to_interval(sqr_r2)); // double dr1 = to_double(r1); // double dr2 = to_double(r2); // assert(CGAL_NTS compare(sqr_r1, sqr_r2) == compare(std::sqrt(dr1), std::sqrt(dr2))); @@ -464,12 +522,11 @@ test_root_of() std::cout << " Testing Root_of_2" << std::endl; for (int i = 0; i < test_loops; ++i) { int n = rnd.get_int(0, 63); - typedef typename Root::FT FT; typedef CGAL::Rational_traits Rat_traits; FT r(n); Root r1(r); Root r2(n); - Root r3(Rat_traits().numerator(r), Rat_traits().denominator(r)); + Root r3=create_root(Rat_traits().numerator(r), Rat_traits().denominator(r)); assert(r1 == r1); assert(r2 == r2); assert(r3 == r3); @@ -480,6 +537,14 @@ test_root_of() return true; } +template +bool +test_root_of(){ + typedef typename Root::RT RT; + typedef typename Root::FT FT; + return test_root_of_g(); +} + // ALL THOSE TESTS ARE BASED ON COMPARING THE DOUBLE RESULT // WITH THE EXACT RESULT // THAT IS NOT NECESSARILY CORRECT @@ -493,7 +558,7 @@ int main(int argc, char **argv) { bool result = true; // std::cout << "Testing Root_of_2" << std::endl; -// result = result && test_root_of >(); + //~ result = result && test_root_of >(); std::cout << "Testing Root_of_2" << std::endl; result = result && test_root_of >(); @@ -507,8 +572,8 @@ int main(int argc, char **argv) { std::cout << "Testing Lazy_exact_nt's RootOf_2 " << std::endl; result = result && - test_root_of > - ::RootOf_2 >(); + test_root_of_g > + ::RootOf_2,CGAL::Lazy_exact_nt,CGAL::Lazy_exact_nt >(); #ifdef CGAL_USE_GMP