Skip to content

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

Closed

Description

@AjithRamachandran
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']

    Activity

    1. added
      stdlibStandard Library Python modules in the Lib/ directory
      type-featureA feature request or enhancement
      on Jun 9, 2021
    2. serhiy-storchaka commented on Jun 9, 2021

      @serhiy-storchaka
      Member

      See also bpo-27353.

    3. added
      3.11only security fixes
      and removed on Jun 9, 2021
    4. mdickinson commented on Jun 9, 2021

      @mdickinson
      Member

      +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.

    5. mdickinson commented on Jun 9, 2021

      @mdickinson
      Member

      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

    6. AjithRamachandran commented on Jun 9, 2021

      AjithRamachandranmannequin
      MannequinAuthor

      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.

    7. serhiy-storchaka commented on Jun 9, 2021

      @serhiy-storchaka
      Member

      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)?

    8. AjithRamachandran commented on Jun 9, 2021

      AjithRamachandranmannequin
      MannequinAuthor

      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().

    9. mdickinson commented on Jun 9, 2021

      @mdickinson
      Member

      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.

    10. mdickinson commented on Jun 9, 2021

      @mdickinson
      Member

      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.

    11. vstinner commented on Jun 9, 2021

      @vstinner
      Member

      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

    12. mdickinson commented on Jun 9, 2021

      @mdickinson
      Member

      @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.

    13. mdickinson commented on Jun 9, 2021

      @mdickinson
      Member

      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.

    14. mdickinson commented on Jun 10, 2021

      @mdickinson
      Member

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

    15. mdickinson commented on Jun 10, 2021

      @mdickinson
      Member

      All done; closing. Thank you for the contribution!

    16. transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    Labels

    3.11only security fixesstdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions