- rm duplicates of CGAL::lower/uppwer(BF)
- rm include conflicts 
- rm Float_traits (from EXACUS but not ready for CGAL)
- added specs for Get_arithmetic_kernel<BigFloat/BF_interval>
- added test for interval support at its current status
This commit is contained in:
Michael Hemmer 2008-03-05 16:53:13 +00:00
parent ef10ca7e16
commit 68be1cfdbb
10 changed files with 766 additions and 2419 deletions

1
.gitattributes vendored
View File

@ -2921,7 +2921,6 @@ Nef_S2/test/Nef_S2/CMakeLists.txt -text
Number_types/doc_tex/NumberTypeSupport_ref/CORE_BigFloat.tex -text
Number_types/doc_tex/NumberTypeSupport_ref/fundamental_types.tex -text
Number_types/doc_tex/NumberTypeSupport_ref/open.tex -text
Number_types/include/CGAL/Float_traits.h -text
Number_types/include/CGAL/Number_types/core_interval_support.h -text
Number_types/include/CGAL/Sqrt_extension/Algebraic_extension_traits.h -text
Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h -text

View File

@ -33,10 +33,7 @@
#include <CGAL/leda_bigfloat.h>
#include <CGAL/leda_real.h>
// #ifdef CGAL_INTERN_USE_BFI
// #include <CGAL/Algebraic_kernel_d/leda_interval_support.h>
#include <CGAL/leda_interval_support.h>
// #endif //CGAL_INTERN_USE_BFI
#endif // CGAL_USE_LEDA
@ -77,12 +74,9 @@ public:
//! exact root expressions, constructible from integers and rationals
typedef leda_real Field_with_sqrt;
// #ifdef CGAL_INTERN_USE_BFI
// undocumented
typedef leda_bigfloat Bigfloat;
// typedef CGALi::leda_bigfloat_interval Bigfloat_interval;
typedef leda_bigfloat_interval Bigfloat_interval;
// #endif //CGAL_INTERN_USE_BFI
};
#endif // CGAL_USE_LEDA
@ -101,11 +95,9 @@ public:
typedef CORE::BigRat Rational;
//! exact root expressions, constructible from integers and rationals
typedef CORE::Expr Field_with_sqrt;
// #ifdef CGAL_INTERN_USE_BFI
// undocumented
typedef CORE::BigFloat Bigfloat;
typedef CORE::BigFloat Bigfloat_interval;
// #endif //CGAL_INTERN_USE_BFI
};
#endif // CGAL_USE_CORE
@ -164,42 +156,10 @@ typedef LEDA_arithmetic_kernel Arithmetic_kernel;
typedef typename AT::Integer Integer; \
typedef typename AT::Rational Rational; \
typedef typename AT::Field_with_sqrt Field_with_sqrt;
// typedef typename AT::Poly_int1 Poly_int1;
// typedef typename AT::Poly_int2 Poly_int2;
// typedef typename AT::Poly_int3 Poly_int3;
// typedef typename AT::Poly_rat1 Poly_rat1;
// typedef typename AT::Poly_rat2 Poly_rat2;
// typedef typename AT::Poly_rat3 Poly_rat3;
// end #define
template <class NT>
class Lazy_exact_nt;
namespace INTERN_AK{
template <class NT>
struct Lazy_exact_type{
typedef CGAL::Lazy_exact_nt<NT> type;
};
template <>
struct Lazy_exact_type<CGAL::Null_tag>{
typedef CGAL::Null_tag type;
};
} // namespace INTERN_AK
template <class AT>
struct Lazy_exact_arithmetic_kernel{
typedef typename INTERN_AK::Lazy_exact_type<typename AT::Integer>::type Integer;
typedef typename INTERN_AK::Lazy_exact_type<typename AT::Exact_float_number>::type Exact_float_number;
typedef typename INTERN_AK::Lazy_exact_type<typename AT::Rational>::type Rational;
typedef typename INTERN_AK::Lazy_exact_type<typename AT::Field_with_sqrt>::type Field_with_sqrt;
};
// #ifdef CGAL_INTERN_USE_BFI
namespace CGALi {
template< class NT > struct Get_arithmetic_kernel;
#ifdef CGAL_USE_LEDA
@ -216,6 +176,14 @@ template< class NT > struct Get_arithmetic_kernel;
struct Get_arithmetic_kernel<leda::real>{
typedef LEDA_arithmetic_kernel Arithmetic_kernel;
};
template <>
struct Get_arithmetic_kernel<leda::bigfloat>{
typedef LEDA_arithmetic_kernel Arithmetic_kernel;
};
template <>
struct Get_arithmetic_kernel<CGAL::leda_bigfloat_interval>{
typedef LEDA_arithmetic_kernel Arithmetic_kernel;
};
#endif //CGAL_USE_LEDA
@ -233,6 +201,10 @@ template< class NT > struct Get_arithmetic_kernel;
struct Get_arithmetic_kernel<CORE::Expr>{
typedef CORE_arithmetic_kernel Arithmetic_kernel;
};
template <>
struct Get_arithmetic_kernel<CORE::BigFloat>{
typedef CORE_arithmetic_kernel Arithmetic_kernel;
};
#endif //CGAL_USE_CORE
template <class COEFF, class ROOT>
@ -241,10 +213,6 @@ template< class NT > struct Get_arithmetic_kernel;
typedef typename GET::Arithmetic_kernel Arithmetic_kernel;
};
} // namespace CGALi
// #endif //CGAL_INTERN_USE_BFI
CGAL_END_NAMESPACE

View File

@ -17,51 +17,19 @@
//
//
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
//============================================================================
#ifndef CGAL_CORE_BIGFLOAT_H
#define CGAL_CORE_BIGFLOAT_H
#include <CGAL/number_type_basic.h>
#include <CGAL/CORE_coercion_traits.h>
#include <CGAL/Float_traits.h>
#include <CGAL/core_interval_support.h>
CGAL_BEGIN_NAMESPACE
//template<typename BFI> class Bigfloat_interval_traits;
// forward declarations of interval support
// namespace CGALi {
CORE::BigFloat
inline
round(const CORE::BigFloat& x, long rel_prec );
//TODO
// functions: upper and lower are defined twice the time,
// please correct this unaesthetic thing
CORE::BigFloat
inline
upper(CORE::BigFloat x){
CORE::BigFloat result = ::CORE::BigFloat(x.m()+x.err(),0,x.exp());
CGAL_postcondition(result >= x);
return result;
}
CORE::BigFloat
inline
lower(CORE::BigFloat x){
CORE::BigFloat result = ::CORE::BigFloat(x.m()-x.err(),0,x.exp());
CGAL_postcondition(result <= x);
return result;
}
// CORE::BigFloat
// inline
// upper(CORE::BigFloat x);
//
// CORE::BigFloat
// inline
// lower(CORE::BigFloat x);
// } // namespace CGALi
//
// Algebraic structure traits
@ -94,14 +62,9 @@ template <> class Algebraic_structure_traits< CORE::BigFloat >
Type result = tmp1*CORE::BigFloat::exp2(a.exp()*7) + err;
CGAL_postcondition(result >= 0);
//#ifndef NDEBUG
// Type tmp = result * result;
// typedef Bigfloat_interval_traits<CORE::BigFloat> bfi_traits;
//bfi_traits::Upper upper;
//bfi_traits::Lower lower;
// CGAL_postcondition(NiX::lower(tmp) <= NiX::lower(x));
// CGAL_postcondition(NiX::upper(tmp) >= NiX::upper(x));
//#endif
CGAL_postcondition(CGAL::lower(result*result) <= CGAL::lower(x));
CGAL_postcondition(CGAL::upper(result*result) >= CGAL::upper(x));
return result;
}
};
@ -118,7 +81,6 @@ template <> class Algebraic_structure_traits< CORE::BigFloat >
return Type(-CORE::radical( -x, k ) );
}
return Type( CORE::radical( x, k ) );
}
};
@ -217,426 +179,8 @@ template <> class Real_embeddable_traits< CORE::BigFloat >
};
};
//**********************NEW**********************
// Specialization of CGAL::Float_traits_kernel for CORE::BigFloat
template <> class Float_traits_kernel< ::CORE::BigFloat > {
public:
typedef ::CORE::BigFloat FT;
typedef ::CORE::BigInt IT;
typedef ::CGAL::Float_number_tag Float_type;
typedef CGAL::Precision_type Precision_type;
class Get_precision {
public:
typedef CGAL::Precision_type result_type;
CGAL::Precision_type operator()() const {
return CGAL::Precision_type( ::CORE::defRelPrec.toLong());
}
};
class Set_precision {
public:
typedef void result_type;
typedef CGAL::Precision_type first_argument_type;
void operator()( const CGAL::Precision_type& precision ) const {
::CORE::defRelPrec = precision;
::CORE::defBFdivRelPrec = precision;
}
};
class Get_rounding_mode {
public:
typedef CGAL::Rounding_mode result_type;
/*??
CGAL::Rounding_mode operator()() const {
return CGAL::Rounding_mode( CORE::BigFloat::get_rounding_mode() );
}
*/
};
class Set_rounding_mode {
public:
typedef void result_type;
typedef CGAL::Rounding_mode first_argument_type;
/* ??
void operator()( const CGAL::Rounding_mode& rounding_mode ) const {
CORE::BigFloat::set_rounding_mode( (CORE::rounding_modes)rounding_mode );
}
*/
};
};
// Specialization of CGAL::Float_traits for CORE::BigFloat
template <> class Float_traits< ::CORE::BigFloat >
: public Float_traits_base< Float_traits_kernel< ::CORE::BigFloat> > {
private:
/* ??
static Rounding_mode get_rounding_mode() {
return Rounding_mode( CORE::BigFloat::get_rounding_mode() );
};
*/
static Precision_type get_precision() {
return Precision_type( ::CORE::defRelPrec.toLong() );
};
public:
typedef Float_traits_kernel< CORE::BigFloat > FT_kernel;
typedef FT_kernel::FT FT;
typedef FT_kernel::IT IT;
typedef FT_kernel::Float_type Float_type;
class Construct
: public Float_traits_base< FT_kernel >::Construct {
public:
FT operator() ( const IT& m, const IT& e = IT(0) ) {
return FT(m,0,0)*FT::exp2(e.intValue());
}
}; // class Constructor
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 {
FT_kernel::Set_precision set_precision;
FT_kernel::Get_precision get_precision;
long old_precision = get_precision();
set_precision(prec);
return old_precision;
}
};
class Get_precision {
public:
// type for the \c AdaptableGenerator concept.
typedef long result_type;
long operator() () const {
FT_kernel::Get_precision get_precision;
return get_precision();
}
};
/*
class Construct_special_value {
public:
FT operator()( const Special_value& sv ) {
switch( sv ) {
case SV_N_ZERO: return leda::bigfloat::nZero;
case SV_P_ZERO: return leda::bigfloat::pZero;
case SV_N_INF: return leda::bigfloat::nInf;
case SV_P_INF: return leda::bigfloat::pInf;
case SV_NAN: return leda::bigfloat::NaN;
default: return FT(0);
}
}
};
*/
/* ??
class Is_special_value {
public:
bool operator()( const FT& bf ) const {
return leda::isSpecial( bf );
}
};
*/
/* ??
class Get_special_value {
public:
Special_value operator()( const FT& bf ) const {
if( leda::isNaN( bf ) )
return SV_NAN;
else if( leda::isnZero( bf ) )
return SV_N_ZERO;
else if( leda::ispZero( bf ) )
return SV_P_ZERO;
else if( leda::isnInf( bf ) )
return SV_N_INF;
else if( leda::ispInf( bf ) )
return SV_P_INF;
else
return SV_NONE;
}
};
*/
class Is_zero {
public:
bool operator()( const FT& bf ) const {
CGAL_precondition(bf.isExact());
return bf == FT(0);
}
};
/* ??
class Is_inf {
public:
bool operator()( const FT& bf ) const {
return leda::isInf( bf );
}
};
*/
class Get_mantissa
: public Float_traits_base< FT_kernel >::Get_mantissa {
public:
//! type for the \c AdaptableUnaryFunction concept.
typedef IT result_type;
//! type for the \c AdaptableUnaryFunction concept.
typedef FT argument_type;
IT operator()( const FT& a ) const {
return a.m();
}
}; // class GetMantissa
class Get_exponent
: public Float_traits_base< FT_kernel >::Get_exponent {
public:
//! type for the \c AdaptableUnaryFunction concept.
typedef long result_type;
//! type for the \c AdaptableUnaryFunction concept.
typedef FT argument_type;
result_type operator()( const FT& a ) const {
return 14*a.exp(); // The basis is 8092
}
}; // class GetExponent
class Get_mantissa_and_exponent
: public Float_traits_base< FT_kernel >::Get_mantissa_and_exponent {
public:
//! type for the \c AdaptableUnaryFunction concept.
typedef std::pair< IT, long > result_type;
//! type for the \c AdaptableUnaryFunction concept.
typedef FT argument_type;
result_type operator()( const FT& a ) const {
IT m = a.m();
long e = 14*a.exp();
result_type p( m, e );
return p;
}
}; // class GetMantissaAndExponent
/* ??
class Round_relative
: public Float_traits_base< FT_kernel >::Round_relative {
public:
//! type for the \c AdaptableTernaryFunction concept.
typedef FT result_type;
//! type for the \c AdaptableTernaryFunction concept.
typedef FT first_argument_type;
//! type for the \c AdaptableTernaryFunction concept.
typedef CGAL::Precision_type second_argument_type;
//! type for the \c AdaptableTernaryFunction concept.
typedef CGAL::Rounding_mode third_argument_type;
FT operator()( const FT& a,
const CGAL::Precision_type& p = get_precision(),
const CGAL::Rounding_mode& m = get_rounding_mode() ) const {
return leda::round(a,(leda::sz_t)p,(leda::rounding_modes)m ) ;
}
}; // class Round
*/
/* ??
class Round_absolute : public Float_traits_base< FT_kernel >::Round_absolute {
public:
//! type for the \c AdaptableTernaryFunction concept.
typedef FT result_type;
//! type for the \c AdaptableTernaryFunction concept.
typedef FT first_argument_type;
//! type for the \c AdaptableTernaryFunction concept.
typedef IT second_argument_type;
//! type for the \c AdaptableTernaryFunction concept.
typedef CGAL::Rounding_mode third_argument_type;
FT operator()( const FT& a,
const IT& new_exponent,
const CGAL::Rounding_mode& r_mode = get_rounding_mode() ) const {
typedef CGAL::Float_number<IT> FN;
FN fn( a.get_significant(), a.get_exponent() );
fn = fn.round_absolute( new_exponent, r_mode );
return FT( fn.get_mantissa(), fn.get_exponent() );
}
};
*/
// special functors ( only for Big_float )
/* ??
class Add
: public Float_traits_base< FT_kernel >::Add {
public:
typedef FT result_type;
typedef FT first_argument_type;
typedef FT second_argument_type;
typedef CGAL::Rounding_mode third_argument_type;
typedef CGAL::Precision_type fourth_argument_type;
FT operator()( const FT& a, const FT& b,
const Rounding_mode& m = get_rounding_mode(),
const Precision_type& p = get_precision() ) const {
return leda::add(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
}
}; // class Add
class Sub
: public Float_traits_base< FT_kernel >::Sub{
public:
typedef FT result_type;
typedef FT first_argument_type;
typedef FT second_argument_type;
typedef CGAL::Rounding_mode third_argument_type;
typedef CGAL::Precision_type fourth_argument_type;
FT operator()( const FT& a, const FT& b ,
const Rounding_mode& m = get_rounding_mode(),
const Precision_type& p = get_precision() ) const {
return leda::sub(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
}
}; // class Sub
class Mul
: public Float_traits_base< FT_kernel >::Mul {
public:
typedef FT result_type;
typedef FT first_argument_type;
typedef FT second_argument_type;
typedef CGAL::Rounding_mode third_argument_type;
typedef CGAL::Precision_type fourth_argument_type;
FT operator()( const FT& a, const FT& b ,
const Rounding_mode& m = get_rounding_mode(),
const Precision_type& p = get_precision() ) const {
return leda::mul(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
}
}; // class Mul
class Div
: public Float_traits_base< FT_kernel >::Div{
public:
typedef FT result_type;
typedef FT first_argument_type;
typedef FT second_argument_type;
typedef CGAL::Rounding_mode third_argument_type;
typedef CGAL::Precision_type fourth_argument_type;
FT operator()( const FT& a, const FT& b ,
const Rounding_mode& m = get_rounding_mode(),
const Precision_type& p = get_precision() ) const {
return leda::div(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
}
}; // class Div
class Sqrt
: public Float_traits_base< FT_kernel >::Sqrt{
public:
typedef FT result_type;
typedef FT first_argument_type;
typedef CGAL::Rounding_mode second_argument_type;
typedef CGAL::Precision_type third_argument_type;
FT operator()( const FT& bf,
const Rounding_mode& r_mode = get_rounding_mode(),
const Precision_type& prec = get_precision() ) const {
return leda::sqrt( bf, (leda::sz_t)prec, (leda::rounding_modes)r_mode);
}
}; // class Sqrt
*/
class Mul_by_pow_of_2
: public Float_traits_base< FT_kernel >::Mul_by_pow_of_2{
public:
//! type for the \c AdaptableBinaryFunction concept.
typedef FT result_type;
//! type for the \c AdaptableBinaryFunction concept.
typedef FT first_argument_type;
//! type for the \c AdaptableBinaryFunction concept.
typedef IT second_argument_type;
FT operator()( const FT& a, const IT& e ) const {
return a*FT::exp2(e.intValue());
}
}; // class Mul_by_pow_of_2
class Div_by_pow_of_2
: public Float_traits_base< FT_kernel >::Div_by_pow_of_2{
public:
//! type for the \c AdaptableBinaryFunction concept.
typedef FT result_type;
//! type for the \c AdaptableBinaryFunction concept.
typedef FT first_argument_type;
//! type for the \c AdaptableBinaryFunction concept.
typedef IT second_argument_type;
FT operator()( const FT& a, const IT& e ) const {
return a*FT::exp2(-e.intValue());
}
}; // class Div_by_pow_of_2
class Floor {
public:
typedef IT result_type;
typedef FT argument_type;
IT operator()( const FT& fn ) const {
IT fl = fn.BigIntValue();
if(fn.sign() < 0 && fn.cmp(fl)!=0) {
fl--;
}
return fl;
}
};
class Ceil {
public:
typedef IT result_type;
typedef FT argument_type;
IT operator()( const FT& fn ) const {
IT fl = fn.BigIntValue();
if(fn.sign() >0 && fn.cmp(fl)!=0) {
fl++;
}
return fl;
}
};
};
//**********************NEW**********************
CGAL_END_NAMESPACE
// #include <CGAL/Number_types/core_interval_support.h>
#include <CGAL/core_interval_support.h>
//since types are included by CORE_coercion_traits.h:
#include <CGAL/CORE_Expr.h>
#include <CGAL/CORE_BigInt.h>

View File

@ -1,477 +0,0 @@
// 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: 4515 rschindl$
//
//
// Author(s) : Ralf Schindlbeck <rschindl@mpi-inf.mpg.de>
//
// ============================================================================
// TODO: The comments are all original EXACUS comments and aren't adapted. So
// they may be wrong now.
/*! \file CGAL/Float_traits.h
\brief Defines class CGAL::Float_traits.
Provides dependent types and function objects for all the functions
beyond operators of the different float types.
*/
#ifndef CGAL_FLOAT_TRAITS_H
#define CGAL_FLOAT_TRAITS_H
#include <CGAL/basic.h>
// #include <NiX/enums.h>
#include <stack>
// namespace NiX {
CGAL_BEGIN_NAMESPACE
//compensation for the #include <NiX/enums.h>
//Enumerator indicating the desired rounding mode for an operation
//and the global rounding mode, if exists.
enum Rounding_mode {
TO_NEAREST = 0, //!< round to nearest number
TO_ZERO = 1, //!< round towards zero
TO_P_INF = 2, //!< round up (towards positive infinity)
TO_N_INF = 3, //!< round down (towards negative infinity)
TO_INF = 4 //!< round away from zero
};
//Enumerator indicating a special value represented by a floating point value.
enum Special_value {
SV_NONE = 0, //!< indicates non-specialness of a value
SV_N_ZERO = -1, //!< zero with a negative sign
SV_P_ZERO = 1, //!< zero with a positive sign
SV_N_INF = -2, //!< negative infinity
SV_P_INF = 2, //!< positive infinity
SV_NAN = 3 //!< "Not Any Number (not even infinity)": error indicator
};
typedef long Precision_type;
// The tags for Float type corresponding to the float type concepts
// ================================================================
//! corresponds to the \c FloatNumber concept.
struct Float_number_tag {};
//! corresponds to the \c ExactFloatNumber concept.
struct Exact_float_number_tag {};
//! corresponds to the \c FixedPointNumber concept.
struct Fixed_point_number_tag {};
// The float traits kernel class
// =========================================================================
// This class provides implementation dependent access to the precision and
// rounding mode settings along with information about the float type, the
// corresponding integer type and the float concept.
template< class FT_ >
class Float_traits_kernel {
public:
typedef FT_ FT;
typedef CGAL::Null_tag IT;
typedef CGAL::Null_tag Float_type;
typedef CGAL::Null_tag Precision_type;
typedef CGAL::Null_functor Get_precision;
typedef CGAL::Null_functor Set_precision;
typedef CGAL::Null_functor Get_rounding_mode;
typedef CGAL::Null_functor Set_rounding_mode;
};
// The float traits template
// =========================
// The general float traits is only declared and not defined.
// That leads to an immediate error message at the first attempt to use
// a non-supported float type.
// Documentation for the concept of being a valid specialization
// of Float_traits is provided in NumeriX/manual/AlgebraicKernel/AK_Float.dox
template< class FT_ >
class Float_traits;
// The float traits base class
// =========================================================================
//! The template specialization that can be used for types that are not any
//! of the float type concepts. All functors are set to \c CGAL::Null_functor.
//! See also \link NiX_Float_traits_functors concept Float_traits \endlink .
//! \ingroup NiX_Float_traits_bases
//
template< class FT_kernel_ >
class Float_traits_base {
private:
typedef FT_kernel_ FT_kernel;
public:
typedef CGAL::Null_functor Construct;
typedef CGAL::Null_functor Get_mantissa;
typedef CGAL::Null_functor Get_exponent;
typedef CGAL::Null_functor Get_mantissa_and_exponent;
typedef CGAL::Null_functor Round_relative;
typedef CGAL::Null_functor Round_absolute;
typedef CGAL::Null_functor Add;
typedef CGAL::Null_functor Sub;
typedef CGAL::Null_functor Mul;
typedef CGAL::Null_functor Div;
typedef CGAL::Null_functor Sqrt;
typedef CGAL::Null_functor Mul_by_pow_of_2;
typedef CGAL::Null_functor Div_by_pow_of_2;
typedef CGAL::Null_functor Floor;
typedef CGAL::Null_functor Ceil;
typedef CGAL::Null_functor Construct_special_value;
typedef CGAL::Null_functor Is_special_value;
typedef CGAL::Null_functor Get_special_value;
typedef CGAL::Null_functor Is_zero;
typedef CGAL::Null_functor Is_inf;
typedef CGAL::Null_functor Set_exponent;
class Rounding_mode_controller {
public:
inline Rounding_mode_controller( const Rounding_mode& mode ) {
// store current rounding mode
rounding_modes.push( get_rounding_mode() );
#ifndef NDEBUG
// store scope id
scope_id = rounding_modes.size();
#endif
set_rounding_mode( mode );
};
inline ~Rounding_mode_controller() {
// restore old rounding mode
set_rounding_mode( rounding_modes.top() );
rounding_modes.pop();
};
inline void set_rounding_mode(
const Rounding_mode& mode ) const {
#ifndef NDEBUG
if( scope_id != rounding_modes.size() )
CGAL_error_msg( "Rounding mode controller out of scope" );
#endif
typename FT_kernel::Set_rounding_mode set_mode;
set_mode( mode );
};
inline static Rounding_mode get_rounding_mode() {
typename FT_kernel::Get_rounding_mode get_mode;
return get_mode();
};
private:
static std::stack<Rounding_mode> rounding_modes;
#ifndef NDEBUG
unsigned scope_id;
#endif
};
class Precision_controller {
public:
typedef typename FT_kernel::Precision_type PT;
Precision_controller( const PT& precision ) {
// store current precision
precisions.push( get_precision() );
#ifndef NDEBUG
// store scope id
scope_id = precisions.size();
#endif
set_precision( precision );
};
inline ~Precision_controller() {
// restore previous precision
set_precision( precisions.top() );
precisions.pop();
};
inline void set_precision( const PT& precision ) const {
#ifndef NDEBUG
if( scope_id != precisions.size() )
CGAL_error_msg( "Precision controller out of scope" );
#endif
typename FT_kernel::Set_precision set_prec;
set_prec( precision );
};
inline static PT get_precision() {
typename FT_kernel::Get_precision get_prec;
return get_prec();
};
private:
static std::stack<PT> precisions;
#ifndef NDEBUG
unsigned scope_id;
#endif
};
};
template< class FT_kernel >
std::stack< typename FT_kernel::Precision_type >
CGAL::Float_traits_base< FT_kernel >::Precision_controller::precisions =
std::stack< typename FT_kernel::Precision_type >();
template< class FT_kernel >
std::stack<Rounding_mode>
CGAL::Float_traits_base< FT_kernel >::Rounding_mode_controller::rounding_modes =
std::stack<Rounding_mode>();
// namespace Intern {
namespace CGALi {
// IT_float_traits provide functionality for arbitary integer values
// such as Division (without and with rounding) and Shifting
// which are not explizit definied for integer value, but needed
// for the float_type
template< class IT_ >
class IT_float_traits {
public:
typedef IT_ IT;
//! returns the length (in bits) of an integer value $v$.
typedef CGAL::Null_functor Length;
//! calculates for an integer value $e$, $2^e$
class Pow_2 {
public:
IT operator() ( const IT& e ) const {
if( e<0 ) return 0;
if( e==0 ) return 1;
IT a = 1;
IT p = 2;
IT n = e;
while( n > 0 ) {
if( n%2 == 1 )
a = p*a;
n = n/2;
p = p*p;
}
return a;
}
};
class Ilog_2 {
public:
IT operator()( const IT& a) const {
IT log=0;
IT pow = 1;
while(pow < a)
{
pow = pow * 2;
log = log + 1;
}
return log;
}
};
class Floor_Ilog_2 {
public:
IT operator()( const IT& a) const {
IT log=0;
IT pow = 1;
IT floor_log;
while(pow <= a)
{
pow = pow * 2;
floor_log = log;
log = log + 1;
}
return floor_log;
}
};
//! count the number of zeros at the end in the binary reprasentation of an integer
class Zeros {
public:
IT operator() ( const IT& value ) const {
if ( value == IT(0) ) return 0;
IT zeros = -1;
IT d = value;
IT f = 1;
do {
zeros++;
d /= IT(2);
f *= IT(2);
} while ( d * f == value ) ;
return zeros;
}
};
//! Division of two integer values $a/b$
//! return an integer div which satisfy the equation
//! a = div * b + r (r < b )
//! Division by zero is not definied.
class Integer_Div {
public:
void help ( const IT&a, const IT& b, IT& sol, IT& sum ) {
if ( a<b ){
sol = 0;
sum = 0;
return;
}
if ( a==b ) {
sol = 1;
sum = b;
return ;
}
sol = IT( 1 );
sum = b;
while ( (sum+sum) <= a ) {
sum += sum;
sol += sol;
}
return ;
}
IT operator() ( const IT& a, const IT& b ) {
typename CGAL::Real_embeddable_traits<IT>::Abs abs;
CGAL_precondition( b != 0 );
IT sol = 0; // solution of division
IT sum_rem = abs( a );
IT abs_b = abs( b );
do {
IT tmpsol, tmpsum;
help( sum_rem, abs_b, tmpsol, tmpsum );
sol += tmpsol;
sum_rem -= tmpsum;
} while ( sum_rem >= abs_b );
// false => terminate
if ( ( a < 0 && b > 0 )
|| ( a > 0 && b < 0 ) ) {
sol = (IT)0 - sol;
}
return sol;
}
}; // class Integer_Div
class Mod {
public:
IT operator() ( const IT& a, const IT&b ) {
typename IT_float_traits<IT>::Integer_Div int_div;
IT divisor = int_div( a, b );
return (a-(b*divisor));
}
};
//! shifts an integer value by shift to the left
//! (multiplication by $2^shift$)
class Shift_left_by {
public:
IT operator() ( const IT& value, const IT& shift ) const {
typename IT_float_traits<IT>::Pow_2 pow_2;
return value* pow_2( shift );
}
}; // class Shift_left_by
//! shifts an integer value by shift to the right
//! (division by $2^shift$)
class Shift_right_by {
public:
IT operator() ( const IT& value, const IT& shift ) const {
typename IT_float_traits<IT>::Pow_2 pow_2;
typename IT_float_traits<IT>::Integer_Div Integer_div;
return Integer_div( value, pow_2( shift ) );
}
}; // class Shift_right_by
}; // class IT_float_traits
} // namespace CGALi
//! For the exact binary number types of EXACUS,
//! this base class provides implementations of
//! \c NiX::NT_traits::Floor_log2_abs and \c NiX::NT_traits::Ceil_log2_abs
//! based on \c NiX::FloatTraits::Get_mantissa and
//! \c NiX::FloatTraits::Get_exponent together with the respective
//! \c NiX::NT_traits functor for the mantissa.
//! \ingroup NiX_NT_traits_bases
template <class NT>
class NT_traits_log2_float_traits_base {
//TODO
//porting Floor_log2_abs and Ceil_log2_abs from EXACUS2CGAL
public:
//! <tt>NiX::NT_traits::Floor_log2_abs()(NT x)</tt> implemented as
//! <tt>NiX::NT_traits<Get_mantissa::result_type>::Floor_log2_abs()(Get_mantissa()(x)) + Get_exponent()(x)</tt>
// class Floor_log2_abs {
// public:
// //! type for the \c AdaptableUnaryFunction concept.
// typedef typename Float_traits<NT>::Get_exponent::result_type
// result_type;
// //! type for the \c AdaptableUnaryFunction concept.
// typedef NT argument_type;
// //! the function call.
// result_type operator() (argument_type x) {
// typedef typename Float_traits<NT>::Get_mantissa Get_mantissa;
// typedef typename Float_traits<NT>::Get_exponent Get_exponent;
// typename NT_traits<typename Get_mantissa::result_type>
// ::Floor_log2_abs log;
// return log(Get_mantissa()(x)) + Get_exponent()(x);
// }
// };
//! <tt>NiX::NT_traits::Ceil_log2_abs()(NT x)</tt> implemented as
//! <tt>NiX::NT_traits<Get_mantissa::result_type>::Ceil_log2_abs()(Get_mantissa()(x)) + Get_exponent()(x)</tt>
// class Ceil_log2_abs {
// public:
// //! type for the \c AdaptableUnaryFunction concept.
// typedef typename Float_traits<NT>::Get_exponent::result_type
// result_type;
// //! type for the \c AdaptableUnaryFunction concept.
// typedef NT argument_type;
// //! the function call.
// result_type operator() (argument_type x) {
// typedef typename Float_traits<NT>::Get_mantissa Get_mantissa;
// typedef typename Float_traits<NT>::Get_exponent Get_exponent;
// typename NT_traits<typename Get_mantissa::result_type>
// ::Ceil_log2_abs log;
// return log(Get_mantissa()(x)) + Get_exponent()(x);
// }
// };
};
// } // namespace NiX
CGAL_END_NAMESPACE
#endif // CGAL_FT_TRAITS_H
// EOF

View File

@ -4,65 +4,53 @@
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL:$
// $Id: 4515 rschindl$
// $Id:$
//
//
// Author(s) : Ralf Schindlbeck <rschindl@mpi-inf.mpg.de>
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
//
// ============================================================================
// TODO: The comments are all original EXACUS comments and aren't adapted. So
// they may be wrong now.
/*! \file CGAL/core_interval_support.h
This is experimental
use CORE::BigFloat as interval type.
*/
// TODO:
// - mv general functors in a new Interval_traits
// - mv function 'round' to Interval_traits
#ifndef CGAL_CORE_INTERVAL_SUPPORT_H
#define CGAL_CORE_INTERVAL_SUPPORT_H
#include <CGAL/basic.h>
#include <CGAL/interval_support.h>
#ifndef CGAL_USE_CORE
#warning This header file needs CORE installed in order to work properly.
#else // CGAL_USE_CORE
//#include <NiX/CORE/BigFloat.h>
//#include <NiX/CORE/Expr.h>
//#include <NiX/CORE/BigInt.h>
//#include <NiX/CORE/BigRat.h>
#include <CGAL/CORE/BigFloat.h>
// namespace NiX{
CGAL_BEGIN_NAMESPACE
template<typename BFI> 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;
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;
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();
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 ;
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{
@ -79,211 +67,218 @@ template<typename BFI> long get_significant_bits(BFI bfi);
return xr;
}
template<typename BFI> class Bigfloat_interval_traits;
template<> class Bigfloat_interval_traits<CORE::BigFloat>
{
public:
typedef CORE::BigFloat NT;
typedef CORE::BigFloat BF;
{
public:
typedef CORE::BigFloat NT;
typedef CORE::BigFloat BF;
typedef Bigfloat_interval_traits<NT> Self;
typedef Bigfloat_interval_traits<NT> 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;
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 {
//std::cout << ":::::::::::::::::::: "<< std::endl;
if(x.err() == 0 ) {
//std::cout << "Exact: \n" << x.m() << std::endl;
return ::CORE::bitLength(x.m());
}
else {
//std::cout << "With error:\n" << x.m() << std::endl << x.err() << std::endl;
//std::cout << "bitlength m: " << ::CORE::bitLength(x.m()) << "\nbitlength e: " << ::CORE::bitLength(x.err()) << std::endl;
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()( 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;
return result;
}
};
long operator() ( long prec ) const {
long result = ::CORE::defRelPrec.toLong();
::CORE::defRelPrec = prec;
::CORE::defBFdivRelPrec = prec;
return result;
}
};
class Get_precision {
public:
// type for the \c AdaptableGenerator concept.
typedef long result_type;
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;
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 {
CORE::BigFloat result = ::CORE::BigFloat(x.m()+x.err(),0,x.exp());
CGAL_postcondition(result >= x);
return result;
}
};
BF operator() ( NT 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;
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 x ) const {
CORE::BigFloat result = ::CORE::BigFloat(x.m()-x.err(),0,x.exp());
CGAL_postcondition(result <= x);
return result;
}
};
BF operator() ( NT x ) const {
CORE::BigFloat result = ::CORE::BigFloat(x.m()-x.err(),0,x.exp());
CGAL_postcondition(result <= x);
return result;
}
};
class In_zero {
public:
// type for the \c AdaptableUnaryFunction concept.
typedef NT argument_type;
// type for the \c AdaptableUnaryFunction concept.
typedef bool result_type;
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 x.isZeroIn();
}
};
bool operator() ( NT 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;
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 {
Self::In_zero in_zero;
bool result = in_zero(x-y);
return result;
}
};
bool operator() ( NT x, NT y ) const {
Self::In_zero in_zero;
bool result = in_zero(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;
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 {
CORE::BigFloat result;
NT operator() ( NT x, NT y ) const {
#if 0
// this is not possible since CORE::centerize has a bug.
NT 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())) {
//rep(x) == rep(y)
return x;
}
Self::Lower lower_functor;
Self::Upper upper_functor;
CORE::BigFloat lower = std::min(lower_functor(x),
lower_functor(y));
CORE::BigFloat upper = std::max(upper_functor(x),
upper_functor(y));
CORE::BigFloat mid = (lower + upper)/2;
CORE::BigFloat err = CGAL::round((upper - lower)/2,0);
err = CORE::BigFloat(0,err.m().longValue()+err.err(),err.exp());
result = mid + err;
// Unfortunately, CORE::centerize(x,y) has bugs.
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 mid = (lower + upper)/2;
CGAL_postcondition(lower_functor(result) <=
std::min(lower_functor(x),
lower_functor(y)));
CGAL_postcondition(upper_functor(result) >=
std::max(upper_functor(x),
upper_functor(y)));
return result ;
}
};
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 x ) const {
return (x.err() == 0);
}
};
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 x ) const {
unsigned long err = 2*x.err();
return BF(CORE::BigInt(err),0,x.exp());
}
};
class Convert_to_bfi {
public:
typedef NT result_type;
// Now we have to compute the error. The problem is that .err() is just a long
CORE::BigFloat err = (upper - lower)/CORE::BigFloat(2);
//std::cout << "lower " << lower << std::endl;
//std::cout << "upper " << upper << std::endl;
//std::cout << "mid " << mid << std::endl;
//std::cout << "err I " << err << std::endl;
// shift such that err.m()+err.err() fits into long
int digits_long = std::numeric_limits<long>::digits;
if(::CORE::bitLength(err.m()) >= digits_long){
long shift = ::CORE::bitLength(err.m()) - digits_long + 1 ;
//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{
err = CORE::BigFloat(0,err.m().longValue()+err.err(),err.exp());
}
result = mid + err;
NT operator() (const ::CORE::Expr& x){
return round(CORE::BigFloat(x));
}
#endif
CGAL_postcondition(
CGAL::lower(result)
<= std::min(CGAL::lower(x), CGAL::lower(y)));
CGAL_postcondition(
CGAL::upper(result)
>= std::max(CGAL::upper(x), CGAL::upper(y)));
NT operator() (const ::CORE::BigInt& x){
return round(CORE::BigFloat(x));
}
return result ;
}
};
class Singleton {
public:
// type for the \c AdaptableUnaryFunction concept.
typedef NT argument_type;
// type for the \c AdaptableUnaryFunction concept.
typedef bool result_type;
NT operator() (const ::CORE::BigRat& x){
return round(CORE::BigFloat(x));
}
};
bool operator() ( NT x ) const {
return (x.err() == 0);
}
};
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 x ) const {
unsigned long err = 2*x.err();
return BF(CORE::BigInt(err),0,x.exp());
}
};
};
class Convert_to_bfi {
public:
typedef NT result_type;
NT operator() (const ::CORE::Expr& x){
return round(CORE::BigFloat(x));
}
NT operator() (const ::CORE::BigInt& x){
return round(CORE::BigFloat(x));
}
NT operator() (const ::CORE::BigRat& x){
return round(CORE::BigFloat(x));
}
};
};
// } // namespace NiX
CGAL_END_NAMESPACE
#endif // CGAL_USE_CORE

View File

@ -3,17 +3,14 @@
// 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: 4515 rschindl$
// $URL$
// $Id$
//
//
// Author(s) : Ralf Schindlbeck <rschindl@mpi-inf.mpg.de>
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
//
// ============================================================================
// TODO: The comments are all original EXACUS comments and aren't adapted. So
// they may be wrong now.
/*! \file CGAL/interval_support.h
This is experimental
@ -23,69 +20,35 @@
#define CGAL_INTERVAL_SUPPORT_H
#include <CGAL/basic.h>
#include <CGAL/Arithmetic_kernel.h>
// #include <NiX/Float_traits.h>
#include <CGAL/Float_traits.h>
///////// covnersion tools:
// namespace NiX{
CGAL_BEGIN_NAMESPACE
template <class NT> class Get_arithmetic_traits;
template <typename A,typename B,typename C,typename D,typename E>
class Algebraic_real;
// } // namespace NiX
// namespace CGAL {
template <typename A,typename B> class Sqrt_extension;
// } // namespace CGAL
// namespace NiX {
// Bigfloat_interval_functions
template<typename BigfloatInterval> class Bigfloat_interval_traits;
template<typename BFI> long get_significant_bits(BFI bfi) {
typename Bigfloat_interval_traits<BFI>::Get_significant_bits
get_significant_bits;
get_significant_bits;
return get_significant_bits(bfi);
}
/*
template<typename BFI> long set_precision(BFI bfi,long prec) {
typename Float_traits<typename Bigfloat_interval_traits<BFI>::BF>
::Set_precision set_precision;
template<typename BFI> long set_precision(BFI bfi,long prec) {
typename Bigfloat_interval_traits<BFI>::Set_precision set_precision;
return set_precision(prec);
}
template<typename BFI> long get_precision(BFI bfi) {
typename Float_traits<typename Bigfloat_interval_traits<BFI>::BF>
::Get_precision get_precision;
typename Bigfloat_interval_traits<BFI>::Get_precision get_precision;
return get_precision();
}
*/
// ONLY FOR TESTING THIS IS THE WRONG FILE!!!
template<typename BF> long set_precision(BF bfi,long prec) {
typename Float_traits<BF>::Set_precision set_precision;
return set_precision(prec);
}
template<typename BF> long get_precision(BF bfi) {
typename Float_traits<BF>::Get_precision get_precision;
return get_precision();
}
template<typename BFI>
typename Bigfloat_interval_traits<BFI>::BF upper(BFI bfi) {
typename Bigfloat_interval_traits<BFI>::BF upper(const BFI& bfi) {
typename Bigfloat_interval_traits<BFI>::Upper upper;
return upper(bfi);
}
template<typename BFI>
typename Bigfloat_interval_traits<BFI>::BF lower(BFI bfi) {
typename Bigfloat_interval_traits<BFI>::BF lower(const BFI& bfi) {
typename Bigfloat_interval_traits<BFI>::Lower lower;
return lower(bfi);
}
@ -107,7 +70,6 @@ template<typename BFI> bool overlap(BFI bfi1, BFI bfi2) {
template<typename BFI> typename Bigfloat_interval_traits<BFI>::BF
width(BFI bfi) {
typename Bigfloat_interval_traits<BFI>::Width width;
return width(bfi);
}
@ -117,226 +79,23 @@ template<typename BFI> bool singleton(BFI bfi) {
return singleton(bfi);
}
template<typename NT> typename CGALi::Get_arithmetic_kernel<NT>::Bigfloat_interval
convert_to_bfi(NT x) {
typedef typename
CGALi::Get_arithmetic_kernel<NT>::Bigfloat_interval BFI;
typename Bigfloat_interval_traits<BFI>::CGALi::Get_arithmetic_kernel
get_arithmetic_traits;
return get_arithmetic_traits(x);
}
#if 0
//TODO
//porting Specialisation for double-intervals from EXACUS2CGAL
// (Parital) Specialisation for double-intervals
#include <NiX/Interval.h>
template<>
class Bigfloat_interval_traits<Interval>
{
public:
typedef Interval NT;
typedef double 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;
long operator()( NT x) const {}
};
*/
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 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:
typedef NT result_type;
template<typename NTX>
NT operator() ( NTX x) {
return to_interval( x );
}
};
};
#endif
#if 0
template <class COEFF, class HP >
leda_bigfloat_interval
inline
convert_to_bfi(const Algebraic_real< COEFF, ::leda::real, ::leda::rational, HP >& x) {
//std::cout << "convert_to_bfi(const Algebraic_real<COEFF, FWS, RAT, HP >& x)"<<std::endl;
typedef ::leda::real FWS;
typedef ::leda::rational RAT;
typedef Algebraic_real< COEFF, FWS, RAT, HP > ALG;
// if zero done
if(NiX::sign(x) == CGAL::ZERO)
return (leda_bigfloat_interval(0));
CGAL_postcondition(NiX::sign(x.low()) == NiX::sign(x.high()));
typedef ::leda::bigfloat BF;
long final_prec = BF::set_precision(BF::get_precision()+4);
::leda::bigfloat rerror(2,-final_prec);
leda_bigfloat_interval bfi(convert_to_bfi(x.low()).lower(), convert_to_bfi(x.high()).upper());
//while( NiX::width(bfi) >= rerror){
//while( NiX::width(bfi) >= NiX::median(NiX::abs(bfi))*rerror){
//std::cout << "rel error: "<< (NiX::width(bfi) / NiX::abs(bfi)).upper() <<std::endl;
while( (NiX::width(bfi) / NiX::abs(bfi)).upper() > rerror ){
//std::cout <<" diff " << NiX::width(bfi) - NiX::abs(bfi).upper()*rerror << std::endl;
x.refine();
bfi = leda_bigfloat_interval(convert_to_bfi(x.low()).lower(), convert_to_bfi(x.high()).upper());
//std::cout <<"bfi: "<< bfi << std::endl;
//std::cout << "final_prec: "<< final_prec << std::endl;
//std::cout << "rerror : "<< rerror << std::endl;
//std::cout << "rel error: "<< (NiX::width(bfi) / NiX::abs(bfi)).upper() <<std::endl;
}
//std::cout << "convert_to_bfi(const Algebraic_real<COEFF, FWS, RAT, HP >& x) end"<<std::endl;
BF::set_precision(final_prec);
#ifndef NDEBUG
::leda::rational lower_num(bfi.lower().get_significant());
::leda::rational lower_denom(NiX::ipower(RAT(2),NiX::abs(bfi.lower().get_exponent().to_long())));
::leda::rational lower;
if(bfi.lower().get_exponent().to_long() < 0 )
lower = lower_num / lower_denom ;
else
lower = lower_num * lower_denom;
CGAL_postcondition( x.compare(lower) == CGAL::LARGER );
::leda::rational upper_num(bfi.upper().get_significant());
::leda::rational upper_denom(NiX::ipower(RAT(2),NiX::abs(bfi.upper().get_exponent().to_long())));
::leda::rational upper;
if(bfi.upper().get_exponent().to_long() < 0 )
upper = upper_num / upper_denom ;
else
upper = upper_num * upper_denom;
CGAL_postcondition( x.compare(upper) == CGAL::SMALLER );
#endif
return bfi;
}
#endif
template <class NTX> class Get_arithmetic_kernel;
template <class NTX>
typename CGALi::Get_arithmetic_kernel<NTX>::Arithmetic_kernel::Bigfloat_interval
typename Get_arithmetic_kernel<NTX>::Arithmetic_kernel::Bigfloat_interval
convert_to_bfi(const NTX& x) {
typedef typename CGALi::Get_arithmetic_kernel<NTX>::Arithmetic_kernel AT;
typedef typename Get_arithmetic_kernel<NTX>::Arithmetic_kernel AT;
typedef typename AT::Bigfloat_interval BFI;
typename Bigfloat_interval_traits<BFI>::Convert_to_bfi convert_to_bfi;
return convert_to_bfi(x);
}
// TODO: move this to sqrt_extension ?
template <typename A,typename B> class Sqrt_extension;
template <typename NT, typename ROOT>
typename CGALi::Get_arithmetic_kernel<NT>::Arithmetic_kernel::Bigfloat_interval
typename Get_arithmetic_kernel<NT>::Arithmetic_kernel::Bigfloat_interval
convert_to_bfi(const CGAL::Sqrt_extension<NT,ROOT>& x) {
typedef typename CGALi::Get_arithmetic_kernel<NT>::Arithmetic_kernel AT;
typedef typename Get_arithmetic_kernel<NT>::Arithmetic_kernel AT;
typedef typename AT::Bigfloat_interval BFI;
if(x.is_extended()){
BFI a0(convert_to_bfi(x.a0()));
@ -348,33 +107,8 @@ convert_to_bfi(const CGAL::Sqrt_extension<NT,ROOT>& x) {
}
}
template <class COEFF, class FWS, class RAT, class T1, class T2>
typename CGALi::Get_arithmetic_kernel<COEFF>::Arithmetic_kernel::Bigfloat_interval
inline
convert_to_bfi(const Algebraic_real< COEFF, FWS, RAT,T1,T2>& x) {
typedef typename CGALi::Get_arithmetic_kernel<COEFF>::Arithmetic_kernel AT;
typedef typename AT::Bigfloat_interval BFI;
typedef typename AT::Bigfloat BF;
BFI result = x.convert_to_bfi();
#ifndef NDEBUG
CGAL::set_precision(BF(),CGAL::get_precision(BF())*2);
CGAL_postcondition(CGAL::lower(result) <= CGAL::lower(CGAL::convert_to_bfi(x.low() )));
CGAL_postcondition(CGAL::upper(result) >= CGAL::upper(CGAL::convert_to_bfi(x.high())));
CGAL::set_precision(BF(),CGAL::get_precision(BF())/2);
#endif
return result;
};
// } // namespace NiX
CGAL_END_NAMESPACE
#ifdef CGAL_USE_LEDA
#include <CGAL/leda_interval_support.h>
#endif // CGAL_USE_LEDA
#ifdef CGAL_USE_CORE
#include <CGAL/core_interval_support.h>
#endif // CGAL_USE_CORE
#include <CGAL/Arithmetic_kernel.h>
#endif // CGAL_INTERVAL_SUPPORT_H

View File

@ -1,3 +1,4 @@
// Copyright (c) 1999,2007 Utrecht University (The Netherlands),
// ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
// INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
@ -24,17 +25,14 @@
#ifndef CGAL_LEDA_BIGFLOAT_H
#define CGAL_LEDA_BIGFLOAT_H
#include <CGAL/number_type_basic.h>
#include <CGAL/basic.h>
#ifdef CGAL_USE_LEDA
#include <utility>
#include <CGAL/leda_coercion_traits.h>
#include <CGAL/Interval_nt.h>
#include <CGAL/LEDA_basic.h>
#if CGAL_LEDA_VERSION < 500
#include <LEDA/bigfloat.h>
@ -42,8 +40,6 @@
#include <LEDA/numbers/bigfloat.h>
#endif
#include <CGAL/Float_traits.h>
CGAL_BEGIN_NAMESPACE
template <> class Algebraic_structure_traits< leda_bigfloat >
@ -147,392 +143,6 @@ class Is_valid< leda_bigfloat >
}
};
//**********************NEW**********************
// Specialization of CGAL::Float_traits_kernel for leda::bigfloat
template <> class Float_traits_kernel< ::leda::bigfloat > {
public:
typedef ::leda::bigfloat FT;
typedef ::leda::integer IT;
typedef ::CGAL::Float_number_tag Float_type;
typedef CGAL::Precision_type Precision_type;
class Get_precision {
public:
typedef CGAL::Precision_type result_type;
CGAL::Precision_type operator()() const {
return CGAL::Precision_type( leda::bigfloat::get_precision() );
}
};
class Set_precision {
public:
typedef void result_type;
typedef CGAL::Precision_type first_argument_type;
void operator()( const CGAL::Precision_type& precision ) const {
leda::bigfloat::set_precision( (leda::sz_t)precision );
}
};
class Get_rounding_mode {
public:
typedef CGAL::Rounding_mode result_type;
CGAL::Rounding_mode operator()() const {
return CGAL::Rounding_mode( leda::bigfloat::get_rounding_mode() );
}
};
class Set_rounding_mode {
public:
typedef void result_type;
typedef CGAL::Rounding_mode first_argument_type;
void operator()( const CGAL::Rounding_mode& rounding_mode ) const {
leda::bigfloat::set_rounding_mode( (leda::rounding_modes)rounding_mode );
}
};
};
// Specialization of CGAL::Float_traits for leda::bigfloat
template <> class Float_traits< ::leda::bigfloat >
: public Float_traits_base< Float_traits_kernel< ::leda::bigfloat> > {
private:
static Rounding_mode get_rounding_mode() {
return Rounding_mode( leda::bigfloat::get_rounding_mode() );
};
static Precision_type get_precision() {
return Precision_type( leda::bigfloat::get_precision() );
};
public:
typedef Float_traits_kernel< leda::bigfloat > FT_kernel;
typedef FT_kernel::FT FT;
typedef FT_kernel::IT IT;
typedef FT_kernel::Float_type Float_type;
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 {
FT_kernel::Set_precision set_precision;
FT_kernel::Get_precision get_precision;
long old_precision = get_precision();
set_precision(prec);
return old_precision;
}
};
class Get_precision {
public:
// type for the \c AdaptableGenerator concept.
typedef long result_type;
long operator() () const {
FT_kernel::Get_precision get_precision;
return get_precision();
}
};
class Construct
: public Float_traits_base< FT_kernel >::Construct {
public:
FT operator() ( const IT& m, const IT& e = IT(0) ) {
return FT( m, e);
}
}; // class Constructor
class Construct_special_value {
public:
FT operator()( const Special_value& sv ) {
switch( sv ) {
case SV_N_ZERO: return leda::bigfloat::nZero;
case SV_P_ZERO: return leda::bigfloat::pZero;
case SV_N_INF: return leda::bigfloat::nInf;
case SV_P_INF: return leda::bigfloat::pInf;
case SV_NAN: return leda::bigfloat::NaN;
default: return FT(0);
}
}
};
class Is_special_value {
public:
bool operator()( const FT& bf ) const {
return leda::isSpecial( bf );
}
};
class Get_special_value {
public:
Special_value operator()( const FT& bf ) const {
if( leda::isNaN( bf ) )
return SV_NAN;
else if( leda::isnZero( bf ) )
return SV_N_ZERO;
else if( leda::ispZero( bf ) )
return SV_P_ZERO;
else if( leda::isnInf( bf ) )
return SV_N_INF;
else if( leda::ispInf( bf ) )
return SV_P_INF;
else
return SV_NONE;
}
};
class Is_zero {
public:
bool operator()( const FT& bf ) const {
return leda::isZero( bf ) || bf == FT(0);
}
};
class Is_inf {
public:
bool operator()( const FT& bf ) const {
return leda::isInf( bf );
}
};
class Get_mantissa
: public Float_traits_base< FT_kernel >::Get_mantissa {
public:
//! type for the \c AdaptableUnaryFunction concept.
typedef IT result_type;
//! type for the \c AdaptableUnaryFunction concept.
typedef FT argument_type;
IT operator()( const FT& a ) const {
return a.get_significant();
}
}; // class GetMantissa
class Get_exponent
: public Float_traits_base< FT_kernel >::Get_exponent {
public:
//! type for the \c AdaptableUnaryFunction concept.
typedef long result_type;
//! type for the \c AdaptableUnaryFunction concept.
typedef FT argument_type;
long operator()( const FT& a ) const {
return a.get_exponent().to_long();
}
}; // class GetMantissa
class Get_mantissa_and_exponent
: public Float_traits_base< FT_kernel >::Get_mantissa_and_exponent {
public:
//! type for the \c AdaptableUnaryFunction concept.
typedef std::pair< IT, IT > result_type;
//! type for the \c AdaptableUnaryFunction concept.
typedef FT argument_type;
std::pair< IT, IT > operator()( const FT& a ) const {
IT m = a.get_significant();
IT e = a.get_exponent();
std::pair< IT, IT > p( m, e );
return p;
}
}; // class GetMantissaAndExponent
class Round_relative
: public Float_traits_base< FT_kernel >::Round_relative {
public:
//! type for the \c AdaptableTernaryFunction concept.
typedef FT result_type;
//! type for the \c AdaptableTernaryFunction concept.
typedef FT first_argument_type;
//! type for the \c AdaptableTernaryFunction concept.
typedef CGAL::Precision_type second_argument_type;
//! type for the \c AdaptableTernaryFunction concept.
typedef CGAL::Rounding_mode third_argument_type;
FT operator()( const FT& a,
const CGAL::Precision_type& p = get_precision(),
const CGAL::Rounding_mode& m = get_rounding_mode() ) const {
return leda::round(a,(leda::sz_t)p,(leda::rounding_modes)m ) ;
}
}; // class Round
//TODO
//porting Round_absolute and NiX::Float_number from EXACUS2CGAL
// class Round_absolute : public Float_traits_base< FT_kernel >::Round_absolute {
// public:
// //! type for the \c AdaptableTernaryFunction concept.
// typedef FT result_type;
// //! type for the \c AdaptableTernaryFunction concept.
// typedef FT first_argument_type;
// //! type for the \c AdaptableTernaryFunction concept.
// typedef IT second_argument_type;
// //! type for the \c AdaptableTernaryFunction concept.
// typedef CGAL::Rounding_mode third_argument_type;
//
// FT operator()( const FT& a,
// const IT& new_exponent,
// const CGAL::Rounding_mode& r_mode = get_rounding_mode() ) const {
// typedef NiX::Float_number<IT> FN;
// FN fn( a.get_significant(), a.get_exponent() );
// fn = fn.round_absolute( new_exponent, r_mode );
// return FT( fn.get_mantissa(), fn.get_exponent() );
// }
// };
// special functors ( only for Big_float )
class Add
: public Float_traits_base< FT_kernel >::Add {
public:
typedef FT result_type;
typedef FT first_argument_type;
typedef FT second_argument_type;
typedef CGAL::Rounding_mode third_argument_type;
typedef CGAL::Precision_type fourth_argument_type;
FT operator()( const FT& a, const FT& b,
const Rounding_mode& m = get_rounding_mode(),
const Precision_type& p = get_precision() ) const {
return leda::add(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
}
}; // class Add
class Sub
: public Float_traits_base< FT_kernel >::Sub{
public:
typedef FT result_type;
typedef FT first_argument_type;
typedef FT second_argument_type;
typedef CGAL::Rounding_mode third_argument_type;
typedef CGAL::Precision_type fourth_argument_type;
FT operator()( const FT& a, const FT& b ,
const Rounding_mode& m = get_rounding_mode(),
const Precision_type& p = get_precision() ) const {
return leda::sub(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
}
}; // class Sub
class Mul
: public Float_traits_base< FT_kernel >::Mul {
public:
typedef FT result_type;
typedef FT first_argument_type;
typedef FT second_argument_type;
typedef CGAL::Rounding_mode third_argument_type;
typedef CGAL::Precision_type fourth_argument_type;
FT operator()( const FT& a, const FT& b ,
const Rounding_mode& m = get_rounding_mode(),
const Precision_type& p = get_precision() ) const {
return leda::mul(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
}
}; // class Mul
class Div
: public Float_traits_base< FT_kernel >::Div{
public:
typedef FT result_type;
typedef FT first_argument_type;
typedef FT second_argument_type;
typedef CGAL::Rounding_mode third_argument_type;
typedef CGAL::Precision_type fourth_argument_type;
FT operator()( const FT& a, const FT& b ,
const Rounding_mode& m = get_rounding_mode(),
const Precision_type& p = get_precision() ) const {
return leda::div(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
}
}; // class Div
class Sqrt
: public Float_traits_base< FT_kernel >::Sqrt{
public:
typedef FT result_type;
typedef FT first_argument_type;
typedef CGAL::Rounding_mode second_argument_type;
typedef CGAL::Precision_type third_argument_type;
FT operator()( const FT& bf,
const Rounding_mode& r_mode = get_rounding_mode(),
const Precision_type& prec = get_precision() ) const {
return leda::sqrt( bf, (leda::sz_t)prec, (leda::rounding_modes)r_mode);
}
}; // class Sqrt
class Mul_by_pow_of_2
: public Float_traits_base< FT_kernel >::Mul_by_pow_of_2{
public:
//! type for the \c AdaptableBinaryFunction concept.
typedef FT result_type;
//! type for the \c AdaptableBinaryFunction concept.
typedef FT first_argument_type;
//! type for the \c AdaptableBinaryFunction concept.
typedef IT second_argument_type;
FT operator()( const FT& a, const IT& e ) const {
return FT(a.get_significant(), a.get_exponent()+e);
}
}; // class Mul_by_pow_of_2
class Div_by_pow_of_2
: public Float_traits_base< FT_kernel >::Div_by_pow_of_2{
public:
//! type for the \c AdaptableBinaryFunction concept.
typedef FT result_type;
//! type for the \c AdaptableBinaryFunction concept.
typedef FT first_argument_type;
//! type for the \c AdaptableBinaryFunction concept.
typedef IT second_argument_type;
FT operator()( const FT& a, const IT& e ) const {
return FT(a.get_significant(), a.get_exponent()-e);
}
}; // class Div_by_pow_of_2
class Floor {
public:
typedef IT result_type;
typedef FT argument_type;
IT operator()( const FT& fn ) const {
return leda::to_integer( fn, leda::TO_N_INF );
}
};
class Ceil {
public:
typedef IT result_type;
typedef FT argument_type;
IT operator()( const FT& fn ) const {
return leda::to_integer( fn, leda::TO_P_INF );
}
};
};
//**********************NEW**********************
CGAL_END_NAMESPACE

View File

@ -0,0 +1,197 @@
// TODO: add sign to RET
#ifndef CGAL_LEDA_BIGFLOAT_INTERVAL_H
#define CGAL_LEDA_BIGFLOAT_INTERVAL_H
#include <CGAL/basic.h>
#ifndef CGAL_USE_LEDA
#warning This header file needs LEDA installed in order to work properly.
#else // CGAL_USE_LEDA
#include <CGAL/LEDA_basic.h>
#if CGAL_LEDA_VERSION < 500
#include <LEDA/bigfloat.h>
#else
#include <LEDA/numbers/bigfloat.h>
#endif
#include <boost/numeric/interval.hpp>
CGAL_BEGIN_NAMESPACE
namespace CGALi {
struct Rounding_for_leda_bigfloat {
private: typedef leda::bigfloat T;
public:
Rounding_for_leda_bigfloat(){};
~Rounding_for_leda_bigfloat(){};
T conv_down(const T& a){
return round(a,leda::bigfloat::get_precision(),leda::TO_N_INF);
};
T conv_up (const T& a){
return round(a,leda::bigfloat::get_precision(),leda::TO_P_INF);
};
// mathematical operations
T add_down(const T& a, const T& b){
return add(a,b,leda::bigfloat::get_precision(),leda::TO_N_INF);
};
T add_up (const T& a, const T& b){
return add(a,b,leda::bigfloat::get_precision(),leda::TO_P_INF);
};
T sub_down(const T& a, const T& b){
return sub(a, b, leda::bigfloat::get_precision(),leda::TO_N_INF);
};
T sub_up (const T& a, const T& b){
return sub(a, b, leda::bigfloat::get_precision(),leda::TO_P_INF);
};
T mul_down(const T& a, const T& b){
return mul(a, b, leda::bigfloat::get_precision(),leda::TO_N_INF);
};
T mul_up (const T& a, const T& b){
return mul(a, b, leda::bigfloat::get_precision(),leda::TO_P_INF);
};
T div_down(const T& a, const T& b){
return div(a, b, leda::bigfloat::get_precision(),leda::TO_N_INF);
};
T div_up (const T& a, const T& b){
return div(a, b, leda::bigfloat::get_precision(),leda::TO_P_INF);
};
T sqrt_down(const T& a){
return sqrt(a, leda::bigfloat::get_precision(),leda::TO_N_INF);
};
T sqrt_up (const T& a){
return sqrt(a, leda::bigfloat::get_precision(),leda::TO_P_INF);
};
T median(const T& a, const T& b){ return (a+b)/2; };
T int_down(const T& a) { return T(floor(a));};
T int_up (const T& a) { return T(ceil(a)); };
};
class Checking_for_leda_bigfloat {
typedef leda::bigfloat T;
public:
static T pos_inf() {
T b = T(5) / T(0);
CGAL_assertion(leda::ispInf(b));
return b;
}
static T neg_inf() {
T b = T(-5) / T(0);
CGAL_assertion(leda::isnInf(b));
return b;
}
static T nan() {
T b = T(0)*pos_inf();
CGAL_assertion(leda::isNaN(b));
return b;
}
static bool is_nan(const T& b) {
return leda::isNaN(b);
}
static T empty_lower() {
return T(1);
}
static T empty_upper() {
return T(0);
}
static bool is_empty(const T& a, const T& b) {
return a==T(1) && b == T(0);
}
};
} // namespace CGALi
CGAL_END_NAMESPACE
namespace boost {
namespace numeric {
inline
std::ostream& operator <<
(std::ostream& os, const boost::numeric::interval<leda::bigfloat>& x)
{
os << "["
<< x.lower().get_significant() << "*2^" << x.lower().get_exponent()
<< " , "
<< x.upper().get_significant() << "*2^" << x.upper().get_exponent()
<< "]";
return os;
}
}//namespace numeric
}//namespace boost
CGAL_BEGIN_NAMESPACE
typedef boost::numeric::interval
< leda::bigfloat,
boost::numeric::interval_lib::policies
< CGALi::Rounding_for_leda_bigfloat,
CGALi::Checking_for_leda_bigfloat > >
leda_bigfloat_interval;
template <> class Algebraic_structure_traits< leda_bigfloat_interval >
: public Algebraic_structure_traits_base< leda_bigfloat_interval,
Field_with_sqrt_tag > {
public:
typedef Tag_false Is_exact;
typedef Tag_true Is_numerical_sensitive;
class Sqrt
: public Unary_function< Type, Type > {
public:
Type operator()( const Type& x ) const {
return ::boost::numeric::sqrt(x);
}
};
};
template <> class Real_embeddable_traits< leda_bigfloat_interval >
: public Real_embeddable_traits_base< leda_bigfloat_interval > {
public:
class Abs
: public Unary_function< Type, Type > {
public:
Type operator()( const Type& x ) const {
return ::boost::numeric::abs(x);
}
};
class To_double
: public Unary_function< Type, double > {
public:
double operator()( const Type& x ) const {
return CGAL::to_double(::boost::numeric::median(x));
}
};
class To_interval
: public Unary_function< Type, std::pair< double, double > > {
public:
std::pair<double, double> operator()( const Type& x ) const {
std::pair<double, double> lower_I(CGAL::to_interval(x.lower()));
std::pair<double, double> upper_I(CGAL::to_interval(x.upper()));
return std::pair< double, double >(
CGAL::min(lower_I.first , upper_I.first ),
CGAL::max(lower_I.second, upper_I.second));
}
};
};
CGAL_END_NAMESPACE
#endif // CGAL_USE_LEDA
#endif // CGAL_LEDA_BIGFLOAT_INTERVAL_H

View File

@ -1,575 +1,261 @@
// 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: 4515 rschindl$
//
//
// Author(s) : Ralf Schindlbeck <rschindl@mpi-inf.mpg.de>
//
// ============================================================================
// TODO: The comments are all original EXACUS comments and aren't adapted. So
// they may be wrong now.
// TODO:
// - add to comming interval_traits:
// -- CGAL::median(bf_interval)
// -- CGAL::ipower(bf_interval)
// -- CGAL::relatoive_error(bf_interval)
/*! \file CGAL/leda_interval_support.h
*/
*/
#ifndef CGAL_LEDA_INTERVAL_SUPPORT_H
#define CGAL_LEDA_INTERVAL_SUPPORT_H
#include <CGAL/basic.h>
#include <CGAL/leda_bigfloat.h>
#include <boost/numeric/interval.hpp>
#ifndef CGAL_USE_LEDA
#warning This header file needs LEDA installed in order to work properly.
#else // CGAL_USE_LEDA
#include <CGAL/leda_bigfloat.h>
#include <CGAL/leda_integer.h>
#include <CGAL/leda_rational.h>
#include <CGAL/leda_real.h>
#include <CGAL/leda_bigfloat_interval.h>
#include <CGAL/interval_support.h>
// namespace NiX {
CGAL_BEGIN_NAMESPACE
// namespace Intern {
namespace CGALi {
struct Rounding_for_leda_bigfloat {
private: typedef leda::bigfloat T;
template<>
class Bigfloat_interval_traits<leda_bigfloat_interval>
{
public:
Rounding_for_leda_bigfloat(){};
~Rounding_for_leda_bigfloat(){};
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;
long operator()( NT x) const {
leda::bigfloat lower = x.lower();
leda::bigfloat upper = x.upper();
leda::integer lower_m = lower.get_significant();
leda::integer upper_m = upper.get_significant();
leda::integer lower_exp = lower.get_exponent();
leda::integer upper_exp = upper.get_exponent();
long shift = (upper_exp - lower_exp).to_long();
if(shift >= 0 ) upper_m = (upper_m << shift);
else lower_m = (lower_m << -shift);
//CGAL_postcondition(lower_m.length() == upper_m.length());
leda::integer err = lower_m-upper_m;
return std::max(lower_m.length()-err.length(),0);
}
};
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 {
return BF::set_precision(prec);
}
};
class Get_precision {
public:
// type for the \c AdaptableGenerator concept.
typedef long result_type;
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;
T conv_down(const T& a){
return round(a,leda::bigfloat::get_precision(),leda::TO_N_INF);
bool operator() ( NT x, NT y ) const {
return ::boost::numeric::overlap(x,y);
}
};
T conv_up (const T& a){
return round(a,leda::bigfloat::get_precision(),leda::TO_P_INF);
};
// mathematical operations
T add_down(const T& a, const T& b){
return add(a,b,leda::bigfloat::get_precision(),leda::TO_N_INF);
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);
}
};
T add_up (const T& a, const T& b){
return add(a,b,leda::bigfloat::get_precision(),leda::TO_P_INF);
};
T sub_down(const T& a, const T& b){
return sub(a, b, leda::bigfloat::get_precision(),leda::TO_N_INF);
};
T sub_up (const T& a, const T& b){
return sub(a, b, leda::bigfloat::get_precision(),leda::TO_P_INF);
};
T mul_down(const T& a, const T& b){
return mul(a, b, leda::bigfloat::get_precision(),leda::TO_N_INF);
};
T mul_up (const T& a, const T& b){
return mul(a, b, leda::bigfloat::get_precision(),leda::TO_P_INF);
};
T div_down(const T& a, const T& b){
return div(a, b, leda::bigfloat::get_precision(),leda::TO_N_INF);
};
T div_up (const T& a, const T& b){
return div(a, b, leda::bigfloat::get_precision(),leda::TO_P_INF);
};
T sqrt_down(const T& a){
return sqrt(a, leda::bigfloat::get_precision(),leda::TO_N_INF);
};
T sqrt_up (const T& a){
return sqrt(a, leda::bigfloat::get_precision(),leda::TO_P_INF);
};
T median(const T& a, const T& b){ return (a+b)/2; };
T int_down(const T& a) { return T(floor(a));};
T int_up (const T& a) { return T(ceil(a)); };
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);
}
};
/*
T exp_down(T);
T exp_up (T);
T log_down(T);
T log_up (T);
T cos_down(T);
T cos_up (T);
T tan_down(T);
T tan_up (T);
T asin_down(T); // [-1;1]
T asin_up (T); // [-1;1]
T acos_down(T); // [-1;1]
T acos_up (T); // [-1;1]
T atan_down(T); // [-?;+?]
T atan_up (T); // [-?;+?]
T sinh_down(T); // [-?;+?]
T sinh_up (T); // [-?;+?]
T cosh_down(T); // [-?;+?]
T cosh_up (T); // [-?;+?]
T tanh_down(T); // [-?;+?]
T tanh_up (T); // [-?;+?]
T asinh_down(T); // [-?;+?]
T asinh_up (T); // [-?;+?]
T acosh_down(T); // [1;+?]
T acosh_up (T); // [1;+?]
T atanh_down(T); // [-1;1]
T atanh_up (T); // [-1;1]
*/
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);
}
// unprotected rounding class
//typedef ... unprotected_rounding;
};
class Convert_to_bfi {
public:
typedef NT result_type;
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);
leda::bigfloat bnum = x.to_bigfloat();
leda::bigfloat berr = x.get_bigfloat_error();
leda::bigfloat low
= leda::sub(bnum,berr,current_prec,LEDA::TO_N_INF);
leda::bigfloat upp
= leda::add(bnum,berr,current_prec,LEDA::TO_P_INF);
leda_bigfloat_interval bfi(low,upp) ;
// std::cout <<"x: "<< x << std::endl;
// std::cout <<"bfi.lower(): "<< bfi.lower() << std::endl;
// std::cout <<"bfi.upper(): "<< bfi.upper() << std::endl;
CGAL_postcondition( bfi.lower() <= x );
CGAL_postcondition( bfi.upper() >= x );
return bfi;
}
NT operator() (const ::leda::integer& x) {
long current_prec = ::leda::bigfloat::get_precision();
leda_bigfloat_interval bfi;
long length = x.length();
if(length > current_prec) {
::leda::integer significant
= CGAL::abs(x) >> (length - current_prec);
::leda::bigfloat lower,upper;
if(x > 0){
lower = ::leda::bigfloat(significant,length - current_prec);
upper = ::leda::bigfloat(significant+1,length - current_prec);
}else{
lower
= -::leda::bigfloat(significant+1,length - current_prec);
upper
= -::leda::bigfloat(significant,length - current_prec);
}
bfi = leda_bigfloat_interval(lower,upper);
}else{
::leda::bigfloat bf(x);
bfi = leda_bigfloat_interval(bf,bf);
}
CGAL_postcondition( bfi.lower() <= x );
CGAL_postcondition( bfi.upper() >= x );
return bfi;
}
NT operator() (const ::leda::rational& x) {
long old_prec = ::leda::bigfloat::get_precision();
::leda::bigfloat::set_precision(old_prec*2);
Bigfloat_interval_traits<NT>::Convert_to_bfi convert_to_bfi;
leda_bigfloat_interval num = convert_to_bfi(x.numerator());
leda_bigfloat_interval den = convert_to_bfi(x.denominator());
::leda::bigfloat::set_precision(old_prec);
leda_bigfloat_interval bfi = num/den;
CGAL_postcondition( bfi.lower() <= x );
CGAL_postcondition( bfi.upper() >= x );
return bfi;
}
};
};
class Checking_for_leda_bigfloat {
typedef leda::bigfloat T;
public:
static T pos_inf() {
T b = T(5) / T(0);
CGAL_assertion(leda::ispInf(b));
return b;
}
static T neg_inf() {
T b = T(-5) / T(0);
CGAL_assertion(leda::isnInf(b));
return b;
}
static T nan() {
T b = T(0)*pos_inf();
CGAL_assertion(leda::isNaN(b));
return b;
}
static bool is_nan(const T& b) {
return leda::isNaN(b);
}
static T empty_lower() {
return T(1);
}
static T empty_upper() {
return T(0);
}
static bool is_empty(const T& a, const T& b) {
return a==T(1) && b == T(0);
}
};
} // namespace CGALi
// } // namespace NiX
CGAL_END_NAMESPACE
namespace boost {
namespace numeric {
inline
std::ostream& operator <<
(std::ostream& os, const boost::numeric::interval<leda::bigfloat>& x)
{
os << "["
<< x.lower().get_significant() << "*2^" << x.lower().get_exponent()
<< " , "
<< x.upper().get_significant() << "*2^" << x.upper().get_exponent()
<< "]";
return os;
}
}//namespace numeric
}//namespace boost
// namespace NiX {
CGAL_BEGIN_NAMESPACE
typedef boost::numeric::interval
< leda::bigfloat,
boost::numeric::interval_lib::policies
< CGALi::Rounding_for_leda_bigfloat,
CGALi::Checking_for_leda_bigfloat > >
leda_bigfloat_interval;
/*
CGAL::Sign inline sign(const leda::bigfloat& x){
if (x < 0 ) return CGAL::NEGATIVE;
if (x > 0 ) return CGAL::POSITIVE;
return CGAL::ZERO;
}
*/
leda_bigfloat_interval inline ipower(const leda_bigfloat_interval& x, int i ){
return ::boost::numeric::pow(x,i);
}
// left overs?
::leda::bigfloat inline median(const leda_bigfloat_interval& x){
return ::boost::numeric::median(x);
}
// forward
template<typename BFI> class Bigfloat_interval_traits;
template<>
class Bigfloat_interval_traits<leda_bigfloat_interval>
{
public:
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;
long operator()( NT x) const {
leda::bigfloat lower = x.lower();
leda::bigfloat upper = x.upper();
leda::integer lower_m = lower.get_significant();
leda::integer upper_m = upper.get_significant();
leda::integer lower_exp = lower.get_exponent();
leda::integer upper_exp = upper.get_exponent();
long shift = (upper_exp - lower_exp).to_long();
if(shift >= 0 ) upper_m = (upper_m << shift);
else lower_m = (lower_m << -shift);
//CGAL_postcondition(lower_m.length() == upper_m.length());
leda::integer err = lower_m-upper_m;
return std::max(lower_m.length()-err.length(),0);
}
};
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 {
return BF::set_precision(prec);
}
};
class Get_precision {
public:
// type for the \c AdaptableGenerator concept.
typedef long result_type;
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:
typedef NT result_type;
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);
leda::bigfloat bnum = x.to_bigfloat();
leda::bigfloat berr = x.get_bigfloat_error();
leda::bigfloat low
= leda::sub(bnum,berr,current_prec,LEDA::TO_N_INF);
leda::bigfloat upp
= leda::add(bnum,berr,current_prec,LEDA::TO_P_INF);
leda_bigfloat_interval bfi(low,upp) ;
// std::cout <<"x: "<< x << std::endl;
// std::cout <<"bfi.lower(): "<< bfi.lower() << std::endl;
// std::cout <<"bfi.upper(): "<< bfi.upper() << std::endl;
CGAL_postcondition( bfi.lower() <= x );
CGAL_postcondition( bfi.upper() >= x );
return bfi;
}
NT operator() (const ::leda::integer& x) {
long current_prec = ::leda::bigfloat::get_precision();
leda_bigfloat_interval bfi;
long length = x.length();
if(length > current_prec) {
::leda::integer significant
= CGAL::abs(x) >> (length - current_prec);
::leda::bigfloat lower,upper;
if(x > 0){
lower = ::leda::bigfloat(significant,length - current_prec);
upper = ::leda::bigfloat(significant+1,length - current_prec);
}else{
lower
= -::leda::bigfloat(significant+1,length - current_prec);
upper
= -::leda::bigfloat(significant,length - current_prec);
}
bfi = leda_bigfloat_interval(lower,upper);
}else{
::leda::bigfloat bf(x);
bfi = leda_bigfloat_interval(bf,bf);
}
CGAL_postcondition( bfi.lower() <= x );
CGAL_postcondition( bfi.upper() >= x );
return bfi;
}
NT operator() (const ::leda::rational& x) {
long old_prec = ::leda::bigfloat::get_precision();
::leda::bigfloat::set_precision(old_prec*2);
Bigfloat_interval_traits<NT>::Convert_to_bfi convert_to_bfi;
leda_bigfloat_interval num = convert_to_bfi(x.numerator());
leda_bigfloat_interval den = convert_to_bfi(x.denominator());
::leda::bigfloat::set_precision(old_prec);
leda_bigfloat_interval bfi = num/den;
CGAL_postcondition( bfi.lower() <= x );
CGAL_postcondition( bfi.upper() >= x );
return bfi;
}
};
};
template <> class Algebraic_structure_traits< leda_bigfloat_interval >
: public Algebraic_structure_traits_base< leda_bigfloat_interval,
Field_with_sqrt_tag > {
public:
typedef Tag_false Is_exact;
typedef Tag_true Is_numerical_sensitive;
class Sqrt
: public Unary_function< Type, Type > {
public:
Type operator()( const Type& x ) const {
return ::boost::numeric::sqrt(x);
}
};
};
template <> class Real_embeddable_traits< leda_bigfloat_interval >
: public Real_embeddable_traits_base< leda_bigfloat_interval > {
public:
class Abs
: public Unary_function< Type, Type > {
public:
Type operator()( const Type& x ) const {
return ::boost::numeric::abs(x);
}
};
class To_double
: public Unary_function< Type, double > {
public:
double operator()( const Type& x ) const {
return CGAL::to_double(::boost::numeric::median(x));
}
};
class To_interval
: public Unary_function< Type, std::pair< double, double > > {
public:
std::pair<double, double> operator()( const Type& x ) const {
// TODO
// return ::boost::numeric::hull(CGAL::to_interval(x.lower()),CGAL::to_interval(x.upper()));
return std::pair< double, double >( CGAL::to_double( x.lower() ),
CGAL::to_double( x.upper() ) );
}
};
};
// template <>
// class NT_traits<leda_bigfloat_interval>
// : public NT_traits_base<leda_bigfloat_interval,
// Field_with_sqrt_tag>,
// public NT_traits_comparable_base<leda_bigfloat_interval>
//
// {
// public:
// typedef leda_bigfloat_interval NT;
//
// class Abs {
// public:
// // type for the \c AdaptableUnaryFunction concept.
// typedef NT argument_type;
// // type for the \c AdaptableUnaryFunction concept.
// typedef NT result_type;
// NT operator()( NT a) const {
// return ::boost::numeric::abs(a);
// };
// };
//
// class Sqrt {
// public:
// // type for the \c AdaptableUnaryFunction concept.
// typedef NT argument_type;
// // type for the \c AdaptableUnaryFunction concept.
// typedef NT result_type;
// NT operator()( NT a) const {
// return ::boost::numeric::sqrt(a);
// };
// };
//
// class To_double {
// public:
// // the result type.
// typedef double result_type;
// // the argument type.
// typedef NT argument_type;
//
// double operator()(const NT& a) const {
// return NiX::to_double(::boost::numeric::median(a));
// }
// };
// class To_Interval {
// public:
// // the result type.
// typedef Interval result_type;
// // the argument type.
// typedef NT argument_type;
//
// Interval operator()(const NT& a) const {
// return ::boost::numeric::hull(NiX::to_Interval(a.lower()),
// NiX::to_Interval(a.upper()));
// }
// };
//TODO
//porting Floor_log2_abs and Ceil_log2_abs from EXACUS2CGAL
// class Floor_log2_abs {
// public:
// typedef NT argument_type;
// typedef long result_type;
// result_type operator() (argument_type x) {
// CGAL_precondition(! ::boost::numeric::in_zero(x));
// return floor_log2_abs(::boost::numeric::abs(x).lower());
// }
// };
// class Ceil_log2_abs {
// public:
// typedef NT argument_type;
// typedef long result_type;
// result_type operator() (argument_type x) {
// CGAL_precondition(!(::boost::numeric::in_zero(x) &&
// ::boost::numeric::singleton(x)));
// return ceil_log2_abs(::boost::numeric::abs(x).upper());
// }
// };
// };
::leda::bigfloat inline relative_error(const leda_bigfloat_interval& x){
if(in_zero(x)){
return CGAL::abs(x).upper();
@ -578,8 +264,11 @@ template <> class Real_embeddable_traits< leda_bigfloat_interval >
}
}
// } // namespace NiX
leda_bigfloat_interval inline ipower(const leda_bigfloat_interval& x, int i ){
return ::boost::numeric::pow(x,i);
}
CGAL_END_NAMESPACE
#endif // CGAL_USE_LEDA
#endif // CGAL_LEDA_INTERVAL_SUPPORT_H

View File

@ -0,0 +1,88 @@
#include <CGAL/basic.h>
#include <CGAL/Testsuite/assert.h>
#include <CGAL/interval_support.h>
#ifdef CGAL_USE_CORE
#include <CGAL/core_interval_support.h>
#endif
#ifdef CGAL_USE_LEDA
#include <CGAL/leda_interval_support.h>
#endif
// TODO: separat BFI functors from interval functors.
template<class BFI>
void generic_test_bigfloat_interval(){
typedef CGAL::Bigfloat_interval_traits<BFI> BFIT;
typedef typename BFIT::BF BF;
//TODO: move this into an new Interval_traits
// get_significant_bits
CGAL_test_assert(CGAL::get_significant_bits(BFI(3)) == 2);
// upper
CGAL_test_assert(CGAL::upper(BFI(3)) == BF(3));
// lower
CGAL_test_assert(CGAL::lower(BFI(3)) == BF(3));
// TODO: rm BFI() within call
// get/set_precsion
long precision = CGAL::get_precision(BFI());
CGAL_test_assert(CGAL::set_precision(BFI(),15) == precision);
CGAL_test_assert(CGAL::set_precision(BFI(),precision) == 15);
// hull
CGAL_test_assert(CGAL::lower(CGAL::hull(BFI(2),BFI(5))) >= BF(1));
CGAL_test_assert(CGAL::lower(CGAL::hull(BFI(2),BFI(5))) <= BF(2));
CGAL_test_assert(CGAL::upper(CGAL::hull(BFI(2),BFI(5))) >= BF(5));
CGAL_test_assert(CGAL::upper(CGAL::hull(BFI(2),BFI(5))) <= BF(6));
// in_zero
CGAL_test_assert(CGAL::in_zero(CGAL::hull(BFI( 2),BFI(3))) == false);
CGAL_test_assert(CGAL::in_zero(CGAL::hull(BFI(-2),BFI(3))) == true);
// overlap
BFI hull_2_5 = CGAL::hull(BFI(2),BFI(5));
CGAL_test_assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(6),BFI(7))) == false);
CGAL_test_assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(5),BFI(6))) == true);
CGAL_test_assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(4),BFI(5))) == true);
CGAL_test_assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(3),BFI(4))) == true);
CGAL_test_assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(2),BFI(3))) == true);
CGAL_test_assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(1),BFI(2))) == true);
CGAL_test_assert(CGAL::overlap(hull_2_5, CGAL::hull(BFI(0),BFI(1))) == false);
// singelton
CGAL_test_assert(CGAL::singleton(CGAL::hull(BFI(2),BFI(2))) == true);
CGAL_test_assert(CGAL::singleton(CGAL::hull(BFI(2),BFI(3))) == false);
// width
CGAL_test_assert(CGAL::width(CGAL::hull(BFI(2),BFI(2))) == BF(0));
CGAL_test_assert(CGAL::width(CGAL::hull(BFI(2),BFI(3))) == BF(1));
typedef typename CGAL::Get_arithmetic_kernel<BFI>::Arithmetic_kernel AK;
typedef typename AK::Integer Integer;
typedef typename AK::Rational Rational;
typedef typename AK::Field_with_sqrt FWS;
CGAL_test_assert(CGAL::convert_to_bfi(Integer(1)) == BFI(1));
CGAL_test_assert(CGAL::convert_to_bfi(Rational(1)) == BFI(1));
CGAL_test_assert(CGAL::convert_to_bfi(FWS(1)) == BFI(1));
}
int main(){
#ifdef CGAL_USE_CORE
// generic_test_bigfloat_interval<CORE::BigFloat>();
#endif
#ifdef CGAL_USE_LEDA
generic_test_bigfloat_interval<CGAL::leda_bigfloat_interval>();
#endif
}