[Python-ideas] Way to check for floating point "closeness"?

Chris Barker chris.barker at noaa.gov
Thu Jan 15 20:45:22 CET 2015


On Thu, Jan 15, 2015 at 9:42 AM, Ron Adam <ron3200 at gmail.com> wrote:

> The conservative, "safe" way to handle this is to just treat the error
>> function as symmetrical
>>
> What if we are not concerned with the location two points are relative to
> zero?


not sure what location two points are relative to zero means.

Or if the numbers straddle zero?


Good catch -- at least if the numbers are symmetric to zero -- i.e. a ==
-b, then they will never be "close" according to our working definition of
relative tolerance:

a = -b

err == 2*a
abs_tol = rel_tol * a

#rel_tol is small and positive

abs_tol is always smaller than a, so always smaller than the error, so
never "close".

In fact, this is true for any numbers that straddle zero:

err  == abs(a,b)

abs_tol  = rel_tol* max(abs(a), abs(b))

abs_tol <= err  # provided 0< rel_tol < 1

So I was thinking the issues were near zero, but they actually are for any
time:

a <= 0 <= b  (or  b <= 0 <= a )

that is, any time they straddle or include zero.

In this case, you need an absolute tolerance defined.

Still figuring out how to use that and provide a smooth transition...

Steven, does your code address this somehow?

-Chris












>
> and always report the larger of the two relative
>
>> errors (excluding the case where the denominator is 0, in which case
>> the relative error is either 100% or it doesn't exist). Worst case, you
>> may reject some values which you should accept, but you will never
>> accept any values that you should reject.
>>
>
> Consider two points that are a constant distance apart, but moving
> relative to zero.  Their closeness doesn't change, but the relative error
> in respect to each other (and zero) does change.
>
> There is an implicit assumption that the number system used and the origin
> the numbers are measured from are chosen and relate to each other in some
> expected way.
>
> When ever you supply all the numbers, like in a test, it's not a problem,
> you just give good numbers.
>
>
>  Note that you would never compare to an expected value of zero.
>>>
>>
>> You *cannot* compare to an expected value of zero, but you certainly can
>> be in a situation where you would like to: math.sin(math.pi) should
>> return 0.0, but doesn't, it returns 1.2246063538223773e-16 instead. What
>> is the relative error of the sin function at x = math.pi?
>>
>>
>>       relerr(a - b, expected_feet) < tolerance   # relative feet from b
>>>      relerr(a - 0, expected_feet) < tolerance   # relative feet from zero
>>>      relerr(a - b, ulp)    # percentage of ulp's
>>>
>>
>> I don't understand what you think these three examples are showing.
>>
>
> A percentage of an expected distance.
>
>   Error of two points compared to a specific distance.
>
>     >>> relerr(5 - -5, 10)
>     0.0
>
> I think unless you use decimal, the ulp example will either be zero or
> some large multiple of ulp.
>
>
>  Take a look at the statistics test suite.
>>
>
> I definitely will. :-)
>
>  I'll be the first to admit
>> that the error tolerances are plucked from thin air, based on what I
>> think are "close enough", but they show how such a function might work:
>>
>> * you provide two values, and at least one of an absolute error
>>    tolerance and a relative error;
>> * if the error is less than the error(s) you provided, the test
>>    passes, otherwise it fails;
>> * NANs and INFs are handled apprpriately.
>>
>>
>>        is_close(218.345, 220, 1, .05)   # OHMs
>>>       is_close(a, b, ULP, 2)     # ULPs
>>>       is_close(a, b, AU, .001)   # astronomical units
>>>
>>>
>>> I don't see anyway to generalise those with just a function.
>>>
>>
>> Generalise in what way?
>>
>
> I meant a function that would work in many places without giving some sort
> size and tolerance hints.
>
> Given two floating point numbers and noting else, I don't think you can
> tell if they represent something that is close without assuming some sort
> of context.  At best, you need to assume the distance from zero and the
> numbers used are chosen to give a meaningful return value.  While that can
> sometimes work, I don't think you can depend on it.
>
>
>  By using objects we can do a bit more.  I seem to recall coming across
>>> measurement objects some place.  They keep a bit more context with them.
>>>
>>
>> A full system of <value + unit> arithmetic is a *much* bigger problem
>> than just calculating error estimates correctly, and should be a
>> third-party library before even considering it for the std lib.
>>
>
> Yes, I agree.  There are a few of them out there already.
>
> Cheers,
>    Ron
>
>
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris.Barker at noaa.gov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150115/b317d77d/attachment-0001.html>


More information about the Python-ideas mailing list