GeezerVison is showing github.com — Let math.nextafter() compute multiple steps at a time. · Issue #94906 · python/cpython
Let math.nextafter() compute multiple steps at a time. #94906DescriptionSometimes math.nextafter() needs to be applied multiple times in succession.
x = nextafter(nextafter( nextafter(x, inf), inf), inf) # Three steps up
It would be nice if the function supported this directly:
x = nextafter(x, inf, n=3)
The implementation would just be a for-loop:
def newnextafter(x, y, /, *, n=1):
'Return the floating-point value n steps after x towards y.'
for i in range(n):
x = nextafter(x, y)
return x
The formal paramater can be just n or the longer but more descriptive steps.
Linked PRs
Activitymdickinson commented on Jul 17, 2022 This feels like a needless expansion of the API to me; I don't think I've ever encountered a use-case for this. On the rare occasions that such a use-case turns up, what's wrong with the for loop, or with adding an integer multiple of math.ulp(x) to x?
-1 from me. Reacted by Serhiy Storchaka and SycamoreLeaf rhettinger commented on Jul 17, 2022 ContributorAuthor More actions mdickinson commented on Jul 17, 2022 Sure, I don't doubt that you had a genuine need, but that need is trivially addressed with a for loop. My use of "needless" referred to the expansion of the API. You needing the functionality is not the same thing as the math module needing to support the functionality directly.
Sorry, but I don't see this use-case as valuable enough or common enough to warrant expanding the math.nextafter API.
I'm also concerned that this might be a performance trap: a user could easily write nextafter(x, y, steps=10**6) without realising that that means a million invocations of nextafter internally. With an explicit for loop, the effect on running time is much more obvious. serhiy-storchaka commented on Jul 17, 2022 I concur with @mdickinson. It is too niche feature, and it is not difficult to implement a wrapper in Python. BTW, the case you found is in tests. rhettinger commented on Jul 17, 2022 ContributorAuthor More actions I wish this wasn't dismissed so casually. All uses of nextafter() are "niche". There are only a handful of people who will ever use it.
I submitted the feature request because I needed to write the replacement function in pure Python (much like the example I posted above) and it was distracting and felt amiss, like something the should have already have been built in to a higher level language.
I wrote the function while working on another problem and had casually created an incorrect result along the way:
>>> sixth_largest_random = 1.0 - 6 * ulp(1.0)
>>> sixth_largest_random
0.9999999999999987
Fortunately, I spotted the problem before going too far with it and wrote the above function giving the correct answer:
>>> sixth_largest_random = newnextafter(1.0, -inf, n=6)
>>> sixth_largest_random
0.9999999999999993
The entire side trip was distracting and annoying. It took the focus away for the error analysis I was working on at the time.
The proposal is an easy thing to do. It isn't even slightly confusing. It would be handy when needed by the few who ever use this function. I don't see any downside.
Note, in numpy and scipy, most interesting functions have many options. That seems to work well for them. But in Python, there seems to be an urge to fight against the simplest of options as "unnecessary API expansion". Reacted by Handell and Goncalo Gomes matthiasgoergens commented on Aug 15, 2022 Reacted by Goncalo Gomes, amirsharif and Stefan Pochmann ambv commented on Apr 24, 2023 Removing "easy" for now as this needs a resolution between the two maintainers of the math module. mblahay commented on Apr 24, 2023 @rhettinger @mdickinson
If the goal here is to produce a one line implementation capable of looping the execution of math.next after, it can be achieved using the reduce function from func tools.
from math import nextafter,inf
from functools import reduce
reduce(nextafter,[-inf]*6,1.0)
The starting point, 1.0, is the third argument, then you must provide an iterator that outputs the direction of nextafter for the desired number of times, in this case I use a list and duplicate -inf 6 times. rhettinger commented on Apr 25, 2023 ContributorAuthor More actions
Removing "easy" for now as this needs a resolution between the two maintainers of the math module.
FWIW, I only care about this a tiny bit. Though I think it would be nice to have, I won't lose any sleep if this gets closed. matthiasgoergens commented on Apr 25, 2023 mdickinson commented on May 20, 2023 matthiasgoergens commented on May 20, 2023
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|