Dune Core Modules (2.5.2)

Classes

struct  Dune::FloatCmp::EpsilonType< T >
 Mapping of value type to epsilon type. More...
 
struct  Dune::FloatCmp::EpsilonType< std::vector< T, A > >
 Specialization of EpsilonType for std::vector. More...
 
struct  Dune::FloatCmp::EpsilonType< FieldVector< T, n > >
 Specialization of EpsilonType for Dune::FieldVector. More...
 
struct  Dune::FloatCmp::DefaultEpsilon< T, style >
 mapping from a value type and a compare style to a default epsilon More...
 
class  Dune::FloatCmpOps< T, cstyle_, rstyle_ >
 Class encapsulating a default epsilon. More...
 

Enumerations

enum  Dune::FloatCmp::CmpStyle { Dune::FloatCmp::relativeWeak , Dune::FloatCmp::relativeStrong , Dune::FloatCmp::absolute , Dune::FloatCmp::defaultCmpStyle = relativeWeak }
 
enum  Dune::FloatCmp::RoundingStyle {
  Dune::FloatCmp::towardZero , Dune::FloatCmp::towardInf , Dune::FloatCmp::downward , Dune::FloatCmp::upward ,
  Dune::FloatCmp::defaultRoundingStyle = towardZero
}
 

Functions

template<class T , CmpStyle style>
bool Dune::FloatCmp::eq (const T &first, const T &second, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, style >::value())
 test for equality using epsilon More...
 
template<class T , CmpStyle style>
bool Dune::FloatCmp::ne (const T &first, const T &second, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, style >::value())
 test for inequality using epsilon More...
 
template<class T , CmpStyle style>
bool Dune::FloatCmp::gt (const T &first, const T &second, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, style >::value())
 test if first greater than second More...
 
template<class T , CmpStyle style>
bool Dune::FloatCmp::lt (const T &first, const T &second, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, style >::value())
 test if first lesser than second More...
 
template<class T , CmpStyle style>
bool Dune::FloatCmp::ge (const T &first, const T &second, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, style >::value())
 test if first greater or equal second More...
 
template<class T , CmpStyle style>
bool Dune::FloatCmp::le (const T &first, const T &second, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, style >::value())
 test if first lesser or equal second More...
 
template<class I , class T , CmpStyle cstyle, RoundingStyle rstyle>
Dune::FloatCmp::round (const T &val, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, cstyle >::value())
 round using epsilon More...
 
template<class I , class T , CmpStyle cstyle, RoundingStyle rstyle>
Dune::FloatCmp::trunc (const T &val, typename EpsilonType< T >::Type epsilon=DefaultEpsilon< T, cstyle >::value())
 truncate using epsilon More...
 

Detailed Description

How to compare floats

When comparing floating point numbers for equality, one often faces the problem that floating point operations are not always exact. For example on i386 the expression

0.2 + 0.2 + 0.2 + 0.2 + 0.2 + 0.2 + 0.2 + 0.2 + 0.2 + 0.2 == 2.0

evaluates to

1.99999999999999977796 == 2.00000000000000000000

which is false. One solution is to compare approximately, using an epsilon which says how much deviation to accept.

The most straightforward way of comparing is using an absolute epsilon. This means comparison for equality is replaced by

abs(first-second) <= epsilon

This has a severe disadvantage: if you have an epsilon like 1e-10 but first and second are of the magnitude 1e-15 everything will compare equal which is certainly not what you want. This can be overcome by selecting an appropriate epsilon. Nevertheless this method of comparing is not recommended in general, and we will present a more robus method in the next paragraph.

There is another way of comparing approximately, using a relative epsilon which is then scaled with first:

abs(first-second) <= epsilon * abs(first)

Of cource the comparison should be symmetric in first and second so we cannot arbitrarily select either first or second to scale epsilon. The are two symmetric variants, relative_weak

abs(first-second) <= epsilon * max(abs(first), abs(second))

and relative_strong

abs(first-second) <= epsilon * min(abs(first), abs(second))

Both variants are good, but in practice the relative_weak variant is preferred. This is also the default variant.

Note
Although using a relative epsilon is better than using an absolute epsilon, using a relative epsilon leads to problems if either first or second equals 0. In principle the relative method can be combined with an absolute method using an epsilon near the minimum representable positive value, but this is not implemented here.

There is a completely different way of comparing floats. Instead of giving an epsilon, the programmer states how many representable value are allowed between first and second. See the "Comparing using integers" section in http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm for more about that.

Interface

To do the comparison, you can use the free functions eq(), ne(), gt(), lt(), ge() and le() from the namespace Dune::FloatCmp. They take the values to compare and optionally an epsilon, which defaults to 8 times the machine epsilon (the difference between 1.0 and the smallest representable value > 1.0) for relative comparisons, or simply 1e-6 for absolute comparisons. The compare style can be given as an optional second template parameter and defaults to relative_weak.

You can also use the class Dune::FloatCmpOps which has eq(), ne(), gt(), lt(), ge() and le() as member functions. In this case the class encapsulates the epsilon and the comparison style (again the defaults from the previous paragraph apply). This may be more convenient if you write your own class utilizing floating point comparisons, and you want the user of you class to specify epsilon and compare style.

Enumeration Type Documentation

◆ CmpStyle

How to compare

Enumerator
relativeWeak 

|a-b|/|a| <= epsilon || |a-b|/|b| <= epsilon

relativeStrong 

|a-b|/|a| <= epsilon && |a-b|/|b| <= epsilon

absolute 

|a-b| <= epsilon

defaultCmpStyle 

the global default compare style (relative_weak)

◆ RoundingStyle

How to round or truncate

Enumerator
towardZero 

always round toward 0

towardInf 

always round away from 0

downward 

round toward \(-\infty\)

upward 

round toward \(+\infty\)

defaultRoundingStyle 

the global default rounding style (toward_zero)

Function Documentation

◆ eq()

template<class T , CmpStyle style>
bool Dune::FloatCmp::eq ( const T &  first,
const T &  second,
typename EpsilonType< T >::Type  epsilon = DefaultEpsilon< T, style >::value() 
)

test for equality using epsilon

Template Parameters
TType of the values to compare
styleHow to compare. This defaults to defaultCmpStyle.
Parameters
firstleft operand of equals operation
secondright operand of equals operation
epsilonThe epsilon to use in the comparison

◆ ge()

template<class T , CmpStyle style>
bool Dune::FloatCmp::ge ( const T &  first,
const T &  second,
typename EpsilonType< T >::Type  epsilon = DefaultEpsilon< T, style >::value() 
)

test if first greater or equal second

Template Parameters
TType of the values to compare
styleHow to compare. This defaults to defaultCmpStyle.
Parameters
firstleft operand of greater-or-equals operation
secondright operand of greater-or-equals operation
epsilonThe epsilon to use in the comparison
Returns
eq(first, second, epsilon) || first > second

this is like first > second, but the region that compares equal with an epsilon is also included

◆ gt()

template<class T , CmpStyle style>
bool Dune::FloatCmp::gt ( const T &  first,
const T &  second,
typename EpsilonType< T >::Type  epsilon = DefaultEpsilon< T, style >::value() 
)

◆ le()

template<class T , CmpStyle style>
bool Dune::FloatCmp::le ( const T &  first,
const T &  second,
typename EpsilonType< T >::Type  epsilon = DefaultEpsilon< T, style >::value() 
)

test if first lesser or equal second

Template Parameters
TType of the values to compare
styleHow to compare. This defaults to defaultCmpStyle.
Parameters
firstleft operand of less-or-equals operation
secondright operand of less-or-equals operation
epsilonThe epsilon to use in the comparison
Returns
eq(first, second) || first < second

this is like first < second, but the region that compares equal with an epsilon is also included

◆ lt()

template<class T , CmpStyle style>
bool Dune::FloatCmp::lt ( const T &  first,
const T &  second,
typename EpsilonType< T >::Type  epsilon = DefaultEpsilon< T, style >::value() 
)

test if first lesser than second

Template Parameters
TType of the values to compare
styleHow to compare. This defaults to defaultCmpStyle.
Parameters
firstleft operand of less-than operation
secondright operand of less-than operation
epsilonThe epsilon to use in the comparison
Returns
ne(first, second, epsilon) && first < second

this is like first < second, but the region that compares equal with an epsilon is excluded

◆ ne()

template<class T , CmpStyle style>
bool Dune::FloatCmp::ne ( const T &  first,
const T &  second,
typename EpsilonType< T >::Type  epsilon = DefaultEpsilon< T, style >::value() 
)

test for inequality using epsilon

Template Parameters
TType of the values to compare
styleHow to compare. This defaults to defaultCmpStyle.
Parameters
firstleft operand of not-equal operation
secondright operand of not-equal operation
epsilonThe epsilon to use in the comparison
Returns
!eq(first, second, epsilon)

◆ round()

template<class I , class T , CmpStyle cstyle, RoundingStyle rstyle>
I Dune::FloatCmp::round ( const T &  val,
typename EpsilonType< T >::Type  epsilon = DefaultEpsilon< T, cstyle >::value() 
)

round using epsilon

Template Parameters
IThe integral type to round to
TType of the value to round
cstyleHow to compare. This defaults to defaultCmpStyle.
rstyleHow to round. This defaults to defaultRoundingStyle.
Parameters
valThe value to round
epsilonThe epsilon to use in comparisons
Returns
The rounded value

Round according to rstyle. If val is already near the mean of two adjacent integers in terms of epsilon, the result will be the rounded mean.

◆ trunc()

template<class I , class T , CmpStyle cstyle, RoundingStyle rstyle>
I Dune::FloatCmp::trunc ( const T &  val,
typename EpsilonType< T >::Type  epsilon = DefaultEpsilon< T, cstyle >::value() 
)

truncate using epsilon

Template Parameters
IThe integral type to truncate to
TType of the value to truncate
cstyleHow to compare. This defaults to defaultCmpStyle.
rstyleHow to truncate. This defaults to defaultRoundingStyle.
Parameters
valThe value to truncate
epsilonThe epsilon to use in comparisons
Returns
The truncated value

Truncate according to rstyle. If val is already near an integer in terms of epsilon, the result will be that integer instead of the real truncated value.

Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Mar 27, 23:31, 2024)