Open steff456 opened 1 year ago
It looks like the NumPy cbrt doesn't support complex arguments.
Presumably for a floating-point negative argument cbrt should return a real negative number, but for a complex real negative argument it should return the principle cube root (if we add complex support).
Complex cube root is tricky (see https://github.com/JuliaLang/julia/issues/36534). My initial sense is that we'd want to leave unspecified if complex dtypes are supported.
Even without implementing the complex version there's still the fact that cbrt(-1) returning -1 is a non-principle cube root (differing from power
):
>>> np.power(-1, 1/3)
<stdin>:1: RuntimeWarning: invalid value encountered in power
nan
>>> np.cbrt(-1)
-1.0
Agreed. For negative reals, cbrt
should return a negative real number. And thanks for highlighting a key limitation of power
.
I don't really see it as a limitation. There are very good reasons for power to return principle roots, even if that means returning nan instead of a real value for noncomplex floating-point inputs.
Of course, sometimes you do want a real cube root. And it seems that that's the C standard for what cbrt
does, so we should definitely do that.
I agree that omitting an extension to complex numbers is probably best because that would require choosing between either returning different values for negative reals, or using a non-principle branch cut, and both seem problematic. Maybe worth bringing up in a consortium meeting though.
Linking to a (closed) feature request on PyTorch: https://github.com/pytorch/pytorch/issues/25766
This RFC requests to include a new API in the array API specification for the purpose of computing the cube root.
Overview
Based on array comparison data, the API is available in the majority of libraries in the PyData ecosystem.
The Array API Specification currently includes
pow
andsqrt
, but does not include the IEEE 754 functioncbrt
.pow: https://github.com/data-apis/array-api/blob/3d918783ac7f11cb5b31681b2badddeca81dc71e/src/array_api_stubs/_2022_12/elementwise_functions.py#L1786
sqrt: https://github.com/data-apis/array-api/blob/3d918783ac7f11cb5b31681b2badddeca81dc71e/src/array_api_stubs/_2022_12/elementwise_functions.py#L2139
While the cube root could be implemented in terms of
pow
, this is not desirable as the rational 1/3 is not typically equal to1.0/3.0
due to limited floating-point precision. Cube root implementations are generally more accurate than the equivalent operation viapow
.Prior art
Proposal:
cc @kgryte