diff --git a/Number_types/include/CGAL/core_interval_support.h b/Number_types/include/CGAL/core_interval_support.h index b4a681867fd..825182f582a 100644 --- a/Number_types/include/CGAL/core_interval_support.h +++ b/Number_types/include/CGAL/core_interval_support.h @@ -29,176 +29,117 @@ CGAL_BEGIN_NAMESPACE -template long get_significant_bits(BFI bfi); - -CORE::BigFloat -inline -round(const CORE::BigFloat& x, long rel_prec = CORE::defRelPrec.toLong() ){ - CGAL_postcondition(rel_prec >= 0); - // since there is not rel prec defined if in_zero(x) - if (x.isZeroIn()) return x; - if (CGAL::get_significant_bits(x) <= rel_prec) return x; - - typedef CORE::BigFloat BF; - typedef CORE::BigFloat BFI; - typedef CORE::BigInt Integer; - BF xr; - - CORE::BigInt m = x.m(); - long err = x.err(); - long exp = x.exp(); - - long shift = ::CORE::bitLength(m) - rel_prec - 1; - if( shift > 0 ){ - Integer new_m = m >> shift ; - if(err == 0){ - xr = BF(new_m,1,0)*BF::exp2(exp*14+shift); - }else{ - xr = BF(new_m,2,0)*BF::exp2(exp*14+shift); - } - }else{ - // noting to do - xr = x; - } - - CGAL_postcondition(CGAL::abs(CGAL::get_significant_bits(xr) - rel_prec) <= 1); - CGAL_postcondition(BF(xr.m()-xr.err(),0,xr.exp()) <= BF(x.m()-x.err(),0,x.exp())); - CGAL_postcondition(BF(xr.m()+xr.err(),0,xr.exp()) >= BF(x.m()+x.err(),0,x.exp())); - return xr; -} - -template<> class Bigfloat_interval_traits -{ -public: - typedef CORE::BigFloat NT; - typedef CORE::BigFloat BF; - - typedef Bigfloat_interval_traits Self; - - class Get_significant_bits { - public: - // type for the \c AdaptableUnaryFunction concept. - typedef NT argument_type; - // type for the \c AdaptableUnaryFunction concept. - typedef long result_type; - - long operator()( NT x) const { - if(x.err() == 0 ) { - return ::CORE::bitLength(x.m()); - } - else { - return ::CORE::bitLength(x.m()) - ::CORE::bitLength(x.err()); - } - } - }; - - class Set_precision { - public: - // type for the \c AdaptableUnaryFunction concept. - typedef long argument_type; - // type for the \c AdaptableUnaryFunction concept. - typedef long result_type; - - long operator() ( long prec ) const { - long result = ::CORE::defRelPrec.toLong(); - ::CORE::defRelPrec = prec; - ::CORE::defBFdivRelPrec = prec; +template<> +class Interval_traits { +public: + typedef CORE::BigFloat Interval; + typedef CORE::BigFloat Boundary; + typedef Interval_traits Self; + + struct Lower :public Unary_function{ + Boundary operator() ( Interval x ) const { + CORE::BigFloat result = ::CORE::BigFloat(x.m()-x.err(),0,x.exp()); + CGAL_postcondition(result <= x); return result; } }; - - class Get_precision { - public: - // type for the \c AdaptableGenerator concept. - typedef long result_type; - - long operator() () const { - return ::CORE::defRelPrec.toLong(); - } - }; - - class Upper { - public: - // type for the \c AdaptableUnaryFunction concept. - typedef NT argument_type; - // type for the \c AdaptableUnaryFunction concept. - typedef BF result_type; - - BF operator() ( NT x ) const { + + struct Upper :public Unary_function{ + Boundary operator() ( Interval x ) const { CORE::BigFloat result = ::CORE::BigFloat(x.m()+x.err(),0,x.exp()); CGAL_postcondition(result >= x); return result; } }; - class Lower { - public: - // type for the \c AdaptableUnaryFunction concept. - typedef NT argument_type; - // type for the \c AdaptableUnaryFunction concept. - typedef BF result_type; + struct Width :public Unary_function{ - BF operator() ( NT x ) const { - CORE::BigFloat result = ::CORE::BigFloat(x.m()-x.err(),0,x.exp()); - CGAL_postcondition(result <= x); - return result; + Boundary operator() ( Interval x ) const { + unsigned long err = 2*x.err(); + return Boundary(CORE::BigInt(err),0,x.exp()); } }; - class In_zero { - public: - // type for the \c AdaptableUnaryFunction concept. - typedef NT argument_type; - // type for the \c AdaptableUnaryFunction concept. - typedef bool result_type; + struct Median :public Unary_function{ - bool operator() ( NT x ) const { + Boundary operator() ( Interval x ) const { + return Boundary(x.m(),0,x.exp()); + } + }; + + struct Norm :public Unary_function{ + Boundary operator() ( Interval x ) const { + return std::max(Upper()(x).abs(),Lower()(x).abs()); + } + }; + + struct Zero_in :public Unary_function{ + bool operator() ( Interval x ) const { return x.isZeroIn(); } }; - class Overlap { - public: - // type for the \c AdaptableBinaryFunction concept. - typedef NT first_argument_type; - // type for the \c AdaptableBinaryFunction concept. - typedef NT second_argument_type; - // type for the \c AdaptableBinaryFunction concept. - typedef bool result_type; + struct In :public Binary_function{ + bool operator()( Boundary x, const Interval& a ) const { + CGAL_precondition(CGAL::singleton(x)); + return (Lower()(a) <= x && x <= Upper()(a)); + } + }; + + struct Equal :public Binary_function{ + bool operator()( const Interval& a, const Interval& b ) const { + return (Upper()(a) == Upper()(b) && Lower()(a) == Lower()(b)); + } + }; - bool operator() ( NT x, NT y ) const { - Self::In_zero in_zero; - bool result = in_zero(x-y); + struct Subset :public Binary_function{ + bool operator()( const Interval& a, const Interval& b ) const { + return Lower()(b) <= Lower()(a) && Upper()(a) <= Upper()(b); + } + }; + + struct Proper_subset :public Binary_function{ + bool operator()( const Interval& a, const Interval& b ) const { + return Subset()(a,b) && (!Equal()(a,b)); + } + }; + + struct Intersection :public Binary_function{ + Interval operator()( const Interval& a, const Interval& b ) const { + // std::cout <<"a= (" << a.m() << "+-" << a.err() << ")*2^" << a.exp() << std::endl; + Boundary l(CGAL::max(Lower()(a),Lower()(b))); + Boundary u(CGAL::min(Upper()(a),Upper()(b))); + + if(u < l ) throw Exception_intersection_is_empty(); + return Construct()(l,u); + } + }; + + + struct Overlap :public Binary_function{ + bool operator() ( Interval x, Interval y ) const { + Self::Zero_in Zero_in; + bool result = Zero_in(x-y); return result; } }; - class Hull { - public: - // type for the \c AdaptableBinaryFunction concept. - typedef NT first_argument_type; - // type for the \c AdaptableBinaryFunction concept. - typedef NT second_argument_type; - // type for the \c AdaptableBinaryFunction concept. - typedef NT result_type; - - NT operator() ( NT x, NT y ) const { + struct Hull :public Binary_function{ + Interval operator() ( Interval x, Interval y ) const { #if 0 // this is not possible since CORE::centerize has a bug. - NT result = CORE::centerize(x,y); + Interval result = CORE::centerize(x,y); #else CORE::BigFloat result; // Unfortunately, CORE::centerize(x,y) has bugs. - if ((x.m() == y.m()) && (x.err() == y.err()) && (x.exp() == y.exp())) { + if ((x.m() == y.m()) && (x.err() == y.err()) && (x.exp() == y.exp())) { return x; } - CORE::BigFloat lower = std::min(CGAL::lower(x), - CGAL::lower(y)); - CORE::BigFloat upper = std::max(CGAL::upper(x), - CGAL::upper(y)); + CORE::BigFloat lower = std::min(CGAL::lower(x), CGAL::lower(y)); + CORE::BigFloat upper = std::max(CGAL::upper(x), CGAL::upper(y)); CORE::BigFloat mid = (lower + upper)/2; @@ -217,7 +158,7 @@ public: //std::cout << "shift " << shift<< std::endl; long new_err = ((err.m()+err.err()) >> shift).longValue()+1; err = CORE::BigFloat(0,new_err,0) * CORE::BigFloat::exp2(err.exp()*14+shift); - }else{ + }else{ err = CORE::BigFloat(0,err.m().longValue()+err.err(),err.exp()); } @@ -235,33 +176,111 @@ public: } }; - class Singleton { - public: + struct Singleton { // type for the \c AdaptableUnaryFunction concept. - typedef NT argument_type; + typedef Interval argument_type; // type for the \c AdaptableUnaryFunction concept. typedef bool result_type; - bool operator() ( NT x ) const { + bool operator() ( Interval x ) const { return (x.err() == 0); } }; - class Width { - public: + struct Construct :public Binary_function{ + Interval operator()( const Boundary& l,const Boundary& r) const { + CGAL_precondition( l < r ); + return Hull()(l,r); + } + }; +}; + + + + +template long get_significant_bits(BFI bfi); + +CORE::BigFloat +inline +round(const CORE::BigFloat& x, long rel_prec = CORE::defRelPrec.toLong() ){CGAL_postcondition(rel_prec >= 0); + // since there is not rel prec defined if Zero_in(x) + if (x.isZeroIn()) return x; + if (CGAL::get_significant_bits(x) <= rel_prec) return x; + + typedef CORE::BigFloat BF; + typedef CORE::BigFloat BFI; + typedef CORE::BigInt Integer; + BF xr; + + CORE::BigInt m = x.m(); + long err = x.err(); + long exp = x.exp(); + + long shift = ::CORE::bitLength(m) - rel_prec - 1; + if( shift > 0 ){ Integer new_m = m >> shift ; + if(err == 0){ xr = BF(new_m,1,0)*BF::exp2(exp*14+shift); + }else{ xr = BF(new_m,2,0)*BF::exp2(exp*14+shift); + } + }else{ // noting to do + xr = x; + } + + CGAL_postcondition(CGAL::abs(CGAL::get_significant_bits(xr) - rel_prec) <= 1); + CGAL_postcondition(BF(xr.m()-xr.err(),0,xr.exp()) <= BF(x.m()-x.err(),0,x.exp())); + CGAL_postcondition(BF(xr.m()+xr.err(),0,xr.exp()) >= BF(x.m()+x.err(),0,x.exp())); + return xr; +} + +template<> class Bigfloat_interval_traits +{ +public: + typedef CORE::BigFloat NT; + typedef CORE::BigFloat BF; + + typedef Bigfloat_interval_traits Self; + + // How about retuning + struct Get_significant_bits { // type for the \c AdaptableUnaryFunction concept. typedef NT argument_type; // type for the \c AdaptableUnaryFunction concept. - typedef BF result_type; - - BF operator() ( NT x ) const { - unsigned long err = 2*x.err(); - return BF(CORE::BigInt(err),0,x.exp()); + typedef long result_type; + + long operator()( NT x) const { + if(x.err() == 0 ) { + return ::CORE::bitLength(x.m()); + } + else { + return ::CORE::bitLength(x.m()) - ::CORE::bitLength(x.err()); + } + } + }; + + struct Set_precision { + // type for the \c AdaptableUnaryFunction concept. + typedef long argument_type; + // type for the \c AdaptableUnaryFunction concept. + typedef long result_type; + + long operator() ( long prec ) const { + long result = ::CORE::defRelPrec.toLong(); + ::CORE::defRelPrec = prec; + ::CORE::defBFdivRelPrec = prec; + return result; + } + }; + + struct Get_precision { + // type for the \c AdaptableGenerator concept. + typedef long result_type; + + long operator() () const { + return ::CORE::defRelPrec.toLong(); } }; - class Convert_to_bfi { - public: + struct Convert_to_bfi { + typedef NT result_type; diff --git a/Number_types/include/CGAL/interval_support.h b/Number_types/include/CGAL/interval_support.h index ea580f25701..4e7d4857c58 100644 --- a/Number_types/include/CGAL/interval_support.h +++ b/Number_types/include/CGAL/interval_support.h @@ -16,6 +16,29 @@ This is experimental */ + +/* bounds-related Interval functions */ +// template T lower(const Interval& x); +// template T upper(const Interval& x); +// template T width(const Interval& x); +// template T median(const Interval& x); +// template T norm(const Interval& x); + +/* bounds-related Interval functions */ +//// template bool empty(const Interval& b); +// template bool singleton(const Interval& x); +// template bool zero_in(const Interval& b); +// template bool in(const T& r, const Interval& b); +// template bool equal(const Interval& x, const Interval& y); +// template bool overlap(const Interval& x, const Interval& y); +// template bool subset(const Interval& a, const Interval& b); +// template bool proper_subset(const Interval& a, const Interval& b); + +/* set manipulation interval functions */ +// template Interval intersection(const Interval& x, const Interval& y); +// template Interval hull(const Interval& x, const Interval& y); + + #ifndef CGAL_INTERVAL_SUPPORT_H #define CGAL_INTERVAL_SUPPORT_H @@ -23,61 +46,146 @@ CGAL_BEGIN_NAMESPACE +template class Interval_traits; +class Exception_intersection_is_empty{}; + +// function returning type Boundary +template inline +typename Interval_traits::Boundary +lower(const Interval& interval) { + typename Interval_traits::Lower lower; + return lower(interval); +} + +template inline +typename Interval_traits::Boundary +upper(const Interval& interval) { + typename Interval_traits::Upper upper; + return upper(interval); +} + +template inline +typename Interval_traits::Boundary +width(Interval interval) { + typename Interval_traits::Width width; + return width(interval); +} + +template inline +typename Interval_traits::Boundary +median(Interval interval) { + typename Interval_traits::Median median; + return median(interval); +} + +template inline +typename Interval_traits::Boundary +norm(Interval interval) { + typename Interval_traits::Norm norm; + return norm(interval); +} + + +// functions returning bool + +template inline +typename Interval_traits::Empty::result_type +empty(Interval interval) { + typename Interval_traits::Empty empty; + return empty(interval); +} + +template inline +typename Interval_traits::Singleton::result_type +singleton(Interval interval) { + typename Interval_traits::Singleton singleton; + return singleton(interval); +} + +template inline +typename Interval_traits::In::result_type +in(typename Interval_traits::Boundary x, Interval interval) { + typename Interval_traits::In in; + return in(x,interval); +} + +template inline +typename Interval_traits::Zero_in::result_type +zero_in(Interval interval) { + typename Interval_traits::Zero_in zero_in; + return zero_in(interval); +} + +template inline +typename Interval_traits::Equal::result_type +equal(Interval interval1,Interval interval2) { + typename Interval_traits::Equal equal; + return equal(interval1,interval2); +} + +template inline +typename Interval_traits::Overlap::result_type +overlap(Interval interval1, Interval interval2) { + typename Interval_traits::Overlap overlap; + return overlap(interval1, interval2); +} + +template inline +typename Interval_traits::Subset::result_type +subset(Interval interval1, Interval interval2) { + typename Interval_traits::Subset subset; + return subset(interval1, interval2); +} + +template inline +typename Interval_traits::Proper_subset::result_type +proper_subset(Interval interval1, Interval interval2) { + typename Interval_traits::Proper_Subset proper_subset; + return proper_subset(interval1, interval2); +} + + +// Set operations, functions returing Interval +template inline +typename Interval_traits::Intersection::result_type +intersection(Interval interval1, Interval interval2) { + typename Interval_traits::Intersection intersection; + return intersection(interval1, interval2); +} + +template inline +typename Interval_traits::Hull::result_type +hull(Interval interval1, Interval interval2) { + typename Interval_traits::Hull hull; + return hull(interval1, interval2); +} + + + + +// This will go intro bigfloat_interval_support.h +//////////////////////////////// BFI Traits + + template class Bigfloat_interval_traits; -template long get_significant_bits(BFI bfi) { + +template inline long get_significant_bits(BFI bfi) { typename Bigfloat_interval_traits::Get_significant_bits get_significant_bits; return get_significant_bits(bfi); } -template long set_precision(BFI bfi,long prec) { +template inline long set_precision(BFI bfi,long prec) { typename Bigfloat_interval_traits::Set_precision set_precision; return set_precision(prec); } -template long get_precision(BFI bfi) { +template inline long get_precision(BFI bfi) { typename Bigfloat_interval_traits::Get_precision get_precision; return get_precision(); } -template - typename Bigfloat_interval_traits::BF upper(const BFI& bfi) { - typename Bigfloat_interval_traits::Upper upper; - return upper(bfi); -} - -template - typename Bigfloat_interval_traits::BF lower(const BFI& bfi) { - typename Bigfloat_interval_traits::Lower lower; - return lower(bfi); -} - -template BFI hull(BFI bfi1, BFI bfi2) { - typename Bigfloat_interval_traits::Hull hull; - return hull(bfi1, bfi2); -} - -template bool in_zero(BFI bfi) { - typename Bigfloat_interval_traits::In_zero in_zero; - return in_zero(bfi); -} - -template bool overlap(BFI bfi1, BFI bfi2) { - typename Bigfloat_interval_traits::Overlap overlap; - return overlap(bfi1, bfi2); -} - -template typename Bigfloat_interval_traits::BF - width(BFI bfi) { - typename Bigfloat_interval_traits::Width width; - return width(bfi); -} - -template bool singleton(BFI bfi) { - typename Bigfloat_interval_traits::Singleton singleton; - return singleton(bfi); -} template class Get_arithmetic_kernel; @@ -107,6 +215,9 @@ convert_to_bfi(const CGAL::Sqrt_extension& x) { } } + + + CGAL_END_NAMESPACE #include diff --git a/Number_types/include/CGAL/leda_interval_support.h b/Number_types/include/CGAL/leda_interval_support.h index cc3f24208fd..7ba642f2559 100644 --- a/Number_types/include/CGAL/leda_interval_support.h +++ b/Number_types/include/CGAL/leda_interval_support.h @@ -28,19 +28,126 @@ CGAL_BEGIN_NAMESPACE template<> -class Bigfloat_interval_traits +class Interval_traits { -public: - typedef leda_bigfloat_interval NT; +public: + typedef Interval_traits Self; + typedef leda_bigfloat_interval Interval; + typedef leda::bigfloat Boundary; + + struct Construct :public Binary_function{ + Interval operator()( const Boundary& l,const Boundary& r) const { + CGAL_precondition( l < r ); + return Interval(l,r); + } + }; + + struct Lower :public Unary_function{ + Boundary operator()( const Interval& a ) const { + return a.lower(); + } + }; + + struct Upper :public Unary_function{ + Boundary operator()( const Interval& a ) const { + return a.upper(); + } + }; + + struct Width :public Unary_function{ + Boundary operator()( const Interval& a ) const { + return ::boost::numeric::width(a); + } + }; + + struct Median :public Unary_function{ + Boundary operator()( const Interval& a ) const { + return ::boost::numeric::median(a); + } + }; + + struct Norm :public Unary_function{ + Boundary operator()( const Interval& a ) const { + return ::boost::numeric::norm(a); + } + }; + + struct Empty :public Unary_function{ + bool operator()( const Interval& a ) const { + return ::boost::numeric::empty(a); + } + }; + + struct Singleton :public Unary_function{ + bool operator()( const Interval& a ) const { + return ::boost::numeric::singleton(a); + } + }; + + struct Zero_in :public Unary_function{ + bool operator()( const Interval& a ) const { + return ::boost::numeric::in_zero(a); + } + }; + + struct In :public Binary_function{ + bool operator()( Boundary x, const Interval& a ) const { + return ::boost::numeric::in(x,a); + } + }; + + struct Equal :public Binary_function{ + bool operator()( const Interval& a, const Interval& b ) const { + return ::boost::numeric::equal(a,b); + } + }; + + struct Overlap :public Binary_function{ + bool operator()( const Interval& a, const Interval& b ) const { + return ::boost::numeric::overlap(a,b); + } + }; + + struct Subset :public Binary_function{ + bool operator()( const Interval& a, const Interval& b ) const { + return ::boost::numeric::subset(a,b); + } + }; + + struct Proper_subset :public Binary_function{ + bool operator()( const Interval& a, const Interval& b ) const { + return ::boost::numeric::proper_subset(a,b); + } + }; + + struct Hull :public Binary_function{ + Interval operator()( const Interval& a, const Interval& b ) const { + return ::boost::numeric::hull(a,b); + } + }; + + struct Intersection :public Binary_function{ + Interval operator()( const Interval& a, const Interval& b ) const { + Interval r = ::boost::numeric::intersect(a,b); + if (::boost::numeric::empty(r)) + throw Exception_intersection_is_empty(); + return r; + } + }; +}; + +template<> +class Bigfloat_interval_traits + :public Interval_traits +{ + +public: + typedef Bigfloat_interval_traits Self; + typedef leda_bigfloat_interval NT; typedef leda::bigfloat BF; - class Get_significant_bits { - public: - // type for the \c AdaptableUnaryFunction concept. - typedef NT argument_type; - // type for the \c AdaptableUnaryFunction concept. - typedef long result_type; + struct Get_significant_bits : public Unary_function{ long operator()( NT x) const { leda::bigfloat lower = x.lower(); @@ -64,124 +171,26 @@ public: } }; - - class Upper { - public: - // type for the \c AdaptableUnaryFunction concept. - typedef NT argument_type; - // type for the \c AdaptableUnaryFunction concept. - typedef BF result_type; - - BF operator() ( NT a ) const { - return a.upper(); - } - }; - - class Lower { - public: - // type for the \c AdaptableUnaryFunction concept. - typedef NT argument_type; - // type for the \c AdaptableUnaryFunction concept. - typedef BF result_type; - - BF operator() ( NT a ) const { - return a.lower(); - } - }; - - class Set_precision { - public: - // type for the \c AdaptableUnaryFunction concept. - typedef long argument_type; - // type for the \c AdaptableUnaryFunction concept. - typedef long result_type; - - long operator() ( long prec ) const { + + struct Set_precision : public Unary_function { + long operator()( long prec ) const { return BF::set_precision(prec); } }; - class Get_precision { - public: + struct Get_precision { // type for the \c AdaptableGenerator concept. typedef long result_type; - - long operator() () const { + long operator()() const { return BF::get_precision(); } }; - class In_zero { - public: - // type for the \c AdaptableUnaryFunction concept. - typedef NT argument_type; - // type for the \c AdaptableUnaryFunction concept. - typedef bool result_type; - - bool operator() ( NT x ) const { - return ::boost::numeric::in_zero(x); - } - }; - - class Overlap { - public: - // type for the \c AdaptableBinaryFunction concept. - typedef NT first_argument_type; - // type for the \c AdaptableBinaryFunction concept. - typedef NT second_argument_type; - // type for the \c AdaptableBinaryFunction concept. - typedef bool result_type; - - bool operator() ( NT x, NT y ) const { - return ::boost::numeric::overlap(x,y); - } - }; - - class Hull { - public: - // type for the \c AdaptableBinaryFunction concept. - typedef NT first_argument_type; - // type for the \c AdaptableBinaryFunction concept. - typedef NT second_argument_type; - // type for the \c AdaptableBinaryFunction concept. - typedef NT result_type; - - NT operator() ( NT x, NT y ) const { - return ::boost::numeric::hull(x,y); - } - }; - - class Singleton { - public: - // type for the \c AdaptableUnaryFunction concept. - typedef NT argument_type; - // type for the \c AdaptableUnaryFunction concept. - typedef bool result_type; - - bool operator() ( NT a ) const { - return ::boost::numeric::singleton(a); - } - }; - - class Width { - public: - // type for the \c AdaptableUnaryFunction concept. - typedef NT argument_type; - // type for the \c AdaptableUnaryFunction concept. - typedef BF result_type; - - BF operator() ( NT a ) const { - return ::boost::numeric::width(a); - } - - }; - - class Convert_to_bfi { - public: + struct Convert_to_bfi { typedef NT result_type; - NT operator() ( const leda::real& x ) { + NT operator()( const leda::real& x ) { long current_prec = ::leda::bigfloat::get_precision(); //x.improve_approximation_to(current_prec); x.guarantee_relative_error(current_prec); @@ -206,7 +215,7 @@ public: } - NT operator() (const ::leda::integer& x) { + NT operator()(const ::leda::integer& x) { long current_prec = ::leda::bigfloat::get_precision(); leda_bigfloat_interval bfi; long length = x.length(); @@ -235,7 +244,7 @@ public: } - NT operator() (const ::leda::rational& x) { + NT operator()(const ::leda::rational& x) { long old_prec = ::leda::bigfloat::get_precision(); ::leda::bigfloat::set_precision(old_prec*2); Bigfloat_interval_traits::Convert_to_bfi convert_to_bfi; @@ -251,10 +260,6 @@ public: }; }; -// left overs? -::leda::bigfloat inline median(const leda_bigfloat_interval& x){ - return ::boost::numeric::median(x); -} ::leda::bigfloat inline relative_error(const leda_bigfloat_interval& x){ if(in_zero(x)){ diff --git a/Number_types/test/Number_types/interval_support.cpp b/Number_types/test/Number_types/interval_support.cpp index 985b6e000ae..e0f96dcb272 100644 --- a/Number_types/test/Number_types/interval_support.cpp +++ b/Number_types/test/Number_types/interval_support.cpp @@ -1,6 +1,3 @@ - - - #include #include #include @@ -13,76 +10,174 @@ #include #endif +template +void generic_test_interval(){ + + typedef typename CGAL::Interval_traits::Self IT; + typedef typename IT::Interval Interval; + typedef typename IT::Boundary Boundary; + + const typename IT::Construct construct = typename IT::Construct(); + const typename IT::Lower lower = typename IT::Lower(); + const typename IT::Upper upper = typename IT::Upper(); + const typename IT::Width width = typename IT::Width(); + const typename IT::Median median = typename IT::Median(); + const typename IT::Norm norm = typename IT::Norm(); -// TODO: separat BFI functors from interval functors. + // const typename IT::Empty empty(); !for CORE + const typename IT::Singleton singleton = typename IT::Singleton(); + const typename IT::Zero_in zero_in = typename IT::Zero_in(); + const typename IT::In in = typename IT::In(); + const typename IT::Equal equal = typename IT::Equal(); + const typename IT::Overlap overlap = typename IT::Overlap(); + const typename IT::Subset subset = typename IT::Subset(); + const typename IT::Proper_subset proper_subset = typename IT::Proper_subset(); + + const typename IT::Intersection intersection = typename IT::Intersection(); + const typename IT::Hull hull = typename IT::Hull(); + + Interval a(construct(Boundary(-7),Boundary(-5))); + Interval b(construct(Boundary(0),Boundary(4))); + Interval c(construct(Boundary(2),Boundary(6))); -template + assert(lower(a) == Boundary(-7)); + assert(upper(a) == Boundary(-5)); + assert(lower(b) == Boundary( 0)); + assert(upper(b) == Boundary( 4)); + assert(lower(c) == Boundary( 2)); + assert(upper(c) == Boundary( 6)); + + assert(width(a) == Boundary( 2)); + assert(median(a) == Boundary(-6)); + assert(norm(a) == Boundary( 7)); + + // assert(!empty(a)); + assert( singleton(Interval(1))); + assert(!singleton(a)); + assert(!singleton(b)); + assert(!singleton(c)); + + assert(!zero_in(Interval(1))); + assert( zero_in(Interval(0))); + assert(!zero_in(a)); + assert( zero_in(b)); + assert(!zero_in(c)); + + assert(!in(Boundary( 3),a)); + assert( in(Boundary(-7),a)); + + + assert( equal(a,a)); + assert( equal(b,b)); + assert( equal(c,c)); + assert(!equal(a,b)); + assert(!equal(a,c)); + + assert(!overlap(a,b)); + assert( overlap(b,c)); + Interval I25 = construct(Boundary(2),Boundary(5)); + assert(overlap(I25, construct(Boundary(6),Boundary(7))) == false); + assert(overlap(I25, construct(Boundary(5),Boundary(6))) == true); + assert(overlap(I25, construct(Boundary(4),Boundary(5))) == true); + assert(overlap(I25, construct(Boundary(3),Boundary(4))) == true); + assert(overlap(I25, construct(Boundary(2),Boundary(3))) == true); + assert(overlap(I25, construct(Boundary(1),Boundary(2))) == true); + assert(overlap(I25, construct(Boundary(0),Boundary(1))) == false); + + assert(!subset(a,b)); + assert( subset(a,a)); + assert( subset(Interval(-6),a)); + + assert(!proper_subset(a,b)); + assert(!proper_subset(a,a)); + assert( proper_subset(Interval(-6),a)); + + // assert( empty(intersection(a,b))); + assert( lower(intersection(b,c)) == Boundary(2)); + assert( upper(intersection(b,c)) == Boundary(4)); + // this part chages in case we allow empty intersection + // which seems to be not possible for CORE::BigFloat as Interval + try{ + try{ + intersection(a,b); + assert(false); // it should not reach this + } + catch(CGAL::Exception_intersection_is_empty){} // it throws the right exception + }catch(...){ + assert(false); // seems to be the wrong exception + } + + // hull + assert(lower(hull(b,c)) == Boundary(0)); + assert(upper(hull(b,c)) == Boundary(6)); + assert(lower(hull(Interval(2),Interval(5))) >= Boundary(1)); + assert(lower(hull(Interval(2),Interval(5))) <= Boundary(2)); + assert(upper(hull(Interval(2),Interval(5))) >= Boundary(5)); + assert(upper(hull(Interval(2),Interval(5))) <= Boundary(6)); + + // singleton + assert(singleton(hull(Interval(2),Interval(2))) == true); + assert(singleton(hull(Interval(2),Interval(3))) == false); + + // width + assert(width(hull(Interval(2),Interval(2))) == Boundary(0)); + assert(width(hull(Interval(2),Interval(3))) == Boundary(1)); +} + +template void generic_test_bigfloat_interval(){ - typedef CGAL::Bigfloat_interval_traits BFIT; - typedef typename BFIT::BF BF; + typedef typename CGAL::Bigfloat_interval_traits::Self BFIT; + typedef typename BFIT::NT Interval; + typedef typename BFIT::BF Boundary; + + const typename BFIT::Set_precision set_precsion = typename BFIT::Set_precision(); + const typename BFIT::Get_precision get_precsion = typename BFIT::Get_precision(); + const typename BFIT::Get_significant_bits get_significant_bits + = typename BFIT::Get_significant_bits(); + //TODO: move this into an new Interval_traits // get_significant_bits - assert(CGAL::get_significant_bits(BFI(3)) == 2); - // upper - assert(CGAL::upper(BFI(3)) == BF(3)); - // lower - assert(CGAL::lower(BFI(3)) == BF(3)); - // TODO: rm BFI() within call - // get/set_precsion - long precision = CGAL::get_precision(BFI()); - assert(CGAL::set_precision(BFI(),15) == precision); - assert(CGAL::set_precision(BFI(),precision) == 15); - - // hull - assert(CGAL::lower(CGAL::hull(BFI(2),BFI(5))) >= BF(1)); - assert(CGAL::lower(CGAL::hull(BFI(2),BFI(5))) <= BF(2)); - assert(CGAL::upper(CGAL::hull(BFI(2),BFI(5))) >= BF(5)); - assert(CGAL::upper(CGAL::hull(BFI(2),BFI(5))) <= BF(6)); + CGAL::set_precision(Interval(),15); + assert(CGAL::get_precision(Interval()) == 15); + assert(CGAL::set_precision(Interval(),23) == 15); + assert(CGAL::set_precision(Interval(),70) == 23); - // in_zero - assert(CGAL::in_zero(CGAL::hull(BFI( 2),BFI(3))) == false); - assert(CGAL::in_zero(CGAL::hull(BFI(-2),BFI(3))) == true); - - // overlap - BFI hull_2_5 = CGAL::hull(BFI(2),BFI(5)); - assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(6),BFI(7))) == false); - assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(5),BFI(6))) == true); - assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(4),BFI(5))) == true); - assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(3),BFI(4))) == true); - assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(2),BFI(3))) == true); - assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(1),BFI(2))) == true); - assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(0),BFI(1))) == false); + //TODO: define what get_significant_bits should do and test is. Better name ? + // just a compile check + CGAL::get_significant_bits(Interval(3)); +} - // singelton - assert(CGAL::singleton(CGAL::hull(BFI(2),BFI(2))) == true); - assert(CGAL::singleton(CGAL::hull(BFI(2),BFI(3))) == false); - // width - assert(CGAL::width(CGAL::hull(BFI(2),BFI(2))) == BF(0)); - assert(CGAL::width(CGAL::hull(BFI(2),BFI(3))) == BF(1)); - typedef typename CGAL::Get_arithmetic_kernel::Arithmetic_kernel AK; +template +void generic_test_convert_to_bfi(){ + typedef typename CGAL::Get_arithmetic_kernel::Arithmetic_kernel AK; typedef typename AK::Integer Integer; typedef typename AK::Rational Rational; typedef typename AK::Field_with_sqrt FWS; - assert(CGAL::convert_to_bfi(Integer(1)) == BFI(1)); - assert(CGAL::convert_to_bfi(Rational(1)) == BFI(1)); - assert(CGAL::convert_to_bfi(FWS(1)) == BFI(1)); + assert(CGAL::convert_to_bfi(Integer(1)) == Interval(1)); + assert(CGAL::convert_to_bfi(Rational(1)) == Interval(1)); + assert(CGAL::convert_to_bfi(FWS(1)) == Interval(1)); } - int main(){ +#ifdef CGAL_USE_LEDA + generic_test_interval(); + generic_test_bigfloat_interval(); + + +#endif + #ifdef CGAL_USE_CORE + generic_test_interval(); generic_test_bigfloat_interval(); #endif -#ifdef CGAL_USE_LEDA - generic_test_bigfloat_interval(); -#endif + }