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/fundamental_types.tex -text
|
||||
Number_types/doc_tex/NumberTypeSupport_ref/open.tex -text
|
||||
Number_types/include/CGAL/Float_traits.h -text
|
||||
Number_types/include/CGAL/Number_types/core_interval_support.h -text
|
||||
Number_types/include/CGAL/Sqrt_extension/Algebraic_extension_traits.h -text
|
||||
Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h -text
|
||||
|
|
|
|||
|
|
@ -33,10 +33,7 @@
|
|||
#include <CGAL/leda_bigfloat.h>
|
||||
#include <CGAL/leda_real.h>
|
||||
|
||||
// #ifdef CGAL_INTERN_USE_BFI
|
||||
// #include <CGAL/Algebraic_kernel_d/leda_interval_support.h>
|
||||
#include <CGAL/leda_interval_support.h>
|
||||
// #endif //CGAL_INTERN_USE_BFI
|
||||
|
||||
#endif // CGAL_USE_LEDA
|
||||
|
||||
|
|
@ -77,12 +74,9 @@ public:
|
|||
//! exact root expressions, constructible from integers and rationals
|
||||
typedef leda_real Field_with_sqrt;
|
||||
|
||||
// #ifdef CGAL_INTERN_USE_BFI
|
||||
// undocumented
|
||||
typedef leda_bigfloat Bigfloat;
|
||||
// typedef CGALi::leda_bigfloat_interval Bigfloat_interval;
|
||||
typedef leda_bigfloat_interval Bigfloat_interval;
|
||||
// #endif //CGAL_INTERN_USE_BFI
|
||||
|
||||
};
|
||||
#endif // CGAL_USE_LEDA
|
||||
|
|
@ -101,11 +95,9 @@ public:
|
|||
typedef CORE::BigRat Rational;
|
||||
//! exact root expressions, constructible from integers and rationals
|
||||
typedef CORE::Expr Field_with_sqrt;
|
||||
// #ifdef CGAL_INTERN_USE_BFI
|
||||
// undocumented
|
||||
typedef CORE::BigFloat Bigfloat;
|
||||
typedef CORE::BigFloat Bigfloat_interval;
|
||||
// #endif //CGAL_INTERN_USE_BFI
|
||||
|
||||
};
|
||||
#endif // CGAL_USE_CORE
|
||||
|
|
@ -164,42 +156,10 @@ typedef LEDA_arithmetic_kernel Arithmetic_kernel;
|
|||
typedef typename AT::Integer Integer; \
|
||||
typedef typename AT::Rational Rational; \
|
||||
typedef typename AT::Field_with_sqrt Field_with_sqrt;
|
||||
// typedef typename AT::Poly_int1 Poly_int1;
|
||||
// typedef typename AT::Poly_int2 Poly_int2;
|
||||
// typedef typename AT::Poly_int3 Poly_int3;
|
||||
// typedef typename AT::Poly_rat1 Poly_rat1;
|
||||
// typedef typename AT::Poly_rat2 Poly_rat2;
|
||||
// typedef typename AT::Poly_rat3 Poly_rat3;
|
||||
|
||||
// end #define
|
||||
|
||||
template <class NT>
|
||||
class Lazy_exact_nt;
|
||||
|
||||
|
||||
namespace INTERN_AK{
|
||||
template <class NT>
|
||||
struct Lazy_exact_type{
|
||||
typedef CGAL::Lazy_exact_nt<NT> type;
|
||||
};
|
||||
template <>
|
||||
struct Lazy_exact_type<CGAL::Null_tag>{
|
||||
typedef CGAL::Null_tag type;
|
||||
};
|
||||
} // namespace INTERN_AK
|
||||
|
||||
template <class AT>
|
||||
struct Lazy_exact_arithmetic_kernel{
|
||||
typedef typename INTERN_AK::Lazy_exact_type<typename AT::Integer>::type Integer;
|
||||
typedef typename INTERN_AK::Lazy_exact_type<typename AT::Exact_float_number>::type Exact_float_number;
|
||||
typedef typename INTERN_AK::Lazy_exact_type<typename AT::Rational>::type Rational;
|
||||
typedef typename INTERN_AK::Lazy_exact_type<typename AT::Field_with_sqrt>::type Field_with_sqrt;
|
||||
};
|
||||
|
||||
|
||||
// #ifdef CGAL_INTERN_USE_BFI
|
||||
|
||||
namespace CGALi {
|
||||
template< class NT > struct Get_arithmetic_kernel;
|
||||
|
||||
#ifdef CGAL_USE_LEDA
|
||||
|
|
@ -216,6 +176,14 @@ template< class NT > struct Get_arithmetic_kernel;
|
|||
struct Get_arithmetic_kernel<leda::real>{
|
||||
typedef LEDA_arithmetic_kernel Arithmetic_kernel;
|
||||
};
|
||||
template <>
|
||||
struct Get_arithmetic_kernel<leda::bigfloat>{
|
||||
typedef LEDA_arithmetic_kernel Arithmetic_kernel;
|
||||
};
|
||||
template <>
|
||||
struct Get_arithmetic_kernel<CGAL::leda_bigfloat_interval>{
|
||||
typedef LEDA_arithmetic_kernel Arithmetic_kernel;
|
||||
};
|
||||
#endif //CGAL_USE_LEDA
|
||||
|
||||
|
||||
|
|
@ -233,6 +201,10 @@ template< class NT > struct Get_arithmetic_kernel;
|
|||
struct Get_arithmetic_kernel<CORE::Expr>{
|
||||
typedef CORE_arithmetic_kernel Arithmetic_kernel;
|
||||
};
|
||||
template <>
|
||||
struct Get_arithmetic_kernel<CORE::BigFloat>{
|
||||
typedef CORE_arithmetic_kernel Arithmetic_kernel;
|
||||
};
|
||||
#endif //CGAL_USE_CORE
|
||||
|
||||
template <class COEFF, class ROOT>
|
||||
|
|
@ -241,10 +213,6 @@ template< class NT > struct Get_arithmetic_kernel;
|
|||
typedef typename GET::Arithmetic_kernel Arithmetic_kernel;
|
||||
};
|
||||
|
||||
|
||||
} // namespace CGALi
|
||||
// #endif //CGAL_INTERN_USE_BFI
|
||||
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
|
|
|
|||
|
|
@ -17,51 +17,19 @@
|
|||
//
|
||||
//
|
||||
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
|
||||
//============================================================================
|
||||
|
||||
#ifndef CGAL_CORE_BIGFLOAT_H
|
||||
#define CGAL_CORE_BIGFLOAT_H
|
||||
|
||||
#include <CGAL/number_type_basic.h>
|
||||
#include <CGAL/CORE_coercion_traits.h>
|
||||
#include <CGAL/Float_traits.h>
|
||||
#include <CGAL/core_interval_support.h>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
//template<typename BFI> class Bigfloat_interval_traits;
|
||||
|
||||
// forward declarations of interval support
|
||||
// namespace CGALi {
|
||||
CORE::BigFloat
|
||||
inline
|
||||
round(const CORE::BigFloat& x, long rel_prec );
|
||||
|
||||
//TODO
|
||||
// functions: upper and lower are defined twice the time,
|
||||
// please correct this unaesthetic thing
|
||||
CORE::BigFloat
|
||||
inline
|
||||
upper(CORE::BigFloat x){
|
||||
CORE::BigFloat result = ::CORE::BigFloat(x.m()+x.err(),0,x.exp());
|
||||
CGAL_postcondition(result >= x);
|
||||
return result;
|
||||
}
|
||||
|
||||
CORE::BigFloat
|
||||
inline
|
||||
lower(CORE::BigFloat x){
|
||||
CORE::BigFloat result = ::CORE::BigFloat(x.m()-x.err(),0,x.exp());
|
||||
CGAL_postcondition(result <= x);
|
||||
return result;
|
||||
}
|
||||
// CORE::BigFloat
|
||||
// inline
|
||||
// upper(CORE::BigFloat x);
|
||||
//
|
||||
// CORE::BigFloat
|
||||
// inline
|
||||
// lower(CORE::BigFloat x);
|
||||
|
||||
// } // namespace CGALi
|
||||
|
||||
//
|
||||
// Algebraic structure traits
|
||||
|
|
@ -94,14 +62,9 @@ template <> class Algebraic_structure_traits< CORE::BigFloat >
|
|||
Type result = tmp1*CORE::BigFloat::exp2(a.exp()*7) + err;
|
||||
|
||||
CGAL_postcondition(result >= 0);
|
||||
//#ifndef NDEBUG
|
||||
// Type tmp = result * result;
|
||||
// typedef Bigfloat_interval_traits<CORE::BigFloat> bfi_traits;
|
||||
//bfi_traits::Upper upper;
|
||||
//bfi_traits::Lower lower;
|
||||
// CGAL_postcondition(NiX::lower(tmp) <= NiX::lower(x));
|
||||
// CGAL_postcondition(NiX::upper(tmp) >= NiX::upper(x));
|
||||
//#endif
|
||||
CGAL_postcondition(CGAL::lower(result*result) <= CGAL::lower(x));
|
||||
CGAL_postcondition(CGAL::upper(result*result) >= CGAL::upper(x));
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
|
@ -118,7 +81,6 @@ template <> class Algebraic_structure_traits< CORE::BigFloat >
|
|||
return Type(-CORE::radical( -x, k ) );
|
||||
}
|
||||
|
||||
|
||||
return Type( CORE::radical( x, k ) );
|
||||
}
|
||||
};
|
||||
|
|
@ -217,426 +179,8 @@ template <> class Real_embeddable_traits< CORE::BigFloat >
|
|||
};
|
||||
};
|
||||
|
||||
//**********************NEW**********************
|
||||
|
||||
// Specialization of CGAL::Float_traits_kernel for CORE::BigFloat
|
||||
|
||||
template <> class Float_traits_kernel< ::CORE::BigFloat > {
|
||||
public:
|
||||
typedef ::CORE::BigFloat FT;
|
||||
typedef ::CORE::BigInt IT;
|
||||
typedef ::CGAL::Float_number_tag Float_type;
|
||||
typedef CGAL::Precision_type Precision_type;
|
||||
|
||||
class Get_precision {
|
||||
public:
|
||||
typedef CGAL::Precision_type result_type;
|
||||
|
||||
CGAL::Precision_type operator()() const {
|
||||
return CGAL::Precision_type( ::CORE::defRelPrec.toLong());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class Set_precision {
|
||||
public:
|
||||
typedef void result_type;
|
||||
typedef CGAL::Precision_type first_argument_type;
|
||||
|
||||
void operator()( const CGAL::Precision_type& precision ) const {
|
||||
::CORE::defRelPrec = precision;
|
||||
::CORE::defBFdivRelPrec = precision;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class Get_rounding_mode {
|
||||
public:
|
||||
typedef CGAL::Rounding_mode result_type;
|
||||
|
||||
/*??
|
||||
CGAL::Rounding_mode operator()() const {
|
||||
return CGAL::Rounding_mode( CORE::BigFloat::get_rounding_mode() );
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
class Set_rounding_mode {
|
||||
public:
|
||||
typedef void result_type;
|
||||
typedef CGAL::Rounding_mode first_argument_type;
|
||||
|
||||
/* ??
|
||||
void operator()( const CGAL::Rounding_mode& rounding_mode ) const {
|
||||
CORE::BigFloat::set_rounding_mode( (CORE::rounding_modes)rounding_mode );
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Specialization of CGAL::Float_traits for CORE::BigFloat
|
||||
|
||||
template <> class Float_traits< ::CORE::BigFloat >
|
||||
: public Float_traits_base< Float_traits_kernel< ::CORE::BigFloat> > {
|
||||
|
||||
private:
|
||||
/* ??
|
||||
static Rounding_mode get_rounding_mode() {
|
||||
return Rounding_mode( CORE::BigFloat::get_rounding_mode() );
|
||||
};
|
||||
*/
|
||||
|
||||
static Precision_type get_precision() {
|
||||
return Precision_type( ::CORE::defRelPrec.toLong() );
|
||||
};
|
||||
|
||||
public:
|
||||
typedef Float_traits_kernel< CORE::BigFloat > FT_kernel;
|
||||
typedef FT_kernel::FT FT;
|
||||
typedef FT_kernel::IT IT;
|
||||
typedef FT_kernel::Float_type Float_type;
|
||||
|
||||
class Construct
|
||||
: public Float_traits_base< FT_kernel >::Construct {
|
||||
public:
|
||||
FT operator() ( const IT& m, const IT& e = IT(0) ) {
|
||||
return FT(m,0,0)*FT::exp2(e.intValue());
|
||||
}
|
||||
}; // class Constructor
|
||||
|
||||
class Set_precision {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator() ( long prec ) const {
|
||||
FT_kernel::Set_precision set_precision;
|
||||
FT_kernel::Get_precision get_precision;
|
||||
long old_precision = get_precision();
|
||||
set_precision(prec);
|
||||
return old_precision;
|
||||
}
|
||||
};
|
||||
|
||||
class Get_precision {
|
||||
public:
|
||||
// type for the \c AdaptableGenerator concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator() () const {
|
||||
FT_kernel::Get_precision get_precision;
|
||||
return get_precision();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
class Construct_special_value {
|
||||
public:
|
||||
FT operator()( const Special_value& sv ) {
|
||||
switch( sv ) {
|
||||
case SV_N_ZERO: return leda::bigfloat::nZero;
|
||||
case SV_P_ZERO: return leda::bigfloat::pZero;
|
||||
case SV_N_INF: return leda::bigfloat::nInf;
|
||||
case SV_P_INF: return leda::bigfloat::pInf;
|
||||
case SV_NAN: return leda::bigfloat::NaN;
|
||||
default: return FT(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
/* ??
|
||||
class Is_special_value {
|
||||
public:
|
||||
bool operator()( const FT& bf ) const {
|
||||
return leda::isSpecial( bf );
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
/* ??
|
||||
class Get_special_value {
|
||||
public:
|
||||
Special_value operator()( const FT& bf ) const {
|
||||
if( leda::isNaN( bf ) )
|
||||
return SV_NAN;
|
||||
else if( leda::isnZero( bf ) )
|
||||
return SV_N_ZERO;
|
||||
else if( leda::ispZero( bf ) )
|
||||
return SV_P_ZERO;
|
||||
else if( leda::isnInf( bf ) )
|
||||
return SV_N_INF;
|
||||
else if( leda::ispInf( bf ) )
|
||||
return SV_P_INF;
|
||||
else
|
||||
return SV_NONE;
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
class Is_zero {
|
||||
public:
|
||||
bool operator()( const FT& bf ) const {
|
||||
CGAL_precondition(bf.isExact());
|
||||
return bf == FT(0);
|
||||
}
|
||||
};
|
||||
|
||||
/* ??
|
||||
class Is_inf {
|
||||
public:
|
||||
bool operator()( const FT& bf ) const {
|
||||
return leda::isInf( bf );
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
class Get_mantissa
|
||||
: public Float_traits_base< FT_kernel >::Get_mantissa {
|
||||
public:
|
||||
//! type for the \c AdaptableUnaryFunction concept.
|
||||
typedef IT result_type;
|
||||
//! type for the \c AdaptableUnaryFunction concept.
|
||||
typedef FT argument_type;
|
||||
IT operator()( const FT& a ) const {
|
||||
return a.m();
|
||||
}
|
||||
}; // class GetMantissa
|
||||
|
||||
class Get_exponent
|
||||
: public Float_traits_base< FT_kernel >::Get_exponent {
|
||||
public:
|
||||
//! type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long result_type;
|
||||
//! type for the \c AdaptableUnaryFunction concept.
|
||||
typedef FT argument_type;
|
||||
|
||||
result_type operator()( const FT& a ) const {
|
||||
return 14*a.exp(); // The basis is 8092
|
||||
}
|
||||
}; // class GetExponent
|
||||
|
||||
class Get_mantissa_and_exponent
|
||||
: public Float_traits_base< FT_kernel >::Get_mantissa_and_exponent {
|
||||
public:
|
||||
//! type for the \c AdaptableUnaryFunction concept.
|
||||
typedef std::pair< IT, long > result_type;
|
||||
//! type for the \c AdaptableUnaryFunction concept.
|
||||
typedef FT argument_type;
|
||||
|
||||
result_type operator()( const FT& a ) const {
|
||||
IT m = a.m();
|
||||
long e = 14*a.exp();
|
||||
result_type p( m, e );
|
||||
|
||||
return p;
|
||||
}
|
||||
}; // class GetMantissaAndExponent
|
||||
|
||||
/* ??
|
||||
class Round_relative
|
||||
: public Float_traits_base< FT_kernel >::Round_relative {
|
||||
public:
|
||||
//! type for the \c AdaptableTernaryFunction concept.
|
||||
typedef FT result_type;
|
||||
//! type for the \c AdaptableTernaryFunction concept.
|
||||
typedef FT first_argument_type;
|
||||
//! type for the \c AdaptableTernaryFunction concept.
|
||||
typedef CGAL::Precision_type second_argument_type;
|
||||
//! type for the \c AdaptableTernaryFunction concept.
|
||||
typedef CGAL::Rounding_mode third_argument_type;
|
||||
|
||||
FT operator()( const FT& a,
|
||||
const CGAL::Precision_type& p = get_precision(),
|
||||
const CGAL::Rounding_mode& m = get_rounding_mode() ) const {
|
||||
return leda::round(a,(leda::sz_t)p,(leda::rounding_modes)m ) ;
|
||||
}
|
||||
}; // class Round
|
||||
|
||||
*/
|
||||
|
||||
/* ??
|
||||
class Round_absolute : public Float_traits_base< FT_kernel >::Round_absolute {
|
||||
public:
|
||||
//! type for the \c AdaptableTernaryFunction concept.
|
||||
typedef FT result_type;
|
||||
//! type for the \c AdaptableTernaryFunction concept.
|
||||
typedef FT first_argument_type;
|
||||
//! type for the \c AdaptableTernaryFunction concept.
|
||||
typedef IT second_argument_type;
|
||||
//! type for the \c AdaptableTernaryFunction concept.
|
||||
typedef CGAL::Rounding_mode third_argument_type;
|
||||
|
||||
FT operator()( const FT& a,
|
||||
const IT& new_exponent,
|
||||
const CGAL::Rounding_mode& r_mode = get_rounding_mode() ) const {
|
||||
typedef CGAL::Float_number<IT> FN;
|
||||
FN fn( a.get_significant(), a.get_exponent() );
|
||||
fn = fn.round_absolute( new_exponent, r_mode );
|
||||
return FT( fn.get_mantissa(), fn.get_exponent() );
|
||||
}
|
||||
};
|
||||
*/
|
||||
// special functors ( only for Big_float )
|
||||
|
||||
/* ??
|
||||
class Add
|
||||
: public Float_traits_base< FT_kernel >::Add {
|
||||
public:
|
||||
typedef FT result_type;
|
||||
typedef FT first_argument_type;
|
||||
typedef FT second_argument_type;
|
||||
typedef CGAL::Rounding_mode third_argument_type;
|
||||
typedef CGAL::Precision_type fourth_argument_type;
|
||||
|
||||
FT operator()( const FT& a, const FT& b,
|
||||
const Rounding_mode& m = get_rounding_mode(),
|
||||
const Precision_type& p = get_precision() ) const {
|
||||
return leda::add(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
|
||||
}
|
||||
}; // class Add
|
||||
|
||||
class Sub
|
||||
: public Float_traits_base< FT_kernel >::Sub{
|
||||
public:
|
||||
typedef FT result_type;
|
||||
typedef FT first_argument_type;
|
||||
typedef FT second_argument_type;
|
||||
typedef CGAL::Rounding_mode third_argument_type;
|
||||
typedef CGAL::Precision_type fourth_argument_type;
|
||||
|
||||
FT operator()( const FT& a, const FT& b ,
|
||||
const Rounding_mode& m = get_rounding_mode(),
|
||||
const Precision_type& p = get_precision() ) const {
|
||||
return leda::sub(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
|
||||
}
|
||||
}; // class Sub
|
||||
|
||||
|
||||
class Mul
|
||||
: public Float_traits_base< FT_kernel >::Mul {
|
||||
public:
|
||||
typedef FT result_type;
|
||||
typedef FT first_argument_type;
|
||||
typedef FT second_argument_type;
|
||||
typedef CGAL::Rounding_mode third_argument_type;
|
||||
typedef CGAL::Precision_type fourth_argument_type;
|
||||
|
||||
FT operator()( const FT& a, const FT& b ,
|
||||
const Rounding_mode& m = get_rounding_mode(),
|
||||
const Precision_type& p = get_precision() ) const {
|
||||
return leda::mul(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
|
||||
}
|
||||
}; // class Mul
|
||||
|
||||
class Div
|
||||
: public Float_traits_base< FT_kernel >::Div{
|
||||
public:
|
||||
typedef FT result_type;
|
||||
typedef FT first_argument_type;
|
||||
typedef FT second_argument_type;
|
||||
typedef CGAL::Rounding_mode third_argument_type;
|
||||
typedef CGAL::Precision_type fourth_argument_type;
|
||||
|
||||
FT operator()( const FT& a, const FT& b ,
|
||||
const Rounding_mode& m = get_rounding_mode(),
|
||||
const Precision_type& p = get_precision() ) const {
|
||||
return leda::div(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
|
||||
}
|
||||
}; // class Div
|
||||
|
||||
class Sqrt
|
||||
: public Float_traits_base< FT_kernel >::Sqrt{
|
||||
public:
|
||||
typedef FT result_type;
|
||||
typedef FT first_argument_type;
|
||||
typedef CGAL::Rounding_mode second_argument_type;
|
||||
typedef CGAL::Precision_type third_argument_type;
|
||||
|
||||
FT operator()( const FT& bf,
|
||||
const Rounding_mode& r_mode = get_rounding_mode(),
|
||||
const Precision_type& prec = get_precision() ) const {
|
||||
return leda::sqrt( bf, (leda::sz_t)prec, (leda::rounding_modes)r_mode);
|
||||
}
|
||||
}; // class Sqrt
|
||||
|
||||
*/
|
||||
|
||||
class Mul_by_pow_of_2
|
||||
: public Float_traits_base< FT_kernel >::Mul_by_pow_of_2{
|
||||
public:
|
||||
//! type for the \c AdaptableBinaryFunction concept.
|
||||
typedef FT result_type;
|
||||
//! type for the \c AdaptableBinaryFunction concept.
|
||||
typedef FT first_argument_type;
|
||||
//! type for the \c AdaptableBinaryFunction concept.
|
||||
typedef IT second_argument_type;
|
||||
|
||||
FT operator()( const FT& a, const IT& e ) const {
|
||||
return a*FT::exp2(e.intValue());
|
||||
}
|
||||
}; // class Mul_by_pow_of_2
|
||||
|
||||
class Div_by_pow_of_2
|
||||
: public Float_traits_base< FT_kernel >::Div_by_pow_of_2{
|
||||
public:
|
||||
//! type for the \c AdaptableBinaryFunction concept.
|
||||
typedef FT result_type;
|
||||
//! type for the \c AdaptableBinaryFunction concept.
|
||||
typedef FT first_argument_type;
|
||||
//! type for the \c AdaptableBinaryFunction concept.
|
||||
typedef IT second_argument_type;
|
||||
|
||||
FT operator()( const FT& a, const IT& e ) const {
|
||||
return a*FT::exp2(-e.intValue());
|
||||
}
|
||||
}; // class Div_by_pow_of_2
|
||||
|
||||
class Floor {
|
||||
public:
|
||||
typedef IT result_type;
|
||||
typedef FT argument_type;
|
||||
|
||||
IT operator()( const FT& fn ) const {
|
||||
IT fl = fn.BigIntValue();
|
||||
if(fn.sign() < 0 && fn.cmp(fl)!=0) {
|
||||
fl--;
|
||||
}
|
||||
return fl;
|
||||
}
|
||||
};
|
||||
|
||||
class Ceil {
|
||||
public:
|
||||
typedef IT result_type;
|
||||
typedef FT argument_type;
|
||||
|
||||
IT operator()( const FT& fn ) const {
|
||||
IT fl = fn.BigIntValue();
|
||||
if(fn.sign() >0 && fn.cmp(fl)!=0) {
|
||||
fl++;
|
||||
}
|
||||
return fl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
//**********************NEW**********************
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
// #include <CGAL/Number_types/core_interval_support.h>
|
||||
#include <CGAL/core_interval_support.h>
|
||||
|
||||
//since types are included by CORE_coercion_traits.h:
|
||||
#include <CGAL/CORE_Expr.h>
|
||||
#include <CGAL/CORE_BigInt.h>
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
//
|
||||
// $URL:$
|
||||
// $Id: 4515 rschindl$
|
||||
// $Id:$
|
||||
//
|
||||
//
|
||||
// Author(s) : Ralf Schindlbeck <rschindl@mpi-inf.mpg.de>
|
||||
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
// TODO: The comments are all original EXACUS comments and aren't adapted. So
|
||||
// they may be wrong now.
|
||||
|
||||
|
||||
|
||||
/*! \file CGAL/core_interval_support.h
|
||||
This is experimental
|
||||
use CORE::BigFloat as interval type.
|
||||
*/
|
||||
|
||||
// TODO:
|
||||
// - mv general functors in a new Interval_traits
|
||||
// - mv function 'round' to Interval_traits
|
||||
|
||||
#ifndef CGAL_CORE_INTERVAL_SUPPORT_H
|
||||
#define CGAL_CORE_INTERVAL_SUPPORT_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/interval_support.h>
|
||||
|
||||
#ifndef CGAL_USE_CORE
|
||||
#warning This header file needs CORE installed in order to work properly.
|
||||
#else // CGAL_USE_CORE
|
||||
|
||||
//#include <NiX/CORE/BigFloat.h>
|
||||
//#include <NiX/CORE/Expr.h>
|
||||
//#include <NiX/CORE/BigInt.h>
|
||||
//#include <NiX/CORE/BigRat.h>
|
||||
|
||||
#include <CGAL/CORE/BigFloat.h>
|
||||
|
||||
// namespace NiX{
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template<typename BFI> long get_significant_bits(BFI bfi);
|
||||
|
||||
CORE::BigFloat
|
||||
inline
|
||||
round(const CORE::BigFloat& x, long rel_prec = CORE::defRelPrec.toLong() ){
|
||||
CGAL_postcondition(rel_prec >= 0);
|
||||
// since there is not rel prec defined if in_zero(x)
|
||||
if (x.isZeroIn()) return x;
|
||||
if (CGAL::get_significant_bits(x) <= rel_prec) return x;
|
||||
CORE::BigFloat
|
||||
inline
|
||||
round(const CORE::BigFloat& x, long rel_prec = CORE::defRelPrec.toLong() ){
|
||||
CGAL_postcondition(rel_prec >= 0);
|
||||
// since there is not rel prec defined if in_zero(x)
|
||||
if (x.isZeroIn()) return x;
|
||||
if (CGAL::get_significant_bits(x) <= rel_prec) return x;
|
||||
|
||||
typedef CORE::BigFloat BF;
|
||||
typedef CORE::BigFloat BFI;
|
||||
typedef CORE::BigInt Integer;
|
||||
BF xr;
|
||||
typedef CORE::BigFloat BF;
|
||||
typedef CORE::BigFloat BFI;
|
||||
typedef CORE::BigInt Integer;
|
||||
BF xr;
|
||||
|
||||
CORE::BigInt m = x.m();
|
||||
long err = x.err();
|
||||
long exp = x.exp();
|
||||
CORE::BigInt m = x.m();
|
||||
long err = x.err();
|
||||
long exp = x.exp();
|
||||
|
||||
long shift = ::CORE::bitLength(m) - rel_prec - 1;
|
||||
if( shift > 0 ){
|
||||
Integer new_m = m >> shift ;
|
||||
long shift = ::CORE::bitLength(m) - rel_prec - 1;
|
||||
if( shift > 0 ){
|
||||
Integer new_m = m >> shift ;
|
||||
if(err == 0){
|
||||
xr = BF(new_m,1,0)*BF::exp2(exp*14+shift);
|
||||
}else{
|
||||
|
|
@ -79,211 +67,218 @@ template<typename BFI> long get_significant_bits(BFI bfi);
|
|||
return xr;
|
||||
}
|
||||
|
||||
template<typename BFI> class Bigfloat_interval_traits;
|
||||
|
||||
template<> class Bigfloat_interval_traits<CORE::BigFloat>
|
||||
{
|
||||
public:
|
||||
typedef CORE::BigFloat NT;
|
||||
typedef CORE::BigFloat BF;
|
||||
|
||||
{
|
||||
public:
|
||||
typedef CORE::BigFloat NT;
|
||||
typedef CORE::BigFloat BF;
|
||||
typedef Bigfloat_interval_traits<NT> Self;
|
||||
|
||||
typedef Bigfloat_interval_traits<NT> Self;
|
||||
class Get_significant_bits {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long result_type;
|
||||
|
||||
class Get_significant_bits {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator()( NT x) const {
|
||||
//std::cout << ":::::::::::::::::::: "<< std::endl;
|
||||
if(x.err() == 0 ) {
|
||||
//std::cout << "Exact: \n" << x.m() << std::endl;
|
||||
return ::CORE::bitLength(x.m());
|
||||
}
|
||||
else {
|
||||
//std::cout << "With error:\n" << x.m() << std::endl << x.err() << std::endl;
|
||||
//std::cout << "bitlength m: " << ::CORE::bitLength(x.m()) << "\nbitlength e: " << ::CORE::bitLength(x.err()) << std::endl;
|
||||
return ::CORE::bitLength(x.m()) - ::CORE::bitLength(x.err());
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class Set_precision {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long result_type;
|
||||
long operator()( NT x) const {
|
||||
if(x.err() == 0 ) {
|
||||
return ::CORE::bitLength(x.m());
|
||||
}
|
||||
else {
|
||||
return ::CORE::bitLength(x.m()) - ::CORE::bitLength(x.err());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Set_precision {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator() ( long prec ) const {
|
||||
long result = ::CORE::defRelPrec.toLong();
|
||||
::CORE::defRelPrec = prec;
|
||||
::CORE::defBFdivRelPrec = prec;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
long operator() ( long prec ) const {
|
||||
long result = ::CORE::defRelPrec.toLong();
|
||||
::CORE::defRelPrec = prec;
|
||||
::CORE::defBFdivRelPrec = prec;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
class Get_precision {
|
||||
public:
|
||||
// type for the \c AdaptableGenerator concept.
|
||||
typedef long result_type;
|
||||
class Get_precision {
|
||||
public:
|
||||
// type for the \c AdaptableGenerator concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator() () const {
|
||||
return ::CORE::defRelPrec.toLong();
|
||||
}
|
||||
};
|
||||
|
||||
class Upper {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
long operator() () const {
|
||||
return ::CORE::defRelPrec.toLong();
|
||||
}
|
||||
};
|
||||
|
||||
class Upper {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
|
||||
BF operator() ( NT x ) const {
|
||||
CORE::BigFloat result = ::CORE::BigFloat(x.m()+x.err(),0,x.exp());
|
||||
CGAL_postcondition(result >= x);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
BF operator() ( NT x ) const {
|
||||
CORE::BigFloat result = ::CORE::BigFloat(x.m()+x.err(),0,x.exp());
|
||||
CGAL_postcondition(result >= x);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
class Lower {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
class Lower {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
|
||||
BF operator() ( NT x ) const {
|
||||
CORE::BigFloat result = ::CORE::BigFloat(x.m()-x.err(),0,x.exp());
|
||||
CGAL_postcondition(result <= x);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
BF operator() ( NT x ) const {
|
||||
CORE::BigFloat result = ::CORE::BigFloat(x.m()-x.err(),0,x.exp());
|
||||
CGAL_postcondition(result <= x);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class In_zero {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef bool result_type;
|
||||
class In_zero {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator() ( NT x ) const {
|
||||
return x.isZeroIn();
|
||||
}
|
||||
};
|
||||
bool operator() ( NT x ) const {
|
||||
return x.isZeroIn();
|
||||
}
|
||||
};
|
||||
|
||||
class Overlap {
|
||||
public:
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT first_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT second_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef bool result_type;
|
||||
class Overlap {
|
||||
public:
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT first_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT second_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator() ( NT x, NT y ) const {
|
||||
Self::In_zero in_zero;
|
||||
bool result = in_zero(x-y);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
bool operator() ( NT x, NT y ) const {
|
||||
Self::In_zero in_zero;
|
||||
bool result = in_zero(x-y);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
class Hull {
|
||||
public:
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT first_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT second_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT result_type;
|
||||
class Hull {
|
||||
public:
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT first_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT second_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT result_type;
|
||||
|
||||
NT operator() ( NT x, NT y ) const {
|
||||
CORE::BigFloat result;
|
||||
NT operator() ( NT x, NT y ) const {
|
||||
#if 0
|
||||
// this is not possible since CORE::centerize has a bug.
|
||||
NT result = CORE::centerize(x,y);
|
||||
#else
|
||||
|
||||
CORE::BigFloat result;
|
||||
|
||||
// Unfortunately, CORE::centerize(x,y) has bugs.
|
||||
if ((x.m() == y.m()) && (x.err() == y.err()) &&
|
||||
(x.exp() == y.exp())) {
|
||||
|
||||
//rep(x) == rep(y)
|
||||
return x;
|
||||
}
|
||||
Self::Lower lower_functor;
|
||||
Self::Upper upper_functor;
|
||||
CORE::BigFloat lower = std::min(lower_functor(x),
|
||||
lower_functor(y));
|
||||
CORE::BigFloat upper = std::max(upper_functor(x),
|
||||
upper_functor(y));
|
||||
CORE::BigFloat mid = (lower + upper)/2;
|
||||
CORE::BigFloat err = CGAL::round((upper - lower)/2,0);
|
||||
err = CORE::BigFloat(0,err.m().longValue()+err.err(),err.exp());
|
||||
result = mid + err;
|
||||
// Unfortunately, CORE::centerize(x,y) has bugs.
|
||||
if ((x.m() == y.m()) && (x.err() == y.err()) && (x.exp() == y.exp())) {
|
||||
return x;
|
||||
}
|
||||
|
||||
CORE::BigFloat lower = std::min(CGAL::lower(x),
|
||||
CGAL::lower(y));
|
||||
CORE::BigFloat upper = std::max(CGAL::upper(x),
|
||||
CGAL::upper(y));
|
||||
|
||||
CORE::BigFloat mid = (lower + upper)/2;
|
||||
|
||||
CGAL_postcondition(lower_functor(result) <=
|
||||
std::min(lower_functor(x),
|
||||
lower_functor(y)));
|
||||
CGAL_postcondition(upper_functor(result) >=
|
||||
std::max(upper_functor(x),
|
||||
upper_functor(y)));
|
||||
return result ;
|
||||
}
|
||||
};
|
||||
|
||||
class Singleton {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator() ( NT x ) const {
|
||||
return (x.err() == 0);
|
||||
}
|
||||
};
|
||||
|
||||
class Width {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
|
||||
BF operator() ( NT x ) const {
|
||||
unsigned long err = 2*x.err();
|
||||
return BF(CORE::BigInt(err),0,x.exp());
|
||||
}
|
||||
};
|
||||
|
||||
class Convert_to_bfi {
|
||||
public:
|
||||
|
||||
typedef NT result_type;
|
||||
// Now we have to compute the error. The problem is that .err() is just a long
|
||||
CORE::BigFloat err = (upper - lower)/CORE::BigFloat(2);
|
||||
|
||||
//std::cout << "lower " << lower << std::endl;
|
||||
//std::cout << "upper " << upper << std::endl;
|
||||
//std::cout << "mid " << mid << std::endl;
|
||||
//std::cout << "err I " << err << std::endl;
|
||||
|
||||
// shift such that err.m()+err.err() fits into long
|
||||
int digits_long = std::numeric_limits<long>::digits;
|
||||
if(::CORE::bitLength(err.m()) >= digits_long){
|
||||
long shift = ::CORE::bitLength(err.m()) - digits_long + 1 ;
|
||||
//std::cout << "shift " << shift<< std::endl;
|
||||
long new_err = (err.m()+err.err() >> shift).longValue()+1;
|
||||
err = CORE::BigFloat(0,new_err,0) * CORE::BigFloat::exp2(err.exp()*14+shift);
|
||||
}else{
|
||||
err = CORE::BigFloat(0,err.m().longValue()+err.err(),err.exp());
|
||||
}
|
||||
|
||||
result = mid + err;
|
||||
|
||||
NT operator() (const ::CORE::Expr& x){
|
||||
return round(CORE::BigFloat(x));
|
||||
}
|
||||
#endif
|
||||
CGAL_postcondition(
|
||||
CGAL::lower(result)
|
||||
<= std::min(CGAL::lower(x), CGAL::lower(y)));
|
||||
CGAL_postcondition(
|
||||
CGAL::upper(result)
|
||||
>= std::max(CGAL::upper(x), CGAL::upper(y)));
|
||||
|
||||
NT operator() (const ::CORE::BigInt& x){
|
||||
return round(CORE::BigFloat(x));
|
||||
}
|
||||
return result ;
|
||||
}
|
||||
};
|
||||
|
||||
class Singleton {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef bool result_type;
|
||||
|
||||
NT operator() (const ::CORE::BigRat& x){
|
||||
return round(CORE::BigFloat(x));
|
||||
}
|
||||
};
|
||||
bool operator() ( NT x ) const {
|
||||
return (x.err() == 0);
|
||||
}
|
||||
};
|
||||
|
||||
class Width {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
|
||||
BF operator() ( NT x ) const {
|
||||
unsigned long err = 2*x.err();
|
||||
return BF(CORE::BigInt(err),0,x.exp());
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
class Convert_to_bfi {
|
||||
public:
|
||||
|
||||
typedef NT result_type;
|
||||
|
||||
NT operator() (const ::CORE::Expr& x){
|
||||
return round(CORE::BigFloat(x));
|
||||
}
|
||||
|
||||
NT operator() (const ::CORE::BigInt& x){
|
||||
return round(CORE::BigFloat(x));
|
||||
}
|
||||
|
||||
NT operator() (const ::CORE::BigRat& x){
|
||||
return round(CORE::BigFloat(x));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// } // namespace NiX
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
#endif // CGAL_USE_CORE
|
||||
|
|
|
|||
|
|
@ -3,17 +3,14 @@
|
|||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL:$
|
||||
// $Id: 4515 rschindl$
|
||||
// $URL$
|
||||
// $Id$
|
||||
//
|
||||
//
|
||||
// Author(s) : Ralf Schindlbeck <rschindl@mpi-inf.mpg.de>
|
||||
// Author(s) : Michael Hemmer <hemmer@mpi-inf.mpg.de>
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
// TODO: The comments are all original EXACUS comments and aren't adapted. So
|
||||
// they may be wrong now.
|
||||
|
||||
|
||||
/*! \file CGAL/interval_support.h
|
||||
This is experimental
|
||||
|
|
@ -23,69 +20,35 @@
|
|||
#define CGAL_INTERVAL_SUPPORT_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Arithmetic_kernel.h>
|
||||
|
||||
// #include <NiX/Float_traits.h>
|
||||
#include <CGAL/Float_traits.h>
|
||||
|
||||
///////// covnersion tools:
|
||||
// namespace NiX{
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class NT> class Get_arithmetic_traits;
|
||||
|
||||
template <typename A,typename B,typename C,typename D,typename E>
|
||||
class Algebraic_real;
|
||||
|
||||
// } // namespace NiX
|
||||
// namespace CGAL {
|
||||
template <typename A,typename B> class Sqrt_extension;
|
||||
// } // namespace CGAL
|
||||
// namespace NiX {
|
||||
// Bigfloat_interval_functions
|
||||
|
||||
template<typename BigfloatInterval> class Bigfloat_interval_traits;
|
||||
|
||||
template<typename BFI> long get_significant_bits(BFI bfi) {
|
||||
typename Bigfloat_interval_traits<BFI>::Get_significant_bits
|
||||
get_significant_bits;
|
||||
get_significant_bits;
|
||||
return get_significant_bits(bfi);
|
||||
}
|
||||
|
||||
/*
|
||||
template<typename BFI> long set_precision(BFI bfi,long prec) {
|
||||
typename Float_traits<typename Bigfloat_interval_traits<BFI>::BF>
|
||||
::Set_precision set_precision;
|
||||
template<typename BFI> long set_precision(BFI bfi,long prec) {
|
||||
typename Bigfloat_interval_traits<BFI>::Set_precision set_precision;
|
||||
return set_precision(prec);
|
||||
}
|
||||
|
||||
template<typename BFI> long get_precision(BFI bfi) {
|
||||
typename Float_traits<typename Bigfloat_interval_traits<BFI>::BF>
|
||||
::Get_precision get_precision;
|
||||
typename Bigfloat_interval_traits<BFI>::Get_precision get_precision;
|
||||
return get_precision();
|
||||
}
|
||||
*/
|
||||
|
||||
// ONLY FOR TESTING THIS IS THE WRONG FILE!!!
|
||||
template<typename BF> long set_precision(BF bfi,long prec) {
|
||||
typename Float_traits<BF>::Set_precision set_precision;
|
||||
return set_precision(prec);
|
||||
}
|
||||
|
||||
template<typename BF> long get_precision(BF bfi) {
|
||||
typename Float_traits<BF>::Get_precision get_precision;
|
||||
return get_precision();
|
||||
}
|
||||
|
||||
|
||||
template<typename BFI>
|
||||
typename Bigfloat_interval_traits<BFI>::BF upper(BFI bfi) {
|
||||
typename Bigfloat_interval_traits<BFI>::BF upper(const BFI& bfi) {
|
||||
typename Bigfloat_interval_traits<BFI>::Upper upper;
|
||||
return upper(bfi);
|
||||
}
|
||||
|
||||
template<typename BFI>
|
||||
typename Bigfloat_interval_traits<BFI>::BF lower(BFI bfi) {
|
||||
typename Bigfloat_interval_traits<BFI>::BF lower(const BFI& bfi) {
|
||||
typename Bigfloat_interval_traits<BFI>::Lower lower;
|
||||
return lower(bfi);
|
||||
}
|
||||
|
|
@ -107,7 +70,6 @@ template<typename BFI> bool overlap(BFI bfi1, BFI bfi2) {
|
|||
|
||||
template<typename BFI> typename Bigfloat_interval_traits<BFI>::BF
|
||||
width(BFI bfi) {
|
||||
|
||||
typename Bigfloat_interval_traits<BFI>::Width width;
|
||||
return width(bfi);
|
||||
}
|
||||
|
|
@ -117,226 +79,23 @@ template<typename BFI> bool singleton(BFI bfi) {
|
|||
return singleton(bfi);
|
||||
}
|
||||
|
||||
template<typename NT> typename CGALi::Get_arithmetic_kernel<NT>::Bigfloat_interval
|
||||
convert_to_bfi(NT x) {
|
||||
|
||||
typedef typename
|
||||
CGALi::Get_arithmetic_kernel<NT>::Bigfloat_interval BFI;
|
||||
typename Bigfloat_interval_traits<BFI>::CGALi::Get_arithmetic_kernel
|
||||
get_arithmetic_traits;
|
||||
return get_arithmetic_traits(x);
|
||||
}
|
||||
|
||||
#if 0
|
||||
//TODO
|
||||
//porting Specialisation for double-intervals from EXACUS2CGAL
|
||||
|
||||
// (Parital) Specialisation for double-intervals
|
||||
|
||||
#include <NiX/Interval.h>
|
||||
|
||||
template<>
|
||||
class Bigfloat_interval_traits<Interval>
|
||||
{
|
||||
public:
|
||||
typedef Interval NT;
|
||||
|
||||
typedef double BF;
|
||||
|
||||
/* ??
|
||||
class Get_significant_bits {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator()( NT x) const {}
|
||||
};
|
||||
*/
|
||||
|
||||
class Upper {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
|
||||
BF operator() ( NT a ) const {
|
||||
return a.upper();
|
||||
}
|
||||
};
|
||||
|
||||
class Lower {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
|
||||
BF operator() ( NT a ) const {
|
||||
return a.lower();
|
||||
}
|
||||
};
|
||||
|
||||
class In_zero {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator() ( NT x ) const {
|
||||
return ::boost::numeric::in_zero(x);
|
||||
}
|
||||
};
|
||||
|
||||
class Overlap {
|
||||
public:
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT first_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT second_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator() ( NT x, NT y ) const {
|
||||
return ::boost::numeric::overlap(x,y);
|
||||
}
|
||||
};
|
||||
|
||||
class Hull {
|
||||
public:
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT first_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT second_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT result_type;
|
||||
|
||||
NT operator() ( NT x, NT y ) const {
|
||||
return ::boost::numeric::hull(x,y);
|
||||
}
|
||||
};
|
||||
|
||||
class Singleton {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator() ( NT a ) const {
|
||||
return ::boost::numeric::singleton(a);
|
||||
}
|
||||
};
|
||||
|
||||
class Width {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
|
||||
BF operator() ( NT a ) const {
|
||||
return ::boost::numeric::width(a);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class Convert_to_bfi {
|
||||
public:
|
||||
|
||||
typedef NT result_type;
|
||||
|
||||
template<typename NTX>
|
||||
NT operator() ( NTX x) {
|
||||
return to_interval( x );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
template <class COEFF, class HP >
|
||||
leda_bigfloat_interval
|
||||
inline
|
||||
convert_to_bfi(const Algebraic_real< COEFF, ::leda::real, ::leda::rational, HP >& x) {
|
||||
|
||||
//std::cout << "convert_to_bfi(const Algebraic_real<COEFF, FWS, RAT, HP >& x)"<<std::endl;
|
||||
typedef ::leda::real FWS;
|
||||
typedef ::leda::rational RAT;
|
||||
typedef Algebraic_real< COEFF, FWS, RAT, HP > ALG;
|
||||
|
||||
// if zero done
|
||||
if(NiX::sign(x) == CGAL::ZERO)
|
||||
return (leda_bigfloat_interval(0));
|
||||
CGAL_postcondition(NiX::sign(x.low()) == NiX::sign(x.high()));
|
||||
|
||||
|
||||
typedef ::leda::bigfloat BF;
|
||||
long final_prec = BF::set_precision(BF::get_precision()+4);
|
||||
|
||||
::leda::bigfloat rerror(2,-final_prec);
|
||||
|
||||
leda_bigfloat_interval bfi(convert_to_bfi(x.low()).lower(), convert_to_bfi(x.high()).upper());
|
||||
|
||||
//while( NiX::width(bfi) >= rerror){
|
||||
//while( NiX::width(bfi) >= NiX::median(NiX::abs(bfi))*rerror){
|
||||
//std::cout << "rel error: "<< (NiX::width(bfi) / NiX::abs(bfi)).upper() <<std::endl;
|
||||
while( (NiX::width(bfi) / NiX::abs(bfi)).upper() > rerror ){
|
||||
|
||||
//std::cout <<" diff " << NiX::width(bfi) - NiX::abs(bfi).upper()*rerror << std::endl;
|
||||
x.refine();
|
||||
bfi = leda_bigfloat_interval(convert_to_bfi(x.low()).lower(), convert_to_bfi(x.high()).upper());
|
||||
//std::cout <<"bfi: "<< bfi << std::endl;
|
||||
//std::cout << "final_prec: "<< final_prec << std::endl;
|
||||
//std::cout << "rerror : "<< rerror << std::endl;
|
||||
//std::cout << "rel error: "<< (NiX::width(bfi) / NiX::abs(bfi)).upper() <<std::endl;
|
||||
}
|
||||
//std::cout << "convert_to_bfi(const Algebraic_real<COEFF, FWS, RAT, HP >& x) end"<<std::endl;
|
||||
BF::set_precision(final_prec);
|
||||
|
||||
#ifndef NDEBUG
|
||||
::leda::rational lower_num(bfi.lower().get_significant());
|
||||
::leda::rational lower_denom(NiX::ipower(RAT(2),NiX::abs(bfi.lower().get_exponent().to_long())));
|
||||
::leda::rational lower;
|
||||
if(bfi.lower().get_exponent().to_long() < 0 )
|
||||
lower = lower_num / lower_denom ;
|
||||
else
|
||||
lower = lower_num * lower_denom;
|
||||
CGAL_postcondition( x.compare(lower) == CGAL::LARGER );
|
||||
|
||||
::leda::rational upper_num(bfi.upper().get_significant());
|
||||
::leda::rational upper_denom(NiX::ipower(RAT(2),NiX::abs(bfi.upper().get_exponent().to_long())));
|
||||
::leda::rational upper;
|
||||
if(bfi.upper().get_exponent().to_long() < 0 )
|
||||
upper = upper_num / upper_denom ;
|
||||
else
|
||||
upper = upper_num * upper_denom;
|
||||
CGAL_postcondition( x.compare(upper) == CGAL::SMALLER );
|
||||
#endif
|
||||
|
||||
return bfi;
|
||||
}
|
||||
#endif
|
||||
template <class NTX> class Get_arithmetic_kernel;
|
||||
|
||||
template <class NTX>
|
||||
typename CGALi::Get_arithmetic_kernel<NTX>::Arithmetic_kernel::Bigfloat_interval
|
||||
typename Get_arithmetic_kernel<NTX>::Arithmetic_kernel::Bigfloat_interval
|
||||
convert_to_bfi(const NTX& x) {
|
||||
typedef typename CGALi::Get_arithmetic_kernel<NTX>::Arithmetic_kernel AT;
|
||||
typedef typename Get_arithmetic_kernel<NTX>::Arithmetic_kernel AT;
|
||||
typedef typename AT::Bigfloat_interval BFI;
|
||||
typename Bigfloat_interval_traits<BFI>::Convert_to_bfi convert_to_bfi;
|
||||
return convert_to_bfi(x);
|
||||
}
|
||||
|
||||
// TODO: move this to sqrt_extension ?
|
||||
template <typename A,typename B> class Sqrt_extension;
|
||||
template <typename NT, typename ROOT>
|
||||
typename CGALi::Get_arithmetic_kernel<NT>::Arithmetic_kernel::Bigfloat_interval
|
||||
typename Get_arithmetic_kernel<NT>::Arithmetic_kernel::Bigfloat_interval
|
||||
convert_to_bfi(const CGAL::Sqrt_extension<NT,ROOT>& x) {
|
||||
typedef typename CGALi::Get_arithmetic_kernel<NT>::Arithmetic_kernel AT;
|
||||
typedef typename Get_arithmetic_kernel<NT>::Arithmetic_kernel AT;
|
||||
typedef typename AT::Bigfloat_interval BFI;
|
||||
if(x.is_extended()){
|
||||
BFI a0(convert_to_bfi(x.a0()));
|
||||
|
|
@ -348,33 +107,8 @@ convert_to_bfi(const CGAL::Sqrt_extension<NT,ROOT>& x) {
|
|||
}
|
||||
}
|
||||
|
||||
template <class COEFF, class FWS, class RAT, class T1, class T2>
|
||||
typename CGALi::Get_arithmetic_kernel<COEFF>::Arithmetic_kernel::Bigfloat_interval
|
||||
inline
|
||||
convert_to_bfi(const Algebraic_real< COEFF, FWS, RAT,T1,T2>& x) {
|
||||
typedef typename CGALi::Get_arithmetic_kernel<COEFF>::Arithmetic_kernel AT;
|
||||
typedef typename AT::Bigfloat_interval BFI;
|
||||
typedef typename AT::Bigfloat BF;
|
||||
BFI result = x.convert_to_bfi();
|
||||
|
||||
#ifndef NDEBUG
|
||||
CGAL::set_precision(BF(),CGAL::get_precision(BF())*2);
|
||||
CGAL_postcondition(CGAL::lower(result) <= CGAL::lower(CGAL::convert_to_bfi(x.low() )));
|
||||
CGAL_postcondition(CGAL::upper(result) >= CGAL::upper(CGAL::convert_to_bfi(x.high())));
|
||||
CGAL::set_precision(BF(),CGAL::get_precision(BF())/2);
|
||||
#endif
|
||||
return result;
|
||||
};
|
||||
|
||||
// } // namespace NiX
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
#ifdef CGAL_USE_LEDA
|
||||
#include <CGAL/leda_interval_support.h>
|
||||
#endif // CGAL_USE_LEDA
|
||||
|
||||
#ifdef CGAL_USE_CORE
|
||||
#include <CGAL/core_interval_support.h>
|
||||
#endif // CGAL_USE_CORE
|
||||
#include <CGAL/Arithmetic_kernel.h>
|
||||
|
||||
#endif // CGAL_INTERVAL_SUPPORT_H
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
// Copyright (c) 1999,2007 Utrecht University (The Netherlands),
|
||||
// ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
|
||||
// INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
|
||||
|
|
@ -24,17 +25,14 @@
|
|||
#ifndef CGAL_LEDA_BIGFLOAT_H
|
||||
#define CGAL_LEDA_BIGFLOAT_H
|
||||
|
||||
#include <CGAL/number_type_basic.h>
|
||||
#include <CGAL/basic.h>
|
||||
|
||||
#ifdef CGAL_USE_LEDA
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <CGAL/leda_coercion_traits.h>
|
||||
#include <CGAL/Interval_nt.h>
|
||||
|
||||
|
||||
|
||||
#include <CGAL/LEDA_basic.h>
|
||||
#if CGAL_LEDA_VERSION < 500
|
||||
#include <LEDA/bigfloat.h>
|
||||
|
|
@ -42,8 +40,6 @@
|
|||
#include <LEDA/numbers/bigfloat.h>
|
||||
#endif
|
||||
|
||||
#include <CGAL/Float_traits.h>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <> class Algebraic_structure_traits< leda_bigfloat >
|
||||
|
|
@ -147,392 +143,6 @@ class Is_valid< leda_bigfloat >
|
|||
}
|
||||
};
|
||||
|
||||
//**********************NEW**********************
|
||||
|
||||
// Specialization of CGAL::Float_traits_kernel for leda::bigfloat
|
||||
|
||||
template <> class Float_traits_kernel< ::leda::bigfloat > {
|
||||
public:
|
||||
typedef ::leda::bigfloat FT;
|
||||
typedef ::leda::integer IT;
|
||||
typedef ::CGAL::Float_number_tag Float_type;
|
||||
typedef CGAL::Precision_type Precision_type;
|
||||
|
||||
class Get_precision {
|
||||
public:
|
||||
typedef CGAL::Precision_type result_type;
|
||||
|
||||
CGAL::Precision_type operator()() const {
|
||||
return CGAL::Precision_type( leda::bigfloat::get_precision() );
|
||||
}
|
||||
};
|
||||
|
||||
class Set_precision {
|
||||
public:
|
||||
typedef void result_type;
|
||||
typedef CGAL::Precision_type first_argument_type;
|
||||
|
||||
void operator()( const CGAL::Precision_type& precision ) const {
|
||||
leda::bigfloat::set_precision( (leda::sz_t)precision );
|
||||
}
|
||||
};
|
||||
|
||||
class Get_rounding_mode {
|
||||
public:
|
||||
typedef CGAL::Rounding_mode result_type;
|
||||
|
||||
CGAL::Rounding_mode operator()() const {
|
||||
return CGAL::Rounding_mode( leda::bigfloat::get_rounding_mode() );
|
||||
}
|
||||
};
|
||||
|
||||
class Set_rounding_mode {
|
||||
public:
|
||||
typedef void result_type;
|
||||
typedef CGAL::Rounding_mode first_argument_type;
|
||||
|
||||
void operator()( const CGAL::Rounding_mode& rounding_mode ) const {
|
||||
leda::bigfloat::set_rounding_mode( (leda::rounding_modes)rounding_mode );
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Specialization of CGAL::Float_traits for leda::bigfloat
|
||||
|
||||
template <> class Float_traits< ::leda::bigfloat >
|
||||
: public Float_traits_base< Float_traits_kernel< ::leda::bigfloat> > {
|
||||
|
||||
private:
|
||||
static Rounding_mode get_rounding_mode() {
|
||||
return Rounding_mode( leda::bigfloat::get_rounding_mode() );
|
||||
};
|
||||
|
||||
static Precision_type get_precision() {
|
||||
return Precision_type( leda::bigfloat::get_precision() );
|
||||
};
|
||||
|
||||
public:
|
||||
typedef Float_traits_kernel< leda::bigfloat > FT_kernel;
|
||||
typedef FT_kernel::FT FT;
|
||||
typedef FT_kernel::IT IT;
|
||||
typedef FT_kernel::Float_type Float_type;
|
||||
|
||||
|
||||
class Set_precision {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator() ( long prec ) const {
|
||||
FT_kernel::Set_precision set_precision;
|
||||
FT_kernel::Get_precision get_precision;
|
||||
long old_precision = get_precision();
|
||||
set_precision(prec);
|
||||
return old_precision;
|
||||
}
|
||||
};
|
||||
|
||||
class Get_precision {
|
||||
public:
|
||||
// type for the \c AdaptableGenerator concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator() () const {
|
||||
FT_kernel::Get_precision get_precision;
|
||||
return get_precision();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Construct
|
||||
: public Float_traits_base< FT_kernel >::Construct {
|
||||
public:
|
||||
FT operator() ( const IT& m, const IT& e = IT(0) ) {
|
||||
return FT( m, e);
|
||||
}
|
||||
}; // class Constructor
|
||||
|
||||
class Construct_special_value {
|
||||
public:
|
||||
FT operator()( const Special_value& sv ) {
|
||||
switch( sv ) {
|
||||
case SV_N_ZERO: return leda::bigfloat::nZero;
|
||||
case SV_P_ZERO: return leda::bigfloat::pZero;
|
||||
case SV_N_INF: return leda::bigfloat::nInf;
|
||||
case SV_P_INF: return leda::bigfloat::pInf;
|
||||
case SV_NAN: return leda::bigfloat::NaN;
|
||||
default: return FT(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Is_special_value {
|
||||
public:
|
||||
bool operator()( const FT& bf ) const {
|
||||
return leda::isSpecial( bf );
|
||||
}
|
||||
};
|
||||
|
||||
class Get_special_value {
|
||||
public:
|
||||
Special_value operator()( const FT& bf ) const {
|
||||
if( leda::isNaN( bf ) )
|
||||
return SV_NAN;
|
||||
else if( leda::isnZero( bf ) )
|
||||
return SV_N_ZERO;
|
||||
else if( leda::ispZero( bf ) )
|
||||
return SV_P_ZERO;
|
||||
else if( leda::isnInf( bf ) )
|
||||
return SV_N_INF;
|
||||
else if( leda::ispInf( bf ) )
|
||||
return SV_P_INF;
|
||||
else
|
||||
return SV_NONE;
|
||||
}
|
||||
};
|
||||
|
||||
class Is_zero {
|
||||
public:
|
||||
bool operator()( const FT& bf ) const {
|
||||
return leda::isZero( bf ) || bf == FT(0);
|
||||
}
|
||||
};
|
||||
|
||||
class Is_inf {
|
||||
public:
|
||||
bool operator()( const FT& bf ) const {
|
||||
return leda::isInf( bf );
|
||||
}
|
||||
};
|
||||
|
||||
class Get_mantissa
|
||||
: public Float_traits_base< FT_kernel >::Get_mantissa {
|
||||
public:
|
||||
//! type for the \c AdaptableUnaryFunction concept.
|
||||
typedef IT result_type;
|
||||
//! type for the \c AdaptableUnaryFunction concept.
|
||||
typedef FT argument_type;
|
||||
|
||||
IT operator()( const FT& a ) const {
|
||||
return a.get_significant();
|
||||
}
|
||||
}; // class GetMantissa
|
||||
|
||||
class Get_exponent
|
||||
: public Float_traits_base< FT_kernel >::Get_exponent {
|
||||
public:
|
||||
//! type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long result_type;
|
||||
//! type for the \c AdaptableUnaryFunction concept.
|
||||
typedef FT argument_type;
|
||||
|
||||
long operator()( const FT& a ) const {
|
||||
return a.get_exponent().to_long();
|
||||
}
|
||||
}; // class GetMantissa
|
||||
|
||||
class Get_mantissa_and_exponent
|
||||
: public Float_traits_base< FT_kernel >::Get_mantissa_and_exponent {
|
||||
public:
|
||||
//! type for the \c AdaptableUnaryFunction concept.
|
||||
typedef std::pair< IT, IT > result_type;
|
||||
//! type for the \c AdaptableUnaryFunction concept.
|
||||
typedef FT argument_type;
|
||||
|
||||
std::pair< IT, IT > operator()( const FT& a ) const {
|
||||
IT m = a.get_significant();
|
||||
IT e = a.get_exponent();
|
||||
std::pair< IT, IT > p( m, e );
|
||||
|
||||
return p;
|
||||
}
|
||||
}; // class GetMantissaAndExponent
|
||||
|
||||
class Round_relative
|
||||
: public Float_traits_base< FT_kernel >::Round_relative {
|
||||
public:
|
||||
//! type for the \c AdaptableTernaryFunction concept.
|
||||
typedef FT result_type;
|
||||
//! type for the \c AdaptableTernaryFunction concept.
|
||||
typedef FT first_argument_type;
|
||||
//! type for the \c AdaptableTernaryFunction concept.
|
||||
typedef CGAL::Precision_type second_argument_type;
|
||||
//! type for the \c AdaptableTernaryFunction concept.
|
||||
typedef CGAL::Rounding_mode third_argument_type;
|
||||
|
||||
FT operator()( const FT& a,
|
||||
const CGAL::Precision_type& p = get_precision(),
|
||||
const CGAL::Rounding_mode& m = get_rounding_mode() ) const {
|
||||
return leda::round(a,(leda::sz_t)p,(leda::rounding_modes)m ) ;
|
||||
}
|
||||
}; // class Round
|
||||
|
||||
|
||||
//TODO
|
||||
//porting Round_absolute and NiX::Float_number from EXACUS2CGAL
|
||||
|
||||
// class Round_absolute : public Float_traits_base< FT_kernel >::Round_absolute {
|
||||
// public:
|
||||
// //! type for the \c AdaptableTernaryFunction concept.
|
||||
// typedef FT result_type;
|
||||
// //! type for the \c AdaptableTernaryFunction concept.
|
||||
// typedef FT first_argument_type;
|
||||
// //! type for the \c AdaptableTernaryFunction concept.
|
||||
// typedef IT second_argument_type;
|
||||
// //! type for the \c AdaptableTernaryFunction concept.
|
||||
// typedef CGAL::Rounding_mode third_argument_type;
|
||||
//
|
||||
// FT operator()( const FT& a,
|
||||
// const IT& new_exponent,
|
||||
// const CGAL::Rounding_mode& r_mode = get_rounding_mode() ) const {
|
||||
// typedef NiX::Float_number<IT> FN;
|
||||
// FN fn( a.get_significant(), a.get_exponent() );
|
||||
// fn = fn.round_absolute( new_exponent, r_mode );
|
||||
// return FT( fn.get_mantissa(), fn.get_exponent() );
|
||||
// }
|
||||
// };
|
||||
|
||||
// special functors ( only for Big_float )
|
||||
|
||||
class Add
|
||||
: public Float_traits_base< FT_kernel >::Add {
|
||||
public:
|
||||
typedef FT result_type;
|
||||
typedef FT first_argument_type;
|
||||
typedef FT second_argument_type;
|
||||
typedef CGAL::Rounding_mode third_argument_type;
|
||||
typedef CGAL::Precision_type fourth_argument_type;
|
||||
|
||||
FT operator()( const FT& a, const FT& b,
|
||||
const Rounding_mode& m = get_rounding_mode(),
|
||||
const Precision_type& p = get_precision() ) const {
|
||||
return leda::add(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
|
||||
}
|
||||
}; // class Add
|
||||
|
||||
class Sub
|
||||
: public Float_traits_base< FT_kernel >::Sub{
|
||||
public:
|
||||
typedef FT result_type;
|
||||
typedef FT first_argument_type;
|
||||
typedef FT second_argument_type;
|
||||
typedef CGAL::Rounding_mode third_argument_type;
|
||||
typedef CGAL::Precision_type fourth_argument_type;
|
||||
|
||||
FT operator()( const FT& a, const FT& b ,
|
||||
const Rounding_mode& m = get_rounding_mode(),
|
||||
const Precision_type& p = get_precision() ) const {
|
||||
return leda::sub(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
|
||||
}
|
||||
}; // class Sub
|
||||
|
||||
|
||||
class Mul
|
||||
: public Float_traits_base< FT_kernel >::Mul {
|
||||
public:
|
||||
typedef FT result_type;
|
||||
typedef FT first_argument_type;
|
||||
typedef FT second_argument_type;
|
||||
typedef CGAL::Rounding_mode third_argument_type;
|
||||
typedef CGAL::Precision_type fourth_argument_type;
|
||||
|
||||
FT operator()( const FT& a, const FT& b ,
|
||||
const Rounding_mode& m = get_rounding_mode(),
|
||||
const Precision_type& p = get_precision() ) const {
|
||||
return leda::mul(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
|
||||
}
|
||||
}; // class Mul
|
||||
|
||||
class Div
|
||||
: public Float_traits_base< FT_kernel >::Div{
|
||||
public:
|
||||
typedef FT result_type;
|
||||
typedef FT first_argument_type;
|
||||
typedef FT second_argument_type;
|
||||
typedef CGAL::Rounding_mode third_argument_type;
|
||||
typedef CGAL::Precision_type fourth_argument_type;
|
||||
|
||||
FT operator()( const FT& a, const FT& b ,
|
||||
const Rounding_mode& m = get_rounding_mode(),
|
||||
const Precision_type& p = get_precision() ) const {
|
||||
return leda::div(a,b,(leda::sz_t)p,(leda::rounding_modes)m);
|
||||
}
|
||||
}; // class Div
|
||||
|
||||
class Sqrt
|
||||
: public Float_traits_base< FT_kernel >::Sqrt{
|
||||
public:
|
||||
typedef FT result_type;
|
||||
typedef FT first_argument_type;
|
||||
typedef CGAL::Rounding_mode second_argument_type;
|
||||
typedef CGAL::Precision_type third_argument_type;
|
||||
|
||||
FT operator()( const FT& bf,
|
||||
const Rounding_mode& r_mode = get_rounding_mode(),
|
||||
const Precision_type& prec = get_precision() ) const {
|
||||
return leda::sqrt( bf, (leda::sz_t)prec, (leda::rounding_modes)r_mode);
|
||||
}
|
||||
}; // class Sqrt
|
||||
|
||||
class Mul_by_pow_of_2
|
||||
: public Float_traits_base< FT_kernel >::Mul_by_pow_of_2{
|
||||
public:
|
||||
//! type for the \c AdaptableBinaryFunction concept.
|
||||
typedef FT result_type;
|
||||
//! type for the \c AdaptableBinaryFunction concept.
|
||||
typedef FT first_argument_type;
|
||||
//! type for the \c AdaptableBinaryFunction concept.
|
||||
typedef IT second_argument_type;
|
||||
|
||||
FT operator()( const FT& a, const IT& e ) const {
|
||||
return FT(a.get_significant(), a.get_exponent()+e);
|
||||
}
|
||||
}; // class Mul_by_pow_of_2
|
||||
|
||||
class Div_by_pow_of_2
|
||||
: public Float_traits_base< FT_kernel >::Div_by_pow_of_2{
|
||||
public:
|
||||
//! type for the \c AdaptableBinaryFunction concept.
|
||||
typedef FT result_type;
|
||||
//! type for the \c AdaptableBinaryFunction concept.
|
||||
typedef FT first_argument_type;
|
||||
//! type for the \c AdaptableBinaryFunction concept.
|
||||
typedef IT second_argument_type;
|
||||
|
||||
FT operator()( const FT& a, const IT& e ) const {
|
||||
return FT(a.get_significant(), a.get_exponent()-e);
|
||||
}
|
||||
}; // class Div_by_pow_of_2
|
||||
|
||||
class Floor {
|
||||
public:
|
||||
typedef IT result_type;
|
||||
typedef FT argument_type;
|
||||
|
||||
IT operator()( const FT& fn ) const {
|
||||
return leda::to_integer( fn, leda::TO_N_INF );
|
||||
}
|
||||
};
|
||||
|
||||
class Ceil {
|
||||
public:
|
||||
typedef IT result_type;
|
||||
typedef FT argument_type;
|
||||
|
||||
IT operator()( const FT& fn ) const {
|
||||
return leda::to_integer( fn, leda::TO_P_INF );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
//**********************NEW**********************
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL:$
|
||||
// $Id: 4515 rschindl$
|
||||
//
|
||||
//
|
||||
// Author(s) : Ralf Schindlbeck <rschindl@mpi-inf.mpg.de>
|
||||
//
|
||||
// ============================================================================
|
||||
|
||||
// TODO: The comments are all original EXACUS comments and aren't adapted. So
|
||||
// they may be wrong now.
|
||||
|
||||
// TODO:
|
||||
// - add to comming interval_traits:
|
||||
// -- CGAL::median(bf_interval)
|
||||
// -- CGAL::ipower(bf_interval)
|
||||
// -- CGAL::relatoive_error(bf_interval)
|
||||
|
||||
/*! \file CGAL/leda_interval_support.h
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifndef CGAL_LEDA_INTERVAL_SUPPORT_H
|
||||
#define CGAL_LEDA_INTERVAL_SUPPORT_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/leda_bigfloat.h>
|
||||
#include <boost/numeric/interval.hpp>
|
||||
|
||||
#ifndef CGAL_USE_LEDA
|
||||
#warning This header file needs LEDA installed in order to work properly.
|
||||
#else // CGAL_USE_LEDA
|
||||
|
||||
#include <CGAL/leda_bigfloat.h>
|
||||
#include <CGAL/leda_integer.h>
|
||||
#include <CGAL/leda_rational.h>
|
||||
#include <CGAL/leda_real.h>
|
||||
#include <CGAL/leda_bigfloat_interval.h>
|
||||
|
||||
|
||||
#include <CGAL/interval_support.h>
|
||||
|
||||
// namespace NiX {
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
// namespace Intern {
|
||||
namespace CGALi {
|
||||
|
||||
|
||||
struct Rounding_for_leda_bigfloat {
|
||||
private: typedef leda::bigfloat T;
|
||||
template<>
|
||||
class Bigfloat_interval_traits<leda_bigfloat_interval>
|
||||
{
|
||||
public:
|
||||
Rounding_for_leda_bigfloat(){};
|
||||
~Rounding_for_leda_bigfloat(){};
|
||||
typedef leda_bigfloat_interval NT;
|
||||
|
||||
typedef leda::bigfloat BF;
|
||||
|
||||
class Get_significant_bits {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator()( NT x) const {
|
||||
leda::bigfloat lower = x.lower();
|
||||
leda::bigfloat upper = x.upper();
|
||||
|
||||
leda::integer lower_m = lower.get_significant();
|
||||
leda::integer upper_m = upper.get_significant();
|
||||
|
||||
leda::integer lower_exp = lower.get_exponent();
|
||||
leda::integer upper_exp = upper.get_exponent();
|
||||
|
||||
long shift = (upper_exp - lower_exp).to_long();
|
||||
if(shift >= 0 ) upper_m = (upper_m << shift);
|
||||
else lower_m = (lower_m << -shift);
|
||||
|
||||
//CGAL_postcondition(lower_m.length() == upper_m.length());
|
||||
|
||||
leda::integer err = lower_m-upper_m;
|
||||
|
||||
return std::max(lower_m.length()-err.length(),0);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class Upper {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
|
||||
BF operator() ( NT a ) const {
|
||||
return a.upper();
|
||||
}
|
||||
};
|
||||
|
||||
class Lower {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
|
||||
BF operator() ( NT a ) const {
|
||||
return a.lower();
|
||||
}
|
||||
};
|
||||
|
||||
class Set_precision {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator() ( long prec ) const {
|
||||
return BF::set_precision(prec);
|
||||
}
|
||||
};
|
||||
|
||||
class Get_precision {
|
||||
public:
|
||||
// type for the \c AdaptableGenerator concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator() () const {
|
||||
return BF::get_precision();
|
||||
}
|
||||
};
|
||||
|
||||
class In_zero {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator() ( NT x ) const {
|
||||
return ::boost::numeric::in_zero(x);
|
||||
}
|
||||
};
|
||||
|
||||
class Overlap {
|
||||
public:
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT first_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT second_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef bool result_type;
|
||||
|
||||
T conv_down(const T& a){
|
||||
return round(a,leda::bigfloat::get_precision(),leda::TO_N_INF);
|
||||
bool operator() ( NT x, NT y ) const {
|
||||
return ::boost::numeric::overlap(x,y);
|
||||
}
|
||||
};
|
||||
T conv_up (const T& a){
|
||||
return round(a,leda::bigfloat::get_precision(),leda::TO_P_INF);
|
||||
};
|
||||
// mathematical operations
|
||||
T add_down(const T& a, const T& b){
|
||||
return add(a,b,leda::bigfloat::get_precision(),leda::TO_N_INF);
|
||||
|
||||
class Hull {
|
||||
public:
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT first_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT second_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT result_type;
|
||||
|
||||
NT operator() ( NT x, NT y ) const {
|
||||
return ::boost::numeric::hull(x,y);
|
||||
}
|
||||
};
|
||||
T add_up (const T& a, const T& b){
|
||||
return add(a,b,leda::bigfloat::get_precision(),leda::TO_P_INF);
|
||||
};
|
||||
T sub_down(const T& a, const T& b){
|
||||
return sub(a, b, leda::bigfloat::get_precision(),leda::TO_N_INF);
|
||||
};
|
||||
T sub_up (const T& a, const T& b){
|
||||
return sub(a, b, leda::bigfloat::get_precision(),leda::TO_P_INF);
|
||||
};
|
||||
T mul_down(const T& a, const T& b){
|
||||
return mul(a, b, leda::bigfloat::get_precision(),leda::TO_N_INF);
|
||||
};
|
||||
T mul_up (const T& a, const T& b){
|
||||
return mul(a, b, leda::bigfloat::get_precision(),leda::TO_P_INF);
|
||||
};
|
||||
T div_down(const T& a, const T& b){
|
||||
return div(a, b, leda::bigfloat::get_precision(),leda::TO_N_INF);
|
||||
};
|
||||
T div_up (const T& a, const T& b){
|
||||
return div(a, b, leda::bigfloat::get_precision(),leda::TO_P_INF);
|
||||
};
|
||||
T sqrt_down(const T& a){
|
||||
return sqrt(a, leda::bigfloat::get_precision(),leda::TO_N_INF);
|
||||
};
|
||||
T sqrt_up (const T& a){
|
||||
return sqrt(a, leda::bigfloat::get_precision(),leda::TO_P_INF);
|
||||
};
|
||||
|
||||
T median(const T& a, const T& b){ return (a+b)/2; };
|
||||
T int_down(const T& a) { return T(floor(a));};
|
||||
T int_up (const T& a) { return T(ceil(a)); };
|
||||
class Singleton {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator() ( NT a ) const {
|
||||
return ::boost::numeric::singleton(a);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
T exp_down(T);
|
||||
T exp_up (T);
|
||||
T log_down(T);
|
||||
T log_up (T);
|
||||
T cos_down(T);
|
||||
T cos_up (T);
|
||||
T tan_down(T);
|
||||
T tan_up (T);
|
||||
T asin_down(T); // [-1;1]
|
||||
T asin_up (T); // [-1;1]
|
||||
T acos_down(T); // [-1;1]
|
||||
T acos_up (T); // [-1;1]
|
||||
T atan_down(T); // [-?;+?]
|
||||
T atan_up (T); // [-?;+?]
|
||||
T sinh_down(T); // [-?;+?]
|
||||
T sinh_up (T); // [-?;+?]
|
||||
T cosh_down(T); // [-?;+?]
|
||||
T cosh_up (T); // [-?;+?]
|
||||
T tanh_down(T); // [-?;+?]
|
||||
T tanh_up (T); // [-?;+?]
|
||||
T asinh_down(T); // [-?;+?]
|
||||
T asinh_up (T); // [-?;+?]
|
||||
T acosh_down(T); // [1;+?]
|
||||
T acosh_up (T); // [1;+?]
|
||||
T atanh_down(T); // [-1;1]
|
||||
T atanh_up (T); // [-1;1]
|
||||
*/
|
||||
class Width {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
|
||||
BF operator() ( NT a ) const {
|
||||
return ::boost::numeric::width(a);
|
||||
}
|
||||
|
||||
// unprotected rounding class
|
||||
//typedef ... unprotected_rounding;
|
||||
};
|
||||
|
||||
class Convert_to_bfi {
|
||||
public:
|
||||
|
||||
typedef NT result_type;
|
||||
|
||||
NT operator() ( const leda::real& x ) {
|
||||
long current_prec = ::leda::bigfloat::get_precision();
|
||||
//x.improve_approximation_to(current_prec);
|
||||
x.guarantee_relative_error(current_prec);
|
||||
|
||||
leda::bigfloat bnum = x.to_bigfloat();
|
||||
leda::bigfloat berr = x.get_bigfloat_error();
|
||||
|
||||
leda::bigfloat low
|
||||
= leda::sub(bnum,berr,current_prec,LEDA::TO_N_INF);
|
||||
leda::bigfloat upp
|
||||
= leda::add(bnum,berr,current_prec,LEDA::TO_P_INF);
|
||||
leda_bigfloat_interval bfi(low,upp) ;
|
||||
|
||||
// std::cout <<"x: "<< x << std::endl;
|
||||
// std::cout <<"bfi.lower(): "<< bfi.lower() << std::endl;
|
||||
// std::cout <<"bfi.upper(): "<< bfi.upper() << std::endl;
|
||||
|
||||
CGAL_postcondition( bfi.lower() <= x );
|
||||
CGAL_postcondition( bfi.upper() >= x );
|
||||
|
||||
return bfi;
|
||||
}
|
||||
|
||||
|
||||
NT operator() (const ::leda::integer& x) {
|
||||
long current_prec = ::leda::bigfloat::get_precision();
|
||||
leda_bigfloat_interval bfi;
|
||||
long length = x.length();
|
||||
|
||||
if(length > current_prec) {
|
||||
::leda::integer significant
|
||||
= CGAL::abs(x) >> (length - current_prec);
|
||||
::leda::bigfloat lower,upper;
|
||||
if(x > 0){
|
||||
lower = ::leda::bigfloat(significant,length - current_prec);
|
||||
upper = ::leda::bigfloat(significant+1,length - current_prec);
|
||||
}else{
|
||||
lower
|
||||
= -::leda::bigfloat(significant+1,length - current_prec);
|
||||
upper
|
||||
= -::leda::bigfloat(significant,length - current_prec);
|
||||
}
|
||||
bfi = leda_bigfloat_interval(lower,upper);
|
||||
}else{
|
||||
::leda::bigfloat bf(x);
|
||||
bfi = leda_bigfloat_interval(bf,bf);
|
||||
}
|
||||
CGAL_postcondition( bfi.lower() <= x );
|
||||
CGAL_postcondition( bfi.upper() >= x );
|
||||
return bfi;
|
||||
}
|
||||
|
||||
|
||||
NT operator() (const ::leda::rational& x) {
|
||||
long old_prec = ::leda::bigfloat::get_precision();
|
||||
::leda::bigfloat::set_precision(old_prec*2);
|
||||
Bigfloat_interval_traits<NT>::Convert_to_bfi convert_to_bfi;
|
||||
leda_bigfloat_interval num = convert_to_bfi(x.numerator());
|
||||
leda_bigfloat_interval den = convert_to_bfi(x.denominator());
|
||||
::leda::bigfloat::set_precision(old_prec);
|
||||
leda_bigfloat_interval bfi = num/den;
|
||||
CGAL_postcondition( bfi.lower() <= x );
|
||||
CGAL_postcondition( bfi.upper() >= x );
|
||||
return bfi;
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
class Checking_for_leda_bigfloat {
|
||||
|
||||
typedef leda::bigfloat T;
|
||||
|
||||
public:
|
||||
|
||||
static T pos_inf() {
|
||||
T b = T(5) / T(0);
|
||||
CGAL_assertion(leda::ispInf(b));
|
||||
return b;
|
||||
}
|
||||
|
||||
static T neg_inf() {
|
||||
T b = T(-5) / T(0);
|
||||
CGAL_assertion(leda::isnInf(b));
|
||||
return b;
|
||||
}
|
||||
|
||||
static T nan() {
|
||||
T b = T(0)*pos_inf();
|
||||
CGAL_assertion(leda::isNaN(b));
|
||||
return b;
|
||||
}
|
||||
|
||||
static bool is_nan(const T& b) {
|
||||
return leda::isNaN(b);
|
||||
}
|
||||
|
||||
static T empty_lower() {
|
||||
return T(1);
|
||||
}
|
||||
|
||||
static T empty_upper() {
|
||||
return T(0);
|
||||
}
|
||||
|
||||
static bool is_empty(const T& a, const T& b) {
|
||||
return a==T(1) && b == T(0);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace CGALi
|
||||
// } // namespace NiX
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
namespace boost {
|
||||
namespace numeric {
|
||||
|
||||
|
||||
inline
|
||||
std::ostream& operator <<
|
||||
(std::ostream& os, const boost::numeric::interval<leda::bigfloat>& x)
|
||||
{
|
||||
os << "["
|
||||
<< x.lower().get_significant() << "*2^" << x.lower().get_exponent()
|
||||
<< " , "
|
||||
<< x.upper().get_significant() << "*2^" << x.upper().get_exponent()
|
||||
<< "]";
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
}//namespace numeric
|
||||
}//namespace boost
|
||||
|
||||
// namespace NiX {
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
typedef boost::numeric::interval
|
||||
< leda::bigfloat,
|
||||
boost::numeric::interval_lib::policies
|
||||
< CGALi::Rounding_for_leda_bigfloat,
|
||||
CGALi::Checking_for_leda_bigfloat > >
|
||||
leda_bigfloat_interval;
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
CGAL::Sign inline sign(const leda::bigfloat& x){
|
||||
if (x < 0 ) return CGAL::NEGATIVE;
|
||||
if (x > 0 ) return CGAL::POSITIVE;
|
||||
return CGAL::ZERO;
|
||||
}
|
||||
*/
|
||||
|
||||
leda_bigfloat_interval inline ipower(const leda_bigfloat_interval& x, int i ){
|
||||
return ::boost::numeric::pow(x,i);
|
||||
}
|
||||
|
||||
// left overs?
|
||||
::leda::bigfloat inline median(const leda_bigfloat_interval& x){
|
||||
return ::boost::numeric::median(x);
|
||||
}
|
||||
|
||||
// forward
|
||||
template<typename BFI> class Bigfloat_interval_traits;
|
||||
template<>
|
||||
class Bigfloat_interval_traits<leda_bigfloat_interval>
|
||||
|
||||
{
|
||||
public:
|
||||
typedef leda_bigfloat_interval NT;
|
||||
|
||||
typedef leda::bigfloat BF;
|
||||
|
||||
class Get_significant_bits {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator()( NT x) const {
|
||||
leda::bigfloat lower = x.lower();
|
||||
leda::bigfloat upper = x.upper();
|
||||
|
||||
leda::integer lower_m = lower.get_significant();
|
||||
leda::integer upper_m = upper.get_significant();
|
||||
|
||||
leda::integer lower_exp = lower.get_exponent();
|
||||
leda::integer upper_exp = upper.get_exponent();
|
||||
|
||||
long shift = (upper_exp - lower_exp).to_long();
|
||||
if(shift >= 0 ) upper_m = (upper_m << shift);
|
||||
else lower_m = (lower_m << -shift);
|
||||
|
||||
//CGAL_postcondition(lower_m.length() == upper_m.length());
|
||||
|
||||
leda::integer err = lower_m-upper_m;
|
||||
|
||||
return std::max(lower_m.length()-err.length(),0);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class Upper {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
|
||||
BF operator() ( NT a ) const {
|
||||
return a.upper();
|
||||
}
|
||||
};
|
||||
|
||||
class Lower {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
|
||||
BF operator() ( NT a ) const {
|
||||
return a.lower();
|
||||
}
|
||||
};
|
||||
|
||||
class Set_precision {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator() ( long prec ) const {
|
||||
return BF::set_precision(prec);
|
||||
}
|
||||
};
|
||||
|
||||
class Get_precision {
|
||||
public:
|
||||
// type for the \c AdaptableGenerator concept.
|
||||
typedef long result_type;
|
||||
|
||||
long operator() () const {
|
||||
return BF::get_precision();
|
||||
}
|
||||
};
|
||||
|
||||
class In_zero {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator() ( NT x ) const {
|
||||
return ::boost::numeric::in_zero(x);
|
||||
}
|
||||
};
|
||||
|
||||
class Overlap {
|
||||
public:
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT first_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT second_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator() ( NT x, NT y ) const {
|
||||
return ::boost::numeric::overlap(x,y);
|
||||
}
|
||||
};
|
||||
|
||||
class Hull {
|
||||
public:
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT first_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT second_argument_type;
|
||||
// type for the \c AdaptableBinaryFunction concept.
|
||||
typedef NT result_type;
|
||||
|
||||
NT operator() ( NT x, NT y ) const {
|
||||
return ::boost::numeric::hull(x,y);
|
||||
}
|
||||
};
|
||||
|
||||
class Singleton {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator() ( NT a ) const {
|
||||
return ::boost::numeric::singleton(a);
|
||||
}
|
||||
};
|
||||
|
||||
class Width {
|
||||
public:
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef NT argument_type;
|
||||
// type for the \c AdaptableUnaryFunction concept.
|
||||
typedef BF result_type;
|
||||
|
||||
BF operator() ( NT a ) const {
|
||||
return ::boost::numeric::width(a);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class Convert_to_bfi {
|
||||
public:
|
||||
|
||||
typedef NT result_type;
|
||||
|
||||
|
||||
NT operator() ( const leda::real& x ) {
|
||||
long current_prec = ::leda::bigfloat::get_precision();
|
||||
//x.improve_approximation_to(current_prec);
|
||||
x.guarantee_relative_error(current_prec);
|
||||
|
||||
leda::bigfloat bnum = x.to_bigfloat();
|
||||
leda::bigfloat berr = x.get_bigfloat_error();
|
||||
|
||||
leda::bigfloat low
|
||||
= leda::sub(bnum,berr,current_prec,LEDA::TO_N_INF);
|
||||
leda::bigfloat upp
|
||||
= leda::add(bnum,berr,current_prec,LEDA::TO_P_INF);
|
||||
leda_bigfloat_interval bfi(low,upp) ;
|
||||
|
||||
// std::cout <<"x: "<< x << std::endl;
|
||||
// std::cout <<"bfi.lower(): "<< bfi.lower() << std::endl;
|
||||
// std::cout <<"bfi.upper(): "<< bfi.upper() << std::endl;
|
||||
|
||||
CGAL_postcondition( bfi.lower() <= x );
|
||||
CGAL_postcondition( bfi.upper() >= x );
|
||||
|
||||
return bfi;
|
||||
}
|
||||
|
||||
|
||||
NT operator() (const ::leda::integer& x) {
|
||||
long current_prec = ::leda::bigfloat::get_precision();
|
||||
leda_bigfloat_interval bfi;
|
||||
long length = x.length();
|
||||
|
||||
if(length > current_prec) {
|
||||
::leda::integer significant
|
||||
= CGAL::abs(x) >> (length - current_prec);
|
||||
::leda::bigfloat lower,upper;
|
||||
if(x > 0){
|
||||
lower = ::leda::bigfloat(significant,length - current_prec);
|
||||
upper = ::leda::bigfloat(significant+1,length - current_prec);
|
||||
}else{
|
||||
lower
|
||||
= -::leda::bigfloat(significant+1,length - current_prec);
|
||||
upper
|
||||
= -::leda::bigfloat(significant,length - current_prec);
|
||||
}
|
||||
bfi = leda_bigfloat_interval(lower,upper);
|
||||
}else{
|
||||
::leda::bigfloat bf(x);
|
||||
bfi = leda_bigfloat_interval(bf,bf);
|
||||
}
|
||||
CGAL_postcondition( bfi.lower() <= x );
|
||||
CGAL_postcondition( bfi.upper() >= x );
|
||||
return bfi;
|
||||
}
|
||||
|
||||
|
||||
NT operator() (const ::leda::rational& x) {
|
||||
long old_prec = ::leda::bigfloat::get_precision();
|
||||
::leda::bigfloat::set_precision(old_prec*2);
|
||||
Bigfloat_interval_traits<NT>::Convert_to_bfi convert_to_bfi;
|
||||
leda_bigfloat_interval num = convert_to_bfi(x.numerator());
|
||||
leda_bigfloat_interval den = convert_to_bfi(x.denominator());
|
||||
::leda::bigfloat::set_precision(old_prec);
|
||||
leda_bigfloat_interval bfi = num/den;
|
||||
CGAL_postcondition( bfi.lower() <= x );
|
||||
CGAL_postcondition( bfi.upper() >= x );
|
||||
return bfi;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template <> class Algebraic_structure_traits< leda_bigfloat_interval >
|
||||
: public Algebraic_structure_traits_base< leda_bigfloat_interval,
|
||||
Field_with_sqrt_tag > {
|
||||
public:
|
||||
typedef Tag_false Is_exact;
|
||||
typedef Tag_true Is_numerical_sensitive;
|
||||
|
||||
class Sqrt
|
||||
: public Unary_function< Type, Type > {
|
||||
public:
|
||||
Type operator()( const Type& x ) const {
|
||||
return ::boost::numeric::sqrt(x);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <> class Real_embeddable_traits< leda_bigfloat_interval >
|
||||
: public Real_embeddable_traits_base< leda_bigfloat_interval > {
|
||||
public:
|
||||
|
||||
class Abs
|
||||
: public Unary_function< Type, Type > {
|
||||
public:
|
||||
Type operator()( const Type& x ) const {
|
||||
return ::boost::numeric::abs(x);
|
||||
}
|
||||
};
|
||||
|
||||
class To_double
|
||||
: public Unary_function< Type, double > {
|
||||
public:
|
||||
double operator()( const Type& x ) const {
|
||||
return CGAL::to_double(::boost::numeric::median(x));
|
||||
}
|
||||
};
|
||||
|
||||
class To_interval
|
||||
: public Unary_function< Type, std::pair< double, double > > {
|
||||
public:
|
||||
std::pair<double, double> operator()( const Type& x ) const {
|
||||
// TODO
|
||||
// return ::boost::numeric::hull(CGAL::to_interval(x.lower()),CGAL::to_interval(x.upper()));
|
||||
|
||||
return std::pair< double, double >( CGAL::to_double( x.lower() ),
|
||||
CGAL::to_double( x.upper() ) );
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
// template <>
|
||||
// class NT_traits<leda_bigfloat_interval>
|
||||
// : public NT_traits_base<leda_bigfloat_interval,
|
||||
// Field_with_sqrt_tag>,
|
||||
// public NT_traits_comparable_base<leda_bigfloat_interval>
|
||||
//
|
||||
// {
|
||||
// public:
|
||||
// typedef leda_bigfloat_interval NT;
|
||||
//
|
||||
// class Abs {
|
||||
// public:
|
||||
// // type for the \c AdaptableUnaryFunction concept.
|
||||
// typedef NT argument_type;
|
||||
// // type for the \c AdaptableUnaryFunction concept.
|
||||
// typedef NT result_type;
|
||||
// NT operator()( NT a) const {
|
||||
// return ::boost::numeric::abs(a);
|
||||
// };
|
||||
// };
|
||||
//
|
||||
// class Sqrt {
|
||||
// public:
|
||||
// // type for the \c AdaptableUnaryFunction concept.
|
||||
// typedef NT argument_type;
|
||||
// // type for the \c AdaptableUnaryFunction concept.
|
||||
// typedef NT result_type;
|
||||
// NT operator()( NT a) const {
|
||||
// return ::boost::numeric::sqrt(a);
|
||||
// };
|
||||
// };
|
||||
//
|
||||
// class To_double {
|
||||
// public:
|
||||
// // the result type.
|
||||
// typedef double result_type;
|
||||
// // the argument type.
|
||||
// typedef NT argument_type;
|
||||
//
|
||||
// double operator()(const NT& a) const {
|
||||
// return NiX::to_double(::boost::numeric::median(a));
|
||||
// }
|
||||
// };
|
||||
// class To_Interval {
|
||||
// public:
|
||||
// // the result type.
|
||||
// typedef Interval result_type;
|
||||
// // the argument type.
|
||||
// typedef NT argument_type;
|
||||
//
|
||||
// Interval operator()(const NT& a) const {
|
||||
// return ::boost::numeric::hull(NiX::to_Interval(a.lower()),
|
||||
// NiX::to_Interval(a.upper()));
|
||||
// }
|
||||
// };
|
||||
|
||||
//TODO
|
||||
//porting Floor_log2_abs and Ceil_log2_abs from EXACUS2CGAL
|
||||
// class Floor_log2_abs {
|
||||
// public:
|
||||
// typedef NT argument_type;
|
||||
// typedef long result_type;
|
||||
// result_type operator() (argument_type x) {
|
||||
// CGAL_precondition(! ::boost::numeric::in_zero(x));
|
||||
// return floor_log2_abs(::boost::numeric::abs(x).lower());
|
||||
// }
|
||||
// };
|
||||
// class Ceil_log2_abs {
|
||||
// public:
|
||||
// typedef NT argument_type;
|
||||
// typedef long result_type;
|
||||
// result_type operator() (argument_type x) {
|
||||
// CGAL_precondition(!(::boost::numeric::in_zero(x) &&
|
||||
// ::boost::numeric::singleton(x)));
|
||||
// return ceil_log2_abs(::boost::numeric::abs(x).upper());
|
||||
// }
|
||||
// };
|
||||
// };
|
||||
|
||||
::leda::bigfloat inline relative_error(const leda_bigfloat_interval& x){
|
||||
if(in_zero(x)){
|
||||
return CGAL::abs(x).upper();
|
||||
|
|
@ -578,8 +264,11 @@ template <> class Real_embeddable_traits< leda_bigfloat_interval >
|
|||
}
|
||||
}
|
||||
|
||||
// } // namespace NiX
|
||||
leda_bigfloat_interval inline ipower(const leda_bigfloat_interval& x, int i ){
|
||||
return ::boost::numeric::pow(x,i);
|
||||
}
|
||||
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
|
||||
#endif // CGAL_USE_LEDA
|
||||
#endif // CGAL_LEDA_INTERVAL_SUPPORT_H
|
||||
|
|
|
|||
|
|
@ -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