mirror of https://github.com/CGAL/cgal
cleanup
- 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:
parent
ef10ca7e16
commit
68be1cfdbb
|
|
@ -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/CORE_BigFloat.tex -text
|
||||||
Number_types/doc_tex/NumberTypeSupport_ref/fundamental_types.tex -text
|
Number_types/doc_tex/NumberTypeSupport_ref/fundamental_types.tex -text
|
||||||
Number_types/doc_tex/NumberTypeSupport_ref/open.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/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_extension_traits.h -text
|
||||||
Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h -text
|
Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h -text
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,7 @@
|
||||||
#include <CGAL/leda_bigfloat.h>
|
#include <CGAL/leda_bigfloat.h>
|
||||||
#include <CGAL/leda_real.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>
|
#include <CGAL/leda_interval_support.h>
|
||||||
// #endif //CGAL_INTERN_USE_BFI
|
|
||||||
|
|
||||||
#endif // CGAL_USE_LEDA
|
#endif // CGAL_USE_LEDA
|
||||||
|
|
||||||
|
|
@ -77,12 +74,9 @@ public:
|
||||||
//! exact root expressions, constructible from integers and rationals
|
//! exact root expressions, constructible from integers and rationals
|
||||||
typedef leda_real Field_with_sqrt;
|
typedef leda_real Field_with_sqrt;
|
||||||
|
|
||||||
// #ifdef CGAL_INTERN_USE_BFI
|
|
||||||
// undocumented
|
// undocumented
|
||||||
typedef leda_bigfloat Bigfloat;
|
typedef leda_bigfloat Bigfloat;
|
||||||
// typedef CGALi::leda_bigfloat_interval Bigfloat_interval;
|
|
||||||
typedef leda_bigfloat_interval Bigfloat_interval;
|
typedef leda_bigfloat_interval Bigfloat_interval;
|
||||||
// #endif //CGAL_INTERN_USE_BFI
|
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif // CGAL_USE_LEDA
|
#endif // CGAL_USE_LEDA
|
||||||
|
|
@ -101,11 +95,9 @@ public:
|
||||||
typedef CORE::BigRat Rational;
|
typedef CORE::BigRat Rational;
|
||||||
//! exact root expressions, constructible from integers and rationals
|
//! exact root expressions, constructible from integers and rationals
|
||||||
typedef CORE::Expr Field_with_sqrt;
|
typedef CORE::Expr Field_with_sqrt;
|
||||||
// #ifdef CGAL_INTERN_USE_BFI
|
|
||||||
// undocumented
|
// undocumented
|
||||||
typedef CORE::BigFloat Bigfloat;
|
typedef CORE::BigFloat Bigfloat;
|
||||||
typedef CORE::BigFloat Bigfloat_interval;
|
typedef CORE::BigFloat Bigfloat_interval;
|
||||||
// #endif //CGAL_INTERN_USE_BFI
|
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif // CGAL_USE_CORE
|
#endif // CGAL_USE_CORE
|
||||||
|
|
@ -164,42 +156,10 @@ typedef LEDA_arithmetic_kernel Arithmetic_kernel;
|
||||||
typedef typename AT::Integer Integer; \
|
typedef typename AT::Integer Integer; \
|
||||||
typedef typename AT::Rational Rational; \
|
typedef typename AT::Rational Rational; \
|
||||||
typedef typename AT::Field_with_sqrt Field_with_sqrt;
|
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
|
// 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;
|
template< class NT > struct Get_arithmetic_kernel;
|
||||||
|
|
||||||
#ifdef CGAL_USE_LEDA
|
#ifdef CGAL_USE_LEDA
|
||||||
|
|
@ -216,6 +176,14 @@ template< class NT > struct Get_arithmetic_kernel;
|
||||||
struct Get_arithmetic_kernel<leda::real>{
|
struct Get_arithmetic_kernel<leda::real>{
|
||||||
typedef LEDA_arithmetic_kernel Arithmetic_kernel;
|
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
|
#endif //CGAL_USE_LEDA
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -233,6 +201,10 @@ template< class NT > struct Get_arithmetic_kernel;
|
||||||
struct Get_arithmetic_kernel<CORE::Expr>{
|
struct Get_arithmetic_kernel<CORE::Expr>{
|
||||||
typedef CORE_arithmetic_kernel Arithmetic_kernel;
|
typedef CORE_arithmetic_kernel Arithmetic_kernel;
|
||||||
};
|
};
|
||||||
|
template <>
|
||||||
|
struct Get_arithmetic_kernel<CORE::BigFloat>{
|
||||||
|
typedef CORE_arithmetic_kernel Arithmetic_kernel;
|
||||||
|
};
|
||||||
#endif //CGAL_USE_CORE
|
#endif //CGAL_USE_CORE
|
||||||
|
|
||||||
template <class COEFF, class ROOT>
|
template <class COEFF, class ROOT>
|
||||||
|
|
@ -242,10 +214,6 @@ template< class NT > struct Get_arithmetic_kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace CGALi
|
|
||||||
// #endif //CGAL_INTERN_USE_BFI
|
|
||||||
|
|
||||||
|
|
||||||
CGAL_END_NAMESPACE
|
CGAL_END_NAMESPACE
|
||||||
|
|
||||||
#endif // CGAL_ARITHMETIC_KERNEL_H
|
#endif // CGAL_ARITHMETIC_KERNEL_H
|
||||||
|
|
|
||||||
|
|
@ -17,51 +17,19 @@
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
|
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
#ifndef CGAL_CORE_BIGFLOAT_H
|
#ifndef CGAL_CORE_BIGFLOAT_H
|
||||||
#define CGAL_CORE_BIGFLOAT_H
|
#define CGAL_CORE_BIGFLOAT_H
|
||||||
|
|
||||||
#include <CGAL/number_type_basic.h>
|
#include <CGAL/number_type_basic.h>
|
||||||
#include <CGAL/CORE_coercion_traits.h>
|
#include <CGAL/CORE_coercion_traits.h>
|
||||||
#include <CGAL/Float_traits.h>
|
#include <CGAL/core_interval_support.h>
|
||||||
|
|
||||||
CGAL_BEGIN_NAMESPACE
|
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
|
// Algebraic structure traits
|
||||||
|
|
@ -94,14 +62,9 @@ template <> class Algebraic_structure_traits< CORE::BigFloat >
|
||||||
Type result = tmp1*CORE::BigFloat::exp2(a.exp()*7) + err;
|
Type result = tmp1*CORE::BigFloat::exp2(a.exp()*7) + err;
|
||||||
|
|
||||||
CGAL_postcondition(result >= 0);
|
CGAL_postcondition(result >= 0);
|
||||||
//#ifndef NDEBUG
|
CGAL_postcondition(CGAL::lower(result*result) <= CGAL::lower(x));
|
||||||
// Type tmp = result * result;
|
CGAL_postcondition(CGAL::upper(result*result) >= CGAL::upper(x));
|
||||||
// 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
|
|
||||||
return result;
|
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 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
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:
|
//since types are included by CORE_coercion_traits.h:
|
||||||
#include <CGAL/CORE_Expr.h>
|
#include <CGAL/CORE_Expr.h>
|
||||||
#include <CGAL/CORE_BigInt.h>
|
#include <CGAL/CORE_BigInt.h>
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -4,65 +4,53 @@
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
//
|
//
|
||||||
// $URL:$
|
// $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
|
// TODO:
|
||||||
// they may be wrong now.
|
// - mv general functors in a new Interval_traits
|
||||||
|
// - mv function 'round' to Interval_traits
|
||||||
|
|
||||||
|
|
||||||
/*! \file CGAL/core_interval_support.h
|
|
||||||
This is experimental
|
|
||||||
use CORE::BigFloat as interval type.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CGAL_CORE_INTERVAL_SUPPORT_H
|
#ifndef CGAL_CORE_INTERVAL_SUPPORT_H
|
||||||
#define CGAL_CORE_INTERVAL_SUPPORT_H
|
#define CGAL_CORE_INTERVAL_SUPPORT_H
|
||||||
|
|
||||||
#include <CGAL/basic.h>
|
#include <CGAL/basic.h>
|
||||||
|
#include <CGAL/interval_support.h>
|
||||||
|
|
||||||
#ifndef CGAL_USE_CORE
|
#ifndef CGAL_USE_CORE
|
||||||
#warning This header file needs CORE installed in order to work properly.
|
#warning This header file needs CORE installed in order to work properly.
|
||||||
#else // CGAL_USE_CORE
|
#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>
|
#include <CGAL/CORE/BigFloat.h>
|
||||||
|
|
||||||
// namespace NiX{
|
|
||||||
CGAL_BEGIN_NAMESPACE
|
CGAL_BEGIN_NAMESPACE
|
||||||
|
|
||||||
template<typename BFI> long get_significant_bits(BFI bfi);
|
template<typename BFI> long get_significant_bits(BFI bfi);
|
||||||
|
|
||||||
CORE::BigFloat
|
CORE::BigFloat
|
||||||
inline
|
inline
|
||||||
round(const CORE::BigFloat& x, long rel_prec = CORE::defRelPrec.toLong() ){
|
round(const CORE::BigFloat& x, long rel_prec = CORE::defRelPrec.toLong() ){
|
||||||
CGAL_postcondition(rel_prec >= 0);
|
CGAL_postcondition(rel_prec >= 0);
|
||||||
// since there is not rel prec defined if in_zero(x)
|
// since there is not rel prec defined if in_zero(x)
|
||||||
if (x.isZeroIn()) return x;
|
if (x.isZeroIn()) return x;
|
||||||
if (CGAL::get_significant_bits(x) <= rel_prec) return x;
|
if (CGAL::get_significant_bits(x) <= rel_prec) return x;
|
||||||
|
|
||||||
typedef CORE::BigFloat BF;
|
typedef CORE::BigFloat BF;
|
||||||
typedef CORE::BigFloat BFI;
|
typedef CORE::BigFloat BFI;
|
||||||
typedef CORE::BigInt Integer;
|
typedef CORE::BigInt Integer;
|
||||||
BF xr;
|
BF xr;
|
||||||
|
|
||||||
CORE::BigInt m = x.m();
|
CORE::BigInt m = x.m();
|
||||||
long err = x.err();
|
long err = x.err();
|
||||||
long exp = x.exp();
|
long exp = x.exp();
|
||||||
|
|
||||||
long shift = ::CORE::bitLength(m) - rel_prec - 1;
|
long shift = ::CORE::bitLength(m) - rel_prec - 1;
|
||||||
if( shift > 0 ){
|
if( shift > 0 ){
|
||||||
Integer new_m = m >> shift ;
|
Integer new_m = m >> shift ;
|
||||||
if(err == 0){
|
if(err == 0){
|
||||||
xr = BF(new_m,1,0)*BF::exp2(exp*14+shift);
|
xr = BF(new_m,1,0)*BF::exp2(exp*14+shift);
|
||||||
}else{
|
}else{
|
||||||
|
|
@ -79,211 +67,218 @@ template<typename BFI> long get_significant_bits(BFI bfi);
|
||||||
return xr;
|
return xr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BFI> class Bigfloat_interval_traits;
|
|
||||||
|
|
||||||
template<> class Bigfloat_interval_traits<CORE::BigFloat>
|
template<> class Bigfloat_interval_traits<CORE::BigFloat>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef CORE::BigFloat NT;
|
||||||
|
typedef CORE::BigFloat BF;
|
||||||
|
|
||||||
{
|
typedef Bigfloat_interval_traits<NT> Self;
|
||||||
public:
|
|
||||||
typedef CORE::BigFloat NT;
|
|
||||||
typedef CORE::BigFloat BF;
|
|
||||||
|
|
||||||
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 {
|
long operator()( NT x) const {
|
||||||
public:
|
if(x.err() == 0 ) {
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
return ::CORE::bitLength(x.m());
|
||||||
typedef NT argument_type;
|
}
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
else {
|
||||||
typedef long result_type;
|
return ::CORE::bitLength(x.m()) - ::CORE::bitLength(x.err());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
long operator()( NT x) const {
|
class Set_precision {
|
||||||
//std::cout << ":::::::::::::::::::: "<< std::endl;
|
public:
|
||||||
if(x.err() == 0 ) {
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
//std::cout << "Exact: \n" << x.m() << std::endl;
|
typedef long argument_type;
|
||||||
return ::CORE::bitLength(x.m());
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
}
|
typedef long result_type;
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
long operator() ( long prec ) const {
|
||||||
};
|
long result = ::CORE::defRelPrec.toLong();
|
||||||
|
::CORE::defRelPrec = prec;
|
||||||
|
::CORE::defBFdivRelPrec = prec;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class Set_precision {
|
class Get_precision {
|
||||||
public:
|
public:
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
// type for the \c AdaptableGenerator concept.
|
||||||
typedef long argument_type;
|
typedef long result_type;
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
|
||||||
typedef long result_type;
|
|
||||||
|
|
||||||
long operator() ( long prec ) const {
|
long operator() () const {
|
||||||
long result = ::CORE::defRelPrec.toLong();
|
return ::CORE::defRelPrec.toLong();
|
||||||
::CORE::defRelPrec = prec;
|
}
|
||||||
::CORE::defBFdivRelPrec = prec;
|
};
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Get_precision {
|
class Upper {
|
||||||
public:
|
public:
|
||||||
// type for the \c AdaptableGenerator concept.
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
typedef long result_type;
|
typedef NT argument_type;
|
||||||
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
|
typedef BF result_type;
|
||||||
|
|
||||||
long operator() () const {
|
BF operator() ( NT x ) const {
|
||||||
return ::CORE::defRelPrec.toLong();
|
CORE::BigFloat result = ::CORE::BigFloat(x.m()+x.err(),0,x.exp());
|
||||||
}
|
CGAL_postcondition(result >= x);
|
||||||
};
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class Upper {
|
class Lower {
|
||||||
public:
|
public:
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
typedef NT argument_type;
|
typedef NT argument_type;
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
typedef BF result_type;
|
typedef BF result_type;
|
||||||
|
|
||||||
BF operator() ( NT x ) const {
|
BF operator() ( NT x ) const {
|
||||||
CORE::BigFloat result = ::CORE::BigFloat(x.m()+x.err(),0,x.exp());
|
CORE::BigFloat result = ::CORE::BigFloat(x.m()-x.err(),0,x.exp());
|
||||||
CGAL_postcondition(result >= x);
|
CGAL_postcondition(result <= x);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Lower {
|
class In_zero {
|
||||||
public:
|
public:
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
typedef NT argument_type;
|
typedef NT argument_type;
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
typedef BF result_type;
|
typedef bool result_type;
|
||||||
|
|
||||||
BF operator() ( NT x ) const {
|
bool operator() ( NT x ) const {
|
||||||
CORE::BigFloat result = ::CORE::BigFloat(x.m()-x.err(),0,x.exp());
|
return x.isZeroIn();
|
||||||
CGAL_postcondition(result <= x);
|
}
|
||||||
return result;
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
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 In_zero {
|
bool operator() ( NT x, NT y ) const {
|
||||||
public:
|
Self::In_zero in_zero;
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
bool result = in_zero(x-y);
|
||||||
typedef NT argument_type;
|
return result;
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
}
|
||||||
typedef bool result_type;
|
};
|
||||||
|
|
||||||
bool operator() ( NT x ) const {
|
class Hull {
|
||||||
return x.isZeroIn();
|
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 Overlap {
|
NT operator() ( NT x, NT y ) const {
|
||||||
public:
|
#if 0
|
||||||
// type for the \c AdaptableBinaryFunction concept.
|
// this is not possible since CORE::centerize has a bug.
|
||||||
typedef NT first_argument_type;
|
NT result = CORE::centerize(x,y);
|
||||||
// type for the \c AdaptableBinaryFunction concept.
|
#else
|
||||||
typedef NT second_argument_type;
|
|
||||||
// type for the \c AdaptableBinaryFunction concept.
|
|
||||||
typedef bool result_type;
|
|
||||||
|
|
||||||
bool operator() ( NT x, NT y ) const {
|
CORE::BigFloat result;
|
||||||
Self::In_zero in_zero;
|
|
||||||
bool result = in_zero(x-y);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Hull {
|
// Unfortunately, CORE::centerize(x,y) has bugs.
|
||||||
public:
|
if ((x.m() == y.m()) && (x.err() == y.err()) && (x.exp() == y.exp())) {
|
||||||
// type for the \c AdaptableBinaryFunction concept.
|
return x;
|
||||||
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 lower = std::min(CGAL::lower(x),
|
||||||
CORE::BigFloat result;
|
CGAL::lower(y));
|
||||||
|
CORE::BigFloat upper = std::max(CGAL::upper(x),
|
||||||
|
CGAL::upper(y));
|
||||||
|
|
||||||
// Unfortunately, CORE::centerize(x,y) has bugs.
|
CORE::BigFloat mid = (lower + upper)/2;
|
||||||
if ((x.m() == y.m()) && (x.err() == y.err()) &&
|
|
||||||
(x.exp() == y.exp())) {
|
|
||||||
|
|
||||||
//rep(x) == rep(y)
|
// Now we have to compute the error. The problem is that .err() is just a long
|
||||||
return x;
|
CORE::BigFloat err = (upper - lower)/CORE::BigFloat(2);
|
||||||
}
|
|
||||||
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;
|
|
||||||
|
|
||||||
CGAL_postcondition(lower_functor(result) <=
|
//std::cout << "lower " << lower << std::endl;
|
||||||
std::min(lower_functor(x),
|
//std::cout << "upper " << upper << std::endl;
|
||||||
lower_functor(y)));
|
//std::cout << "mid " << mid << std::endl;
|
||||||
CGAL_postcondition(upper_functor(result) >=
|
//std::cout << "err I " << err << std::endl;
|
||||||
std::max(upper_functor(x),
|
|
||||||
upper_functor(y)));
|
|
||||||
return result ;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Singleton {
|
// shift such that err.m()+err.err() fits into long
|
||||||
public:
|
int digits_long = std::numeric_limits<long>::digits;
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
if(::CORE::bitLength(err.m()) >= digits_long){
|
||||||
typedef NT argument_type;
|
long shift = ::CORE::bitLength(err.m()) - digits_long + 1 ;
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
//std::cout << "shift " << shift<< std::endl;
|
||||||
typedef bool result_type;
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
bool operator() ( NT x ) const {
|
result = mid + err;
|
||||||
return (x.err() == 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Width {
|
#endif
|
||||||
public:
|
CGAL_postcondition(
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
CGAL::lower(result)
|
||||||
typedef NT argument_type;
|
<= std::min(CGAL::lower(x), CGAL::lower(y)));
|
||||||
// type for the \c AdaptableUnaryFunction concept.
|
CGAL_postcondition(
|
||||||
typedef BF result_type;
|
CGAL::upper(result)
|
||||||
|
>= std::max(CGAL::upper(x), CGAL::upper(y)));
|
||||||
|
|
||||||
BF operator() ( NT x ) const {
|
return result ;
|
||||||
unsigned long err = 2*x.err();
|
}
|
||||||
return BF(CORE::BigInt(err),0,x.exp());
|
};
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Convert_to_bfi {
|
class Singleton {
|
||||||
public:
|
public:
|
||||||
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
|
typedef NT argument_type;
|
||||||
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
|
typedef bool result_type;
|
||||||
|
|
||||||
typedef NT 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;
|
||||||
|
|
||||||
NT operator() (const ::CORE::Expr& x){
|
BF operator() ( NT x ) const {
|
||||||
return round(CORE::BigFloat(x));
|
unsigned long err = 2*x.err();
|
||||||
}
|
return BF(CORE::BigInt(err),0,x.exp());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
NT operator() (const ::CORE::BigInt& x){
|
class Convert_to_bfi {
|
||||||
return round(CORE::BigFloat(x));
|
public:
|
||||||
}
|
|
||||||
|
|
||||||
NT operator() (const ::CORE::BigRat& x){
|
typedef NT result_type;
|
||||||
return round(CORE::BigFloat(x));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
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
|
CGAL_END_NAMESPACE
|
||||||
|
|
||||||
#endif // CGAL_USE_CORE
|
#endif // CGAL_USE_CORE
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,14 @@
|
||||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
//
|
//
|
||||||
// $URL:$
|
// $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/interval_support.h
|
/*! \file CGAL/interval_support.h
|
||||||
This is experimental
|
This is experimental
|
||||||
|
|
@ -23,69 +20,35 @@
|
||||||
#define CGAL_INTERVAL_SUPPORT_H
|
#define CGAL_INTERVAL_SUPPORT_H
|
||||||
|
|
||||||
#include <CGAL/basic.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
|
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 BigfloatInterval> class Bigfloat_interval_traits;
|
||||||
|
|
||||||
template<typename BFI> long get_significant_bits(BFI bfi) {
|
template<typename BFI> long get_significant_bits(BFI bfi) {
|
||||||
typename Bigfloat_interval_traits<BFI>::Get_significant_bits
|
typename Bigfloat_interval_traits<BFI>::Get_significant_bits
|
||||||
get_significant_bits;
|
get_significant_bits;
|
||||||
return get_significant_bits(bfi);
|
return get_significant_bits(bfi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
template<typename BFI> long set_precision(BFI bfi,long prec) {
|
||||||
template<typename BFI> long set_precision(BFI bfi,long prec) {
|
typename Bigfloat_interval_traits<BFI>::Set_precision set_precision;
|
||||||
typename Float_traits<typename Bigfloat_interval_traits<BFI>::BF>
|
|
||||||
::Set_precision set_precision;
|
|
||||||
return set_precision(prec);
|
return set_precision(prec);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BFI> long get_precision(BFI bfi) {
|
template<typename BFI> long get_precision(BFI bfi) {
|
||||||
typename Float_traits<typename Bigfloat_interval_traits<BFI>::BF>
|
typename Bigfloat_interval_traits<BFI>::Get_precision get_precision;
|
||||||
::Get_precision get_precision;
|
|
||||||
return 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>
|
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;
|
typename Bigfloat_interval_traits<BFI>::Upper upper;
|
||||||
return upper(bfi);
|
return upper(bfi);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename 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;
|
typename Bigfloat_interval_traits<BFI>::Lower lower;
|
||||||
return lower(bfi);
|
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
|
template<typename BFI> typename Bigfloat_interval_traits<BFI>::BF
|
||||||
width(BFI bfi) {
|
width(BFI bfi) {
|
||||||
|
|
||||||
typename Bigfloat_interval_traits<BFI>::Width width;
|
typename Bigfloat_interval_traits<BFI>::Width width;
|
||||||
return width(bfi);
|
return width(bfi);
|
||||||
}
|
}
|
||||||
|
|
@ -117,226 +79,23 @@ template<typename BFI> bool singleton(BFI bfi) {
|
||||||
return singleton(bfi);
|
return singleton(bfi);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename NT> typename CGALi::Get_arithmetic_kernel<NT>::Bigfloat_interval
|
template <class NTX> class Get_arithmetic_kernel;
|
||||||
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>
|
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) {
|
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;
|
typedef typename AT::Bigfloat_interval BFI;
|
||||||
typename Bigfloat_interval_traits<BFI>::Convert_to_bfi convert_to_bfi;
|
typename Bigfloat_interval_traits<BFI>::Convert_to_bfi convert_to_bfi;
|
||||||
return convert_to_bfi(x);
|
return convert_to_bfi(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: move this to sqrt_extension ?
|
||||||
|
template <typename A,typename B> class Sqrt_extension;
|
||||||
template <typename NT, typename ROOT>
|
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) {
|
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;
|
typedef typename AT::Bigfloat_interval BFI;
|
||||||
if(x.is_extended()){
|
if(x.is_extended()){
|
||||||
BFI a0(convert_to_bfi(x.a0()));
|
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
|
CGAL_END_NAMESPACE
|
||||||
|
|
||||||
#ifdef CGAL_USE_LEDA
|
#include <CGAL/Arithmetic_kernel.h>
|
||||||
#include <CGAL/leda_interval_support.h>
|
|
||||||
#endif // CGAL_USE_LEDA
|
|
||||||
|
|
||||||
#ifdef CGAL_USE_CORE
|
|
||||||
#include <CGAL/core_interval_support.h>
|
|
||||||
#endif // CGAL_USE_CORE
|
|
||||||
|
|
||||||
#endif // CGAL_INTERVAL_SUPPORT_H
|
#endif // CGAL_INTERVAL_SUPPORT_H
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
// Copyright (c) 1999,2007 Utrecht University (The Netherlands),
|
// Copyright (c) 1999,2007 Utrecht University (The Netherlands),
|
||||||
// ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
|
// ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
|
||||||
// INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
|
// INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
|
||||||
|
|
@ -24,17 +25,14 @@
|
||||||
#ifndef CGAL_LEDA_BIGFLOAT_H
|
#ifndef CGAL_LEDA_BIGFLOAT_H
|
||||||
#define CGAL_LEDA_BIGFLOAT_H
|
#define CGAL_LEDA_BIGFLOAT_H
|
||||||
|
|
||||||
#include <CGAL/number_type_basic.h>
|
#include <CGAL/basic.h>
|
||||||
|
|
||||||
#ifdef CGAL_USE_LEDA
|
#ifdef CGAL_USE_LEDA
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <CGAL/leda_coercion_traits.h>
|
#include <CGAL/leda_coercion_traits.h>
|
||||||
#include <CGAL/Interval_nt.h>
|
#include <CGAL/Interval_nt.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <CGAL/LEDA_basic.h>
|
#include <CGAL/LEDA_basic.h>
|
||||||
#if CGAL_LEDA_VERSION < 500
|
#if CGAL_LEDA_VERSION < 500
|
||||||
#include <LEDA/bigfloat.h>
|
#include <LEDA/bigfloat.h>
|
||||||
|
|
@ -42,8 +40,6 @@
|
||||||
#include <LEDA/numbers/bigfloat.h>
|
#include <LEDA/numbers/bigfloat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <CGAL/Float_traits.h>
|
|
||||||
|
|
||||||
CGAL_BEGIN_NAMESPACE
|
CGAL_BEGIN_NAMESPACE
|
||||||
|
|
||||||
template <> class Algebraic_structure_traits< leda_bigfloat >
|
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
|
CGAL_END_NAMESPACE
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -1,575 +1,261 @@
|
||||||
// TODO: Add licence
|
// TODO:
|
||||||
//
|
// - add to comming interval_traits:
|
||||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
// -- CGAL::median(bf_interval)
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
// -- CGAL::ipower(bf_interval)
|
||||||
//
|
// -- CGAL::relatoive_error(bf_interval)
|
||||||
// $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/leda_interval_support.h
|
/*! \file CGAL/leda_interval_support.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CGAL_LEDA_INTERVAL_SUPPORT_H
|
#ifndef CGAL_LEDA_INTERVAL_SUPPORT_H
|
||||||
#define CGAL_LEDA_INTERVAL_SUPPORT_H
|
#define CGAL_LEDA_INTERVAL_SUPPORT_H
|
||||||
|
|
||||||
#include <CGAL/basic.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_integer.h>
|
||||||
#include <CGAL/leda_rational.h>
|
#include <CGAL/leda_rational.h>
|
||||||
#include <CGAL/leda_real.h>
|
#include <CGAL/leda_real.h>
|
||||||
|
#include <CGAL/leda_bigfloat_interval.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <CGAL/interval_support.h>
|
||||||
|
|
||||||
// namespace NiX {
|
|
||||||
CGAL_BEGIN_NAMESPACE
|
CGAL_BEGIN_NAMESPACE
|
||||||
|
|
||||||
// namespace Intern {
|
template<>
|
||||||
namespace CGALi {
|
class Bigfloat_interval_traits<leda_bigfloat_interval>
|
||||||
|
{
|
||||||
|
|
||||||
struct Rounding_for_leda_bigfloat {
|
|
||||||
private: typedef leda::bigfloat T;
|
|
||||||
public:
|
public:
|
||||||
Rounding_for_leda_bigfloat(){};
|
typedef leda_bigfloat_interval NT;
|
||||||
~Rounding_for_leda_bigfloat(){};
|
|
||||||
|
|
||||||
T conv_down(const T& a){
|
typedef leda::bigfloat BF;
|
||||||
return round(a,leda::bigfloat::get_precision(),leda::TO_N_INF);
|
|
||||||
};
|
class Get_significant_bits {
|
||||||
T conv_up (const T& a){
|
public:
|
||||||
return round(a,leda::bigfloat::get_precision(),leda::TO_P_INF);
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
};
|
typedef NT argument_type;
|
||||||
// mathematical operations
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
T add_down(const T& a, const T& b){
|
typedef long result_type;
|
||||||
return add(a,b,leda::bigfloat::get_precision(),leda::TO_N_INF);
|
|
||||||
};
|
long operator()( NT x) const {
|
||||||
T add_up (const T& a, const T& b){
|
leda::bigfloat lower = x.lower();
|
||||||
return add(a,b,leda::bigfloat::get_precision(),leda::TO_P_INF);
|
leda::bigfloat upper = x.upper();
|
||||||
};
|
|
||||||
T sub_down(const T& a, const T& b){
|
leda::integer lower_m = lower.get_significant();
|
||||||
return sub(a, b, leda::bigfloat::get_precision(),leda::TO_N_INF);
|
leda::integer upper_m = upper.get_significant();
|
||||||
};
|
|
||||||
T sub_up (const T& a, const T& b){
|
leda::integer lower_exp = lower.get_exponent();
|
||||||
return sub(a, b, leda::bigfloat::get_precision(),leda::TO_P_INF);
|
leda::integer upper_exp = upper.get_exponent();
|
||||||
};
|
|
||||||
T mul_down(const T& a, const T& b){
|
long shift = (upper_exp - lower_exp).to_long();
|
||||||
return mul(a, b, leda::bigfloat::get_precision(),leda::TO_N_INF);
|
if(shift >= 0 ) upper_m = (upper_m << shift);
|
||||||
};
|
else lower_m = (lower_m << -shift);
|
||||||
T mul_up (const T& a, const T& b){
|
|
||||||
return mul(a, b, leda::bigfloat::get_precision(),leda::TO_P_INF);
|
//CGAL_postcondition(lower_m.length() == upper_m.length());
|
||||||
};
|
|
||||||
T div_down(const T& a, const T& b){
|
leda::integer err = lower_m-upper_m;
|
||||||
return div(a, b, leda::bigfloat::get_precision(),leda::TO_N_INF);
|
|
||||||
};
|
return std::max(lower_m.length()-err.length(),0);
|
||||||
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; };
|
class Upper {
|
||||||
T int_down(const T& a) { return T(floor(a));};
|
public:
|
||||||
T int_up (const T& a) { return T(ceil(a)); };
|
// 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 {
|
||||||
T exp_down(T);
|
return a.upper();
|
||||||
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]
|
|
||||||
*/
|
|
||||||
|
|
||||||
// unprotected rounding class
|
class Lower {
|
||||||
//typedef ... unprotected_rounding;
|
public:
|
||||||
};
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
|
typedef NT argument_type;
|
||||||
|
// type for the \c AdaptableUnaryFunction concept.
|
||||||
|
typedef BF result_type;
|
||||||
|
|
||||||
class Checking_for_leda_bigfloat {
|
BF operator() ( NT a ) const {
|
||||||
|
return a.lower();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
typedef leda::bigfloat T;
|
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:
|
public:
|
||||||
|
|
||||||
static T pos_inf() {
|
typedef NT result_type;
|
||||||
T b = T(5) / T(0);
|
|
||||||
CGAL_assertion(leda::ispInf(b));
|
NT operator() ( const leda::real& x ) {
|
||||||
return b;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static T neg_inf() {
|
|
||||||
T b = T(-5) / T(0);
|
NT operator() (const ::leda::integer& x) {
|
||||||
CGAL_assertion(leda::isnInf(b));
|
long current_prec = ::leda::bigfloat::get_precision();
|
||||||
return b;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static T nan() {
|
|
||||||
T b = T(0)*pos_inf();
|
NT operator() (const ::leda::rational& x) {
|
||||||
CGAL_assertion(leda::isNaN(b));
|
long old_prec = ::leda::bigfloat::get_precision();
|
||||||
return b;
|
::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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// left overs?
|
||||||
// } // 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
::leda::bigfloat inline median(const leda_bigfloat_interval& x){
|
::leda::bigfloat inline median(const leda_bigfloat_interval& x){
|
||||||
return ::boost::numeric::median(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){
|
::leda::bigfloat inline relative_error(const leda_bigfloat_interval& x){
|
||||||
if(in_zero(x)){
|
if(in_zero(x)){
|
||||||
return CGAL::abs(x).upper();
|
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
|
CGAL_END_NAMESPACE
|
||||||
|
#endif // CGAL_USE_LEDA
|
||||||
|
|
||||||
#endif // CGAL_LEDA_INTERVAL_SUPPORT_H
|
#endif // CGAL_LEDA_INTERVAL_SUPPORT_H
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue