New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add nroot function to math #71540
Comments
For bpo-27181 (add geometric mean to statistics module), I need a function to calculate nth roots that is more accurate than pow(x, 1/n). E.g. math.pow(1000, 1/3) returns 9.999999999999998 instead of 10.0. I have a pure-Python implementation of nroot which I believe is satisfactory, and I could use that, but I'm uncomfortable about making it a public function in statistics. It's not really a statistics function, its more general, and I think it would be generally useful enough that it should go into math. To recap the options:
I'm willing to do the first if there is no other alternative, reluctant to do the second, and think that the third is the most useful, but I don't have the ability to write a pure C version. If the math library was written in Python that would be the obvious place for it. |
I suggested on python-ideas that the math module be given a pure-Python front end. Guido wasn't too keen on that idea, so I won't push for it. He did agree that having nroot in math was a reasonable idea. If I attach a pure Python implementation and tests, is anyone interested in porting it to C? I'm afraid that "Hello World" is about the level of my C skills. As far as the geometric mean goes, Serhiy refers to a comment about the naive calculation likely overflowing. That's true, but I don't intend to do a naive calculation. In any case, even if I don't end up use nroot for geometric mean, it will still be useful as a more explicit and more accurate alternative to pow(x, 1/n). |
For general use I think it would be more useful to make pow() supporting fractions (using as_integer_ration()). >>> math.pow(1000, fractions.Fraction(2, 3))
100.0
>>> math.pow(100000, decimal.Decimal('0.4'))
100.0 |
If this ends up going forward (and I'm don't believe a good case has been made), I would prefer the function to be called "nth_root" which is unequivocal and readable (it is also close to what Matlab uses: http://www.mathworks.com/help/matlab/ref/nthroot.html ) It seems that Matlab's reason for inclusion doesn't have anything to do with precision; instead, they say "While power is a more efficient function for computing the roots of numbers, in cases where both real and complex roots exist, power returns only the complex roots. In these cases, use nthroot to obtain the real roots." Mathematica uses Surd[n, x] for that purpose. Outside of Matlab and Mathematica, I'm not seeing this function elsewhere (on my calculator, in Java math, etc.). This suggests that the need is minimal. As an alternative, we could follow the model used in the itertools module and include "recipes" for functions that don't meet that bar for inclusion in the standard library. Here's one recipe I found after a few seconds of googling: from decimal import Decimal, getcontext
def nthroot (n, A, precision):
getcontext().prec = precision
n = Decimal(n)
x_0 = A / n #step 1: make a while guess.
x_1 = 1 #need it to exist before step 2
while True:
#step 2:
x_0, x_1 = x_1, (1 / n)*((n - 1)*x_0 + (A / (x_0 ** (n - 1))))
if x_0 == x_1:
return x_1 Out of Steven's original suggestions, I most prefer "leave nth_root in statistics as a private function". |
Note that the very popular TI graphics calculators have had a distinct nth-root function at least since the TI-83. It's a minor convenience there. I'm +0 on adding it to Python's math module, which means not enough to do any work ;-) Note that if it is added to Short of that, a private function in |
[Raymond, quoting Matlab]
Yes, this would be the main motivation for me, too, if only to be able to answer the many StackOverflow questions like this one: http://stackoverflow.com/questions/30923838/how-to-get-the-real-cube-root-of-a-negative-number-in-python3 +1 for a private function in the statistics module for now. |
[Serhiy]
It's fine, so long as it's only being called once or twice at the end of the calculation (it's even helpful to have the last operation be an nth root call, since that's a contracting operation that tends to reduce relative error). It's calling it on every single item in the input list and *then* multiplying that would be bad. |
On Mon, Jun 20, 2016 at 09:02:09PM +0000, Tim Peters wrote:
Likewise HP calculators ("xroot") and at least one Javascript library. But seeing as there isn't that much interest, I'll stick with a private |
Is this still needed? It was requested for bpo-27181, which has been resolved by now. |
[Irit]
It's not needed for geometric_mean. It's still a reasonable feature request, but it would be non-trivial effort to put a good quality implementation together - C doesn't have this function, so we can't simply wrap it like we did for cbrt. But at least IEEE 754 does specify a "rootn" function, so we know what the behaviour should be in all the various special cases. cbrt probably covers a good proportion of use-cases for rootn (those that weren't already satisfied by sqrt). NumPy seems to have survived without needing a rootn function so far, which seems like an indication that it's not a really pressing need. Let's close, and re-open or open a new issue if someone discovers another good use-case. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: