Class FloatComparison is used to test a == b, a < b, a <= b, a > b, a >= b and a != b when a and b are floating-point numbers, complex numbers, or NumPy arrays.
Because of possible round-off errors in the numbers, the tests are performed approximately with a prescribed tolerance.
For example, a==b is true if abs(a-b) < atol + rtol*abs(b). The atol parameter comes into play when |a| and |b| are large. (It would be mathematically more appealing to have rtol*max(abs(a), abs(b)), but float_eq is used with a is close to b so the max function is not necessary.)
If the desired test is |a-b| < eps, set atol=eps and rtol=0. If a relative test is wanted, |(a-b)/b| < eps, set atol=0 and rtol=eps.
The test a < b is performed as a < b + atol (a can be larger than b, but not more than atol). A corresponding relative test reads a/abs(b) < 1 + rtol. These are combined into a common test a < b + atol + rtol*abs(b). Similarly, a > b if a > b - atol (i.e., a can be less than b, but not less than b-atol). The relative test is then a/abs(b) > 1 - rtol. These are combined to a > b - a tol - rtol*abs(b). The >= and <= operators are the same as > and < when tolerances are used.
Class FloatComparison can be used directly, or the convenience names float_eq, float_ne, float_lt, float_le, float_gt and float_ge for the various operators can be used instead. For example, float_eq is a FloatComparison object for the equality operator.
Here is an interactive example:
>>> from FloatComparison import FloatComparison, float_eq, float_ne, float_lt, float_le, float_gt, float_ge
>>> float_eq.get_absolute_tolerance() # default
1e-14 >>> float_eq.get_relative_tolerance() # default 1e-14 >>> float_eq.set_absolute_tolerance(1E-2) >>> float_eq.set_relative_tolerance(1E-2) >>> print float_eq a == b, computed as abs(a-b) < 0.01 + 0.01*abs(b) >>> >>> float_eq(2.1, 2.100001) True >>> # tolerances can be given as part of the test: >>> float_ne(2.1, 2.100001, atol=1E-14, rtol=1E-14) True
>>> float_gt(2.0999999, 2.1000001) # not greater with strict tol
False
>>> print float_gt
a > b, computed as a > b - 1e-14 - 1e-14*abs(b)
>>> float_gt.set_absolute_tolerance(1E-4)
>>> print float_gt
a > b, computed as a > b - 0.0001 - 1e-14*abs(b)
>>> float_gt(2.0999999, 2.1000001) # greater with less strict tol
True
>>> import numpy
>>> a = numpy.array([2.1, 2.1000001])
>>> b = numpy.array([2.100001, 2.0999999])
>>> float_eq(a, b)
True
>>> float_lt(a, b) # not less with strict tol
False
>>> float_lt(a, b, atol=1E-2, rtol=1E-2)
True
>>> # use class FloatComparison directly:
>>> compare = FloatComparison('==', atol=1E-3, rtol=1E-3)
>>> compare(2.1, 2.100001) # __call__ directs to compare.eq
True
>>> compare.gt(2.1, 2.100001) # same tolerance
True
>>> compare.ge(a, b)
False
The __call__ method calls eq, ne, lt, le, gt, or ge, depending on the first argument to the constructor.
Methods
__call__(a, b[, rtol, atol]) | Compares a with b: a == b, a!= b, a < b, etc., depending |
eq(a, b[, rtol, atol]) | Tests a == b with tolerance. |
ge(a, b[, rtol, atol]) | Tests a >= b with tolerance. |
get_absolute_tolerance() | |
get_relative_tolerance() | |
gt(a, b[, rtol, atol]) | Tests a > b with tolerance. |
le(a, b[, rtol, atol]) | Tests a <= b with tolerance. |
lt(a, b[, rtol, atol]) | Tests a < b with tolerance. |
ne(a, b[, rtol, atol]) | Tests a != b with tolerance. |
set_absolute_tolerance(atol) | |
set_relative_tolerance(rtol) |
Compares a with b: a == b, a!= b, a < b, etc., depending on how this FloatComparison was initialized. a and b can be numbers or arrays. The comparison is actually performed in the methods eq, ne, lt, le, etc.
operation is ‘==’, ‘<’, ‘<=’, ‘>’, ‘>=’ or ‘!=’. The value determines what operation that __call__ performs.
rtol: relative tolerance, atol: absolute tolerance. a==b is true if abs(a-b) < atol + rtol*abs(b). atol comes into play when abs(b) is large.