<div dir="ltr">Steven, I can't take it any longer. It is just absolutely ridiculous how much discussion we've already seen about a function that's a single line of code. I'll give you three choices. You can vote +1, 0 or -1. No more discussion. If you still keep picking on details I'll just kill the PEP to be done with the discussion.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Feb 5, 2015 at 8:48 PM, Steven D'Aprano <span dir="ltr"><<a href="mailto:steve@pearwood.info" target="_blank">steve@pearwood.info</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Thu, Feb 05, 2015 at 05:12:32PM -0800, Chris Barker wrote:<br>
> On Thu, Feb 5, 2015 at 4:44 PM, Steven D'Aprano <<a href="mailto:steve@pearwood.info">steve@pearwood.info</a>> wrote:<br>
><br>
> > > 0.0 < rel_tol < 1.0)<br>
> ><br>
> > I can just about see the point in restricting rel_tol to the closed<br>
> > interval 0...1, but not the open interval. Mathematically, setting the<br>
> > tolerance to 0 should just degrade gracefully to exact equality,<br>
><br>
> sure -- no harm done there.<br>
><br>
> > and a tolerance of 1 is nothing special at all.<br>
><br>
> well, I ended up putting that in because it turns out with the "weak" test,<br>
> then anything compares as "close" to zero:<br>
<br>
</span>Okay. Maybe that means that the "weak test" is not useful if one of the<br>
numbers is zero. Neither is a relative tolerance, or an ULP calculation.<br>
<span class=""><br>
<br>
> tol>=1.0<br>
> a = anything<br>
> b = 0.0<br>
> min( abs(a), abs(b) ) = 0.0<br>
> abs(a-b) = a<br>
<br>
</span>That is incorrect. abs(a-b) for b == 0 is abs(a), not a.<br>
<span class=""><br>
> tol * a >= a<br>
> abs(a-b) <= tol * a<br>
<br>
</span>If and only if a >= 0. Makes perfect mathematical sense, even if it's<br>
not useful. That's an argument for doing what Bruce Dawson says, and<br>
comparing against the maximum of a and b, not the minimum.<br>
<span class=""><br>
<br>
> Granted, that's actually the best argument yet for using the strong test --<br>
> which I am suggesting, though I haven't thought out what that will do in<br>
> the case of large tolerances.<br>
<br>
</span>It should work exactly the same as for small tolerances, except larger<br>
*wink*<br>
<span class=""><br>
<br>
> > Values larger than 1 aren't often useful, but there really is no reason<br>
> > to exclude tolerances larger than 1. "Give or take 300%" (ie.<br>
> > rel_tol=3.0) is a pretty big tolerance, but it is well-defined: a<br>
> > difference of 299% is "close enough", 301% is "too far".<br>
> ><br>
><br>
> yes it is, but then the whole weak vs string vs asymmetric test becomes<br>
> important.<br>
<br>
</span>Um, yes? I know Guido keeps saying that the difference is unimportant,<br>
but I think he is wrong: at the edges, the way you determine "close to"<br>
makes a difference whether a and b are considered close or not. If you<br>
care enough to specify a specific tolerance (say, 2.3e-4), as opposed to<br>
plucking a round number out of thin air, then you care about the edge<br>
cases. I'm not entirely sure what to do about it, but my sense is that<br>
we should do something.<br>
<span class=""><br>
<br>
> From my math the "delta" between the weak and strong tests goes<br>
> with  tolerance**2 * max(a,b).  So if the tolerance is >=1, then it makes a<br>
> big difference which test you choose. IN fact:<br>
><br>
> Is a within 300% of b makes sense, but "are a and b within 300% of<br>
> each-other" is poorly defined.<br>
<br>
</span>No more so that "a and b within 1% of each other". It's just a<br>
short-hand. What I mean by "of each other" is the method recommended by<br>
Bruce Dawson, use the larger of a and b, what Boost(?) and you are<br>
calling the "strong test".<br>
<br>
<br>
[...]<br>
<span class="">> > Negative error tolerances, on the other hand, do seem to be meaningless<br>
> > and should be prevented.<br>
><br>
><br>
> you could just take the abs(rel_tol), but really?  what's the point?<br>
<br>
</span>No no, I agree with you that tolerances (relative or absolute) should<br>
prohibit negative values. Or complex ones for that matter.<br>
<span class=""><br>
<br>
> > (E.g. "guess the number of grains of sand on this beach".) Any upper<br>
> > limit you put in is completely arbitrary,<br>
><br>
><br>
> somehow one doesn't feel arbitrary to me -- numbers aren't close if the<br>
> difference between them is larger than the largest of the numbers -- not<br>
> arbitrary, maybe unneccesary , but not arbirtrary<br>
<br>
</span>Consider one way of detecting outliers in numeric data: any number more<br>
than X standard deviations from the mean in either direction may be an<br>
outlier.<br>
<br>
py> import statistics<br>
py> data = [1, 2, 100, 100, 100, 101, 102, 103, 104, 500, 100000]<br>
py> m = statistics.mean(data)<br>
py> tol = 3*statistics.stdev(data)<br>
py> [x for x in data if abs(x-m) > tol]<br>
[100000]<br>
py> m, tol, tol/m<br>
(9201.181818181818, 90344.55455462009, 9.818798969508077)<br>
<br>
tol/m is, of course, the error tolerance relative to m, which for the<br>
sake of the argument we are treating as the "known value": anything more<br>
than 9.818... times the mean is probably an outlier.<br>
<br>
Now, the above uses an absolute tolerance, but I should be able to get<br>
the same results from a relative tolerance of 9.818... depending on<br>
which is more convenient to work with at the time.<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
--<br>
Steve<br>
_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" target="_blank">http://python.org/psf/codeofconduct/</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br><div class="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido">python.org/~guido</a>)</div>
</div>