[Python-ideas] PEP 485: A Function for testing approximate equality

Chris Barker - NOAA Federal chris.barker at noaa.gov
Sat Jan 24 02:41:17 CET 2015


> 2) use of max() instead of + to combine the relative and absolute
> tolerance.

In fact, the code uses "or", but in amounts to the same thing -- if
the difference is within either the relative or absolute tolerance,
it's "close".

> I understand that you find the + conceptually offensive,
> but I'm not really sure why -- max() is maybe a bit better, but it
> seems like much of a muchness to me in practice.

Actually I agree with you here -- I think I've said elsewhere that I
expect in practice people will set their tolerance to an order of
magnitude, so even a factor of two doesn't much matter. But I see no
advantage to doing it that way (except perhaps as a vectorized
computation, which this is not)

> It might be worth switching to + just for compatibility.

Well, the other difference is that numpy's version sets a default
non-zero absolute tolerance. I think this is fatally wrong. Way too
easy to get something really wrong for small values.

Once we've done something incompatible, why not make it cleaner? And I
see little reason for compatability for it's own sake.

> However, a lot of the benefit of numpy.allclose is that it will do
> something mostly-reasonable out-of-the-box even if the users haven't
> thought things through at all. 99% of the benefit of having something
> like this available is that it makes it easy to write tests, and 99%
> of the benefit of a test is that it exists and makes sure that your
> values are not wildly incorrect. So that's nice. BUT if you want that
> kind of out-of-the-box utility then you need to have some kind of
> sensible default for comparisons to zero.

I spent some time thinking about this, and my first version did have a
default abs_tol to cover the near-zero case. But it would be
absolutely the wrong thing for comparing small values.

If you can think of defaults and an algorithm that would work well for
large and small values and also comparison to zero, I'd be all for it.

> (I just did a quick look at uses of python code uses of
> assertAlmostEqual on github, and in my unscientific survey of reading
> the first page of results, 30.4% of the calls were comparisons against
> zero. IMO asking all these people to specify tolerances by hand on
> every call is not very nice.)

Hmm  -- my thinking is that at least those tests would immediately not
work, but agreed, nicer for defaults to work for common cases.

> One option would be to add a zero_tol argument, which is an absolute
> tolerance that is only applied if expected == 0.

Here is where I'm not sure: is there only an issue with comparing to
exactly zero? Or can vet small numbers under flow and cause the same
problem?

> [And a nice possible side-effect of this is that numpy could
> conceivably then add such an argument as well "for compatibility with
> the stdlib", and possibly use this as a lever to fix it's weird
> allclose/assert_allclose discrepancy. The main blocker to making them
> consistent is that there is lots of code in the wild that assumes
> allclose handles comparisons-to-zeros right, and also lots of code
> that assumes that assert_allclose is strict with very-small non-zero
> numbers, and with only rtol and atol you can't get both of these
> behaviours simultaneously.]

I'm not sure it's much of an incentive for ghe Stalin, but sure, that
would be nice.

> I'd strongly consider expanding the scope of this PEP a bit so that
> it's proposing both a relative/absolute-error-based function *and* a
> ULP-difference function.

I responded to this elsewhere.

Thanks for your input.

-Chris


More information about the Python-ideas mailing list