Skip to content
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 math.cbrt() function: Cube Root #88523

Closed
AjithRamachandran mannequin opened this issue Jun 9, 2021 · 13 comments
Closed

Add math.cbrt() function: Cube Root #88523

AjithRamachandran mannequin opened this issue Jun 9, 2021 · 13 comments
Assignees
Labels
3.11 stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@AjithRamachandran
Copy link
Mannequin

AjithRamachandran mannequin commented Jun 9, 2021

BPO 44357
Nosy @malemburg, @rhettinger, @mdickinson, @vstinner, @serhiy-storchaka, @AjithRamachandran
PRs
  • bpo-44357:Add math.cbrt() function: Cube Root #26622
  • 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:

    assignee = 'https://github.com/mdickinson'
    closed_at = <Date 2021-06-10.16:43:16.244>
    created_at = <Date 2021-06-09.07:45:49.555>
    labels = ['type-feature', 'library', '3.11']
    title = 'Add math.cbrt() function: Cube Root'
    updated_at = <Date 2021-06-16.12:21:53.430>
    user = 'https://github.com/AjithRamachandran'

    bugs.python.org fields:

    activity = <Date 2021-06-16.12:21:53.430>
    actor = 'mark.dickinson'
    assignee = 'mark.dickinson'
    closed = True
    closed_date = <Date 2021-06-10.16:43:16.244>
    closer = 'mark.dickinson'
    components = ['Library (Lib)']
    creation = <Date 2021-06-09.07:45:49.555>
    creator = 'AjithRamachandran'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 44357
    keywords = ['patch']
    message_count = 13.0
    messages = ['395388', '395396', '395399', '395405', '395411', '395415', '395417', '395418', '395420', '395421', '395430', '395553', '395554']
    nosy_count = 7.0
    nosy_names = ['lemburg', 'rhettinger', 'mark.dickinson', 'vstinner', 'stutzbach', 'serhiy.storchaka', 'AjithRamachandran']
    pr_nums = ['26622']
    priority = 'normal'
    resolution = None
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue44357'
    versions = ['Python 3.11']

    @AjithRamachandran AjithRamachandran mannequin added 3.10 stdlib Python modules in the Lib dir type-feature A feature request or enhancement labels Jun 9, 2021
    @serhiy-storchaka
    Copy link
    Member

    serhiy-storchaka commented Jun 9, 2021

    See also bpo-27353.

    @serhiy-storchaka serhiy-storchaka added 3.11 and removed 3.10 labels Jun 9, 2021
    @mdickinson
    Copy link
    Member

    mdickinson commented Jun 9, 2021

    +1. This is part of C99, so if it's also supported by Visual Studio, then this seems like a no-brainer. If it's _not_ also supported by Visual Studio, or if there are implementations that have serious numerical problems (as was the case with fma) we'll need to write our own fallback implementation, which is less simple.

    In principle it should be relatively easy for a math library to provide a correctly-rounded cbrt.

    @mdickinson
    Copy link
    Member

    mdickinson commented Jun 9, 2021

    BTW, to forestall questions about adding cmath.cbrt: it's not obvious how to extend the real cube root function to a complex cube root, so it might make sense to wait for actual use-cases before doing so.

    The issue is that the most natural way to define a complex cube root would use a branch cut along the negative real axis (the same branch cut that cmath.sqrt and cmath.log use). But then the principal branch would *not* be an extension of math.cbrt: it would return non-real values on the negative real axis. (The *real* cube roots of negative numbers would fall on the two non-principal branches.)

    See for example https://math.stackexchange.com/questions/71775/extending-the-cube-root-function-to-mathbbc

    @AjithRamachandran
    Copy link
    Mannequin Author

    AjithRamachandran mannequin commented Jun 9, 2021

    When I needed a function to find cube root, I couldn't find one in the math module. Also found the cbrt() function in C. I didn't account for the complex numbers. I didn't wanted to make it a complex function unnecessarily. So I used the cbrt() function directly and it was working well for my test cases. And it is supported by visual studio.

    @serhiy-storchaka
    Copy link
    Member

    serhiy-storchaka commented Jun 9, 2021

    I am surprised that this was not proposed before. Perhaps because it is so easy to write x**(1/3), and if you want a real root of negative argument, it is -(-x)**(1/3). It can be slightly less accurate that the result of C library function cbrt(), but good enough for any practical applications.

    Ajith, was you aware of x**(1/3)?

    @AjithRamachandran
    Copy link
    Mannequin Author

    AjithRamachandran mannequin commented Jun 9, 2021

    Yes I was aware of x**(1/3) and used that. I just thought it would be useful if it was present in math module as it is also used in many situations like sqrt().

    @mdickinson
    Copy link
    Member

    mdickinson commented Jun 9, 2021

    Perhaps because it is so easy to write x**(1/3), and if you want a real root of negative argument, it is -(-x)**(1/3).

    I consider x**(1/3) to be a trap and a bug magnet: many people won't realise that the correct spelling for their situation is actually def f(x): return -((-x)**(1/3)) if x < 0 else x**(1/3) and the failure mode of x**(1/3) for negative x seems suboptimal, in that it happily returns a complex number rather than raising a ValueError with a clear message indicating what was wrong. I've seen a good number of Stack Overflow questions from users confused about this exact thing.

    And not only is that correct spelling unwieldy, but it still doesn't do the right thing for -0.0, and if you care about getting that corner case right then the right spelling becomes even more unwieldy.

    Of course, even with math.cbrt in the standard library people will still fall into the x**(1/3) trap, but at least we then have a decent replacement to point them to.

    @mdickinson
    Copy link
    Member

    mdickinson commented Jun 9, 2021

    There's also a decent chance that a libm implementation of cbrt will be correctly rounded, while x**(1/3) is highly unlikely to be so.

    @vstinner
    Copy link
    Member

    vstinner commented Jun 9, 2021

    I didn't know the "cbrt" function name. It seems like it exists in the libc, but also in numpy. So it's a good idea to reuse this name ;-)

    numpy.cbrt(): Return the cube-root of an array, element-wise.
    https://numpy.org/doc/stable/reference/generated/numpy.cbrt.html

    @mdickinson
    Copy link
    Member

    mdickinson commented Jun 9, 2021

    @victor: Yep, the name is pretty standard. Not just C, but JavaScript, Java, R, and likely a lot of other languages that I haven't checked.

    @mdickinson
    Copy link
    Member

    mdickinson commented Jun 9, 2021

    If we *really* wanted to bikeshed on the name, back in 1991 Kahan wrote:

    Perhaps the last problem is the hardest: choosing the program's name. Ideally it should need no explanation, but a limitation upon its length may preclude that. Although "CBRT" has seen use, I prefer "QBRT" in order that the prefix "C" may be reserved for use with complex-valued functions.

    Source: https://csclub.uwaterloo.ca/~pbarfuss/qbrt.pdf

    But that was 30 years ago, and I think the "CBRT"-shaped ship has long since sailed.

    @mdickinson
    Copy link
    Member

    mdickinson commented Jun 10, 2021

    New changeset ac867f1 by Ajith Ramachandran in branch 'main':
    bpo-44357:Add math.cbrt() function: Cube Root (GH-26622)
    ac867f1

    @mdickinson
    Copy link
    Member

    mdickinson commented Jun 10, 2021

    All done; closing. Thank you for the contribution!

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.11 stdlib Python modules in the Lib dir type-feature A feature request or enhancement
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants