# [Python-Dev] math.areclose ...?

Tue Feb 7 00:51:29 CET 2006

```Alex Martelli wrote:
> On 2/6/06, Aahz <aahz at pythoncraft.com> wrote:
>    ...
>
>>>def areclose(x, y, relative_err = 1.e-5, absolute_err=1.e-8):
>>>  diff = abs(x - y)
>>>  ave = (abs(x) + abs(y))/2
>>>  return diff < absolute_err or diff/ave < relative_err
>>>
>>>Also, separating the two terms with 'or' rather than '+' makes the
>>>two error terms mean more what they are named. The '+' mixes the two
>>>effects and even though the result is basically the same, it makes it
>>>difficult to explain when the test will be true.
>>
>>Yes, that's a big help.  I was a bit concerned that this would have no
>>utility for numbers with large magnitude.  Alex, given your focus on
>>Python readability, I'm a bit surprised you didn't write this to start
>>with!
>
>
> As I said, I was just copying the definition in Numeric, which is
> well-tried by long use.  Besides, this "clear expression" could
> present problems, such as possible overflows or divisions by zero when
> correctness even more.

It looks like the definition from Numeric measures relative error while
the above measure relative deviation.  I'm not sure which one would be
desirable or if they are interchangeable.  I was looking up relative
error to try and understand the above at the following site.

http://mathforum.org/library/drmath/view/65797.html

As far as beginner vs advanced users are concerned I think that is a
matter of documentation especially when intermediate users are concerned
which I believe are the majority.

Possibly something like the following would be suitable... ?

"""
The absolute error is the absolute value of the difference between
the accepted value and the measurement.

Absolute error = abs( Observed - Accepted value )

The Relative err is the percentage of absolute err relative to the
accepted value.

Absolute error
Relative error = -------------- x 100%
Accepted value
"""

def isclose(observed, accepted, abs_err, rel_err):
"""Determine if the accuracy of a observed value is close
to an accepted value"""
diff = abs(observed, accepted)
if diff < abs_err: return True
try:
return 100 * abs_diff / accepted < rel_err
except ZeroDivisionError:
pass
return False

Cheers,