comparison common/floateq.py @ 355:430c9e92cd23

Added common directory
author Joseph Turian <turian@iro.umontreal.ca>
date Thu, 19 Jun 2008 16:12:29 -0400
parents
children
comparison
equal deleted inserted replaced
354:d580b3a369a4 355:430c9e92cd23
1 #
2 # Determine if floating point numbers are very close
3 ###########
4
5 import math
6
7 DEFAULT_SANITY_CHECK_EPSILON = 1e-6
8
9 def floateq(a, b, epsilon=DEFAULT_SANITY_CHECK_EPSILON):
10 """
11 Compare two floats, with some epsilon tolerance.
12 """
13 return absolute_relative_error(a, b) < epsilon
14
15 def absolute_relative_error(a, b, epsilon=DEFAULT_SANITY_CHECK_EPSILON):
16 return abs(a - b) / (abs(a) + abs(b) + epsilon)
17
18 def double_epsilon_multiplicative_eq(a, b, epsilon=DEFAULT_SANITY_CHECK_EPSILON):
19 """
20 Determine if doubles are equal to within a multiplicative factor of
21 L{epsilon}.
22 @note: This function should be preferred over
23 L{double_epsilon_additive_eq}, unless the values to be compared may
24 have differing signs.
25 @precondition: sign(a) == sign(b)
26 @rtype: bool
27 """
28 if a == b: return True
29 if a == 0 and b == 0: return True
30 assert a != 0
31 assert b != 0
32 assert sign(a) == sign(b)
33 if a > b: d = a / b
34 else: d = b / a
35 assert d >= 1
36 return True if d <= 1 + SANITY_CHECK_EPSILON else False
37
38 def double_epsilon_additive_eq(a, b):
39 """
40 Determine if doubles are equal to within an additive factor of
41 L{SANITY_CHECK_EPSILON}.
42 @note: Prefer L{double_epsilon_multiplicative_eq} to this function
43 unless the values to be compared may have differing signs.
44 """
45 if a == b: return True
46 if a == 0 and b == 0: return True
47 assert sign(a) != sign(b) # Should use SANITY_CHECK_EPSILON
48 d = math.fabs(a - b)
49 return d <= SANITY_CHECK_EPSILON