1
+ import math
2
+
1
3
import numpy as np
2
4
3
5
from pandas.core.dtypes.missing import isna, array_equivalent
@@ -38,13 +40,6 @@ cdef bint is_dictlike(obj):
38
40
return hasattr (obj, ' keys' ) and hasattr (obj, ' __getitem__' )
39
41
40
42
41
- cdef bint decimal_almost_equal(double desired, double actual, int decimal):
42
- # Code from
43
- # http://docs.scipy.org/doc/numpy/reference/generated
44
- # /numpy.testing.assert_almost_equal.html
45
- return abs (desired - actual) < (0.5 * 10.0 ** - decimal)
46
-
47
-
48
43
cpdef assert_dict_equal(a, b, bint compare_keys = True ):
49
44
assert is_dictlike(a) and is_dictlike(b), (
50
45
" Cannot compare dict objects, one or both is not dict-like"
@@ -63,7 +58,7 @@ cpdef assert_dict_equal(a, b, bint compare_keys=True):
63
58
64
59
65
60
cpdef assert_almost_equal(a, b,
66
- check_less_precise = False ,
61
+ rtol = 0.5e-5 , atol = 0.5e-5 ,
67
62
bint check_dtype = True ,
68
63
obj = None , lobj = None , robj = None ):
69
64
"""
@@ -73,25 +68,23 @@ cpdef assert_almost_equal(a, b,
73
68
----------
74
69
a : object
75
70
b : object
76
- check_less_precise : bool or int, default False
77
- Specify comparison precision.
78
- 5 digits (False) or 3 digits (True) after decimal points are
79
- compared. If an integer, then this will be the number of decimal
80
- points to compare
71
+ rtol : float, default 0.5e-5
72
+ Relative tolerance.
73
+ atol : float, default 0.5e-5
74
+ Absolute tolerance.
81
75
check_dtype: bool, default True
82
- check dtype if both a and b are np.ndarray
76
+ check dtype if both a and b are np.ndarray.
83
77
obj : str, default None
84
78
Specify object name being compared, internally used to show
85
- appropriate assertion message
79
+ appropriate assertion message.
86
80
lobj : str, default None
87
81
Specify left object name being compared, internally used to show
88
- appropriate assertion message
82
+ appropriate assertion message.
89
83
robj : str, default None
90
84
Specify right object name being compared, internally used to show
91
- appropriate assertion message
85
+ appropriate assertion message.
92
86
"""
93
87
cdef:
94
- int decimal
95
88
double diff = 0.0
96
89
Py_ssize_t i, na, nb
97
90
double fa, fb
@@ -102,8 +95,6 @@ cpdef assert_almost_equal(a, b,
102
95
if robj is None :
103
96
robj = b
104
97
105
- assert isinstance (check_less_precise, (int , bool ))
106
-
107
98
if isinstance (a, dict ) or isinstance (b, dict ):
108
99
return assert_dict_equal(a, b)
109
100
@@ -161,8 +152,7 @@ cpdef assert_almost_equal(a, b,
161
152
162
153
for i in range (len (a)):
163
154
try :
164
- assert_almost_equal(a[i], b[i],
165
- check_less_precise = check_less_precise)
155
+ assert_almost_equal(a[i], b[i], rtol = rtol, atol = atol)
166
156
except AssertionError :
167
157
is_unequal = True
168
158
diff += 1
@@ -194,24 +184,11 @@ cpdef assert_almost_equal(a, b,
194
184
# inf comparison
195
185
return True
196
186
197
- if check_less_precise is True :
198
- decimal = 3
199
- elif check_less_precise is False :
200
- decimal = 5
201
- else :
202
- decimal = check_less_precise
203
-
204
187
fa, fb = a, b
205
188
206
- # case for zero
207
- if abs (fa) < 1e-5 :
208
- if not decimal_almost_equal(fa, fb, decimal):
209
- assert False , (f' (very low values) expected {fb:.5f} '
210
- f' but got {fa:.5f}, with decimal {decimal}' )
211
- else :
212
- if not decimal_almost_equal(1 , fb / fa, decimal):
213
- assert False , (f' expected {fb:.5f} but got {fa:.5f}, '
214
- f' with decimal {decimal}' )
189
+ if not math.isclose(fa, fb, rel_tol = rtol, abs_tol = atol):
190
+ assert False , (f" expected {fb:.5f} but got {fa:.5f}, "
191
+ f" with rtol={rtol}, atol={atol}" )
215
192
return True
216
193
217
194
raise AssertionError (f" {a} != {b}" )
0 commit comments