CGAL 5.4.4  Number Types

#include <CGAL/Interval_nt.h>
The class Interval_nt
provides an interval arithmetic number type.
This section describes briefly what interval arithmetic is, its implementation in CGAL, and its possible use by geometric programs. The main reason for having interval arithmetic in CGAL is its integration into the filtered robust and fast predicates scheme, but we also provide a number type so that you can use it separately if you find any use for it, such as interval analysis, or to represent data with tolerance...
The purpose of interval arithmetic is to provide an efficient way to bound the roundoff errors made by floating point computations. You can choose the behavior of your program depending on these errors. You can find more theoretical information on this topic in [1].
Interval arithmetic is a large concept and we will only consider here a simple arithmetic based on intervals whose bounds are doubles. So each variable is an interval representing any value inside the interval. All arithmetic operations (+, , \( *\), \( /\), \( \sqrt{}\), square()
, min()
, max()
and abs()
) on intervals preserve the inclusion. This property can be expressed by the following formula ( \( x\) and \( y\) are real, \( X\) and \( Y\) are intervals, \( \mathcal{OP}\) is an arithmetic operation):
\[ \forall\ x \in X, \forall\ y \in Y, (x\ \mathcal{OP}\ y) \in (X\ \mathcal{OP}\ Y) \]
For example, if the final result of a sequence of arithmetic operations is an interval that does not contain zero, then you can safely determine its sign.
Parameters
The template parameter Protected
is a Boolean parameter, which defaults to true
. It provides a way to select faster computations by avoiding rounding mode switches, at the expense of more care to be taken by the user (see below). The default value, true
, is the safe way, and takes care of proper rounding mode changes. When specifying false
, the user has to take care about setting the rounding mode towards plus infinity before doing any computations with the interval class. He can do so using the Protect_FPU_rounding
class for example.
Example
Protecting an area of code that uses operations on the class Interval_nt_advanced
can be done in the following way:
The basic idea is to use the directed rounding modes specified by the IEEE 754 standard, which are implemented by almost all processors nowadays. It states that you have the possibility, concerning the basic floating point operations ( \( +,,*,/,\sqrt{}\)) to specify the rounding mode of each operation instead of using the default, which is set to 'round to the nearest'. This feature allows us to compute easily on intervals. For example, to add the two intervals [a.i;a.s] and [b.i;b.s], compute \( c.i=a.i+b.i\) rounded towards minus infinity, and \( c.s=a.s+b.s\) rounded towards plus infinity, and the result is the interval [c.i;c.s]. This method can be extended easily to the other operations.
The problem is that we have to change the rounding mode very often, and the functions of the C library doing this operation are slow and not portable. That's why assembly versions are used as often as possible. Another trick is to store the opposite of the lower bound, instead of the lower bound itself, which allows us to never change the rounding mode inside simple operations. Therefore, all basic operations, which are in the class Interval_nt_advanced
assume that the rounding mode is set to 'round to infinity', and everything works with this correctly set.
So, if the user needs the speed of Interval_nt_advanced
, he must take care of setting the rounding mode to 'round to infinity' before each block of operations on this number type. And if other operations might be affected by this, he must take care to reset it to 'round to the nearest' before they are executed.
Notes:
CGAL_IA_NO_X86_OVER_UNDER_FLOW_PROTECT
. Other platforms are not affected by this flag. CGAL_IA_DONT_STOP_CONSTANT_PROPAGATION
. Related Functions  
(Note that these are not member functions.)  
Interval_nt  sqrt (Interval_nt I) 
returns [0; \( \sqrt{upper\_bound(I)}\)] when only the lower bound is negative (expectable case with roundoff errors), and is unspecified when the upper bound also is negative (unexpected case).  
double  to_double (Interval_nt I) 
returns the middle of the interval, as a double approximation of the interval.  
Uncertain< Sign >  sign (Interval_nt i) 
void  FPU_set_cw (FPU_CW_t R) 
sets the rounding mode to R .  
FPU_CW_t  FPU_get_cw (void) 
returns the current rounding mode.  
FPU_CW_t  FPU_get_and_set_cw (FPU_CW_t R) 
sets the rounding mode to R and returns the old one.  
Comparisons  
The comparison operators ( \( <\), \( >\), \( <=\), \( >=\), \( ==\), \( !=\), This can be expressed by the following formula ( \( x\) and \( y\) are real, \( X\) and \( Y\) are intervals, \( \mathcal{OP}\) is a comparison operator): \[ \left(\forall x \in X, \forall y \in Y, (x\ \mathcal{OP}\ y) = true\right) \Rightarrow (X\ \mathcal{OP}\ Y) = true \] and \[ \left(\forall x \in X, \forall y \in Y, (x\ \mathcal{OP}\ y) = false\right) \Rightarrow (X\ \mathcal{OP}\ Y) =false \] Otherwise, the comparison is not safe, and we specify this by returning a type encoding this uncertainty, namely using  
Uncertain< bool >  operator< (Interval_nt i, Interval_nt j) 
Uncertain< bool >  operator> (Interval_nt i, Interval_nt j) 
Uncertain< bool >  operator<= (Interval_nt i, Interval_nt j) 
Uncertain< bool >  operator>= (Interval_nt i, Interval_nt j) 
Uncertain< bool >  operator== (Interval_nt i, Interval_nt j) 
Uncertain< bool >  operator!= (Interval_nt i, Interval_nt j) 
Uncertain< Comparison_result >  compare (Interval_nt i, Interval_nt j) 
Types  
The class  
typedef double  value_type 
The type of the bounds of the interval.  
typedef Uncertain_conversion_exception  unsafe_comparison 
The type of the exceptions raised when uncertain comparisons are performed.  
typedef unspecified_type  Protector 
A type whose default constructor and destructor allow to protect a block of code from FPU rounding modes necessary for the computations with Interval_nt<false> . More...  
Creation  
Interval_nt (long long i)  
introduces a small interval containing i (possibly a point).  
Interval_nt (double d)  
introduces the interval [d ;d ].  
Interval_nt (double i, double s)  
introduces the interval [i ;s ].  
Interval_nt (std::pair< double, double > p)  
introduces the interval [p.first ;p.second ].  
Operations  
All functions required by a class to be considered as a CGAL number type (see Numbertype) are present, as well as the utility functions, sometimes with a particular semantic which is described below. There are also a few additional functions.  
Interval_nt  operator/ (Interval_nt J) 
returns [ \( \infty\); \( +\infty\)] when the denominator contains 0.  
double  inf () 
returns the lower bound of the interval.  
double  sup () 
returns the upper bound of the interval.  
bool  is_point () 
returns whether both bounds are equal.  
bool  is_same (Interval_nt J) 
returns whether both intervals have the same bounds.  
bool  do_overlap (Interval_nt J) 
returns whether both intervals have a non empty intersection.  
Implementation  
The operations on Users that need performance are encouraged to use We provide two interfaces to change the rounding mode. The first one is to use a protector object whose default constructor and destructor will take care of changing the rounding mode. The protector is implemented using  
typedef int  FPU_CW_t 
The type used by the following functions to deal with rounding modes. More...  
typedef int CGAL::Interval_nt< Protected >::FPU_CW_t 
The type used by the following functions to deal with rounding modes.
This is usually an int
.
typedef unspecified_type CGAL::Interval_nt< Protected >::Protector 
A type whose default constructor and destructor allow to protect a block of code from FPU rounding modes necessary for the computations with Interval_nt<false>
.
It does nothing for Interval_nt<true>
. It is implemented as Protect_FPU_rounding<!Protected>
.