interval_support, is now ported from EXACUS2CGAL

This commit is contained in:
Ralf Schindlbeck 2008-02-14 09:33:09 +00:00
parent 7eee16103a
commit edd70f970a
5 changed files with 1736 additions and 0 deletions

4
.gitattributes vendored
View File

@ -2917,6 +2917,7 @@ 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
@ -2927,6 +2928,9 @@ Number_types/include/CGAL/Sqrt_extension/Real_embeddable_traits.h -text
Number_types/include/CGAL/Sqrt_extension/Scalar_factor_traits.h -text
Number_types/include/CGAL/Sqrt_extension/Sqrt_extension_type.h -text
Number_types/include/CGAL/Sqrt_extension/io.h -text
Number_types/include/CGAL/core_interval_support.h -text
Number_types/include/CGAL/interval_support.h -text
Number_types/include/CGAL/leda_interval_support.h -text
Number_types/test/Number_types/CMakeLists.txt -text
Optimisation_doc/doc_tex/Bounding_volumes/annulus.eps -text svneol=unset#application/postscript
Optimisation_doc/doc_tex/Bounding_volumes/annulus.gif -text svneol=unset#image/gif

View File

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

View File

@ -0,0 +1,290 @@
// 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/core_interval_support.h
This is experimental
use CORE::BigFloat as interval type.
*/
#ifndef CGAL_CORE_INTERVAL_SUPPORT_H
#define CGAL_CORE_INTERVAL_SUPPORT_H
#include <CGAL/basic.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;
typedef CORE::BigFloat BF;
typedef CORE::BigFloat BFI;
typedef CORE::BigInt Integer;
BF xr;
CORE::BigInt m = x.m();
long err = x.err();
long exp = x.exp();
long shift = ::CORE::bitLength(m) - rel_prec - 1;
if( shift > 0 ){
Integer new_m = m >> shift ;
if(err == 0){
xr = BF(new_m,1,0)*BF::exp2(exp*14+shift);
}else{
xr = BF(new_m,2,0)*BF::exp2(exp*14+shift);
}
}else{
// noting to do
xr = x;
}
CGAL_postcondition(CGAL::abs(CGAL::get_significant_bits(xr) - rel_prec) <= 1);
CGAL_postcondition(BF(xr.m()-xr.err(),0,xr.exp()) <= BF(x.m()-x.err(),0,x.exp()));
CGAL_postcondition(BF(xr.m()+xr.err(),0,xr.exp()) >= BF(x.m()+x.err(),0,x.exp()));
return xr;
}
template<typename BFI> class Bigfloat_interval_traits;
template<> class Bigfloat_interval_traits<CORE::BigFloat>
{
public:
typedef CORE::BigFloat NT;
typedef CORE::BigFloat BF;
typedef Bigfloat_interval_traits<NT> Self;
class Get_significant_bits {
public:
// type for the \c AdaptableUnaryFunction concept.
typedef NT argument_type;
// type for the \c AdaptableUnaryFunction concept.
typedef long result_type;
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() ( 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;
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;
}
};
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;
}
};
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();
}
};
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;
}
};
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;
// 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;
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;
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
#endif // CGAL_CORE_INTERVAL_SUPPORT_H

View File

@ -0,0 +1,380 @@
// 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/interval_support.h
This is experimental
*/
#ifndef CGAL_INTERVAL_SUPPORT_H
#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;
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;
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;
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>::Upper upper;
return upper(bfi);
}
template<typename BFI>
typename Bigfloat_interval_traits<BFI>::BF lower(BFI bfi) {
typename Bigfloat_interval_traits<BFI>::Lower lower;
return lower(bfi);
}
template<typename BFI> BFI hull(BFI bfi1, BFI bfi2) {
typename Bigfloat_interval_traits<BFI>::Hull hull;
return hull(bfi1, bfi2);
}
template<typename BFI> bool in_zero(BFI bfi) {
typename Bigfloat_interval_traits<BFI>::In_zero in_zero;
return in_zero(bfi);
}
template<typename BFI> bool overlap(BFI bfi1, BFI bfi2) {
typename Bigfloat_interval_traits<BFI>::Overlap overlap;
return overlap(bfi1, bfi2);
}
template<typename BFI> typename Bigfloat_interval_traits<BFI>::BF
width(BFI bfi) {
typename Bigfloat_interval_traits<BFI>::Width width;
return width(bfi);
}
template<typename BFI> bool singleton(BFI bfi) {
typename Bigfloat_interval_traits<BFI>::Singleton singleton;
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>
typename CGALi::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 AT::Bigfloat_interval BFI;
typename Bigfloat_interval_traits<BFI>::Convert_to_bfi convert_to_bfi;
return convert_to_bfi(x);
}
template <typename NT, typename ROOT>
typename CGALi::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 AT::Bigfloat_interval BFI;
if(x.is_extended()){
BFI a0(convert_to_bfi(x.a0()));
BFI a1(convert_to_bfi(x.a1()));
BFI root(CGAL::sqrt(convert_to_bfi(x.root())));
return a0+a1*root;
}else{
return convert_to_bfi(x.a0());
}
}
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
#endif // CGAL_INTERVAL_SUPPORT_H

View File

@ -0,0 +1,585 @@
// 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/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>
#include <CGAL/leda_integer.h>
#include <CGAL/leda_rational.h>
#include <CGAL/leda_real.h>
// namespace NiX {
CGAL_BEGIN_NAMESPACE
// namespace Intern {
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)); };
/*
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]
*/
// unprotected rounding class
//typedef ... unprotected_rounding;
};
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);
}
::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();
}else{
return (width(x) / CGAL::abs(x)).upper();
}
}
// } // namespace NiX
CGAL_END_NAMESPACE
#endif // CGAL_LEDA_INTERVAL_SUPPORT_H