Add gamma function to cmath module
Since the gamma function (see https://en.wikipedia.org/wiki/Gamma_function) is defined for complex numbers too, wouldn't it be normal to have it implemented on the `cmath` module? The `math` module has this function, but it doesn't support complex numbers (as expected). I know that others libraries such as scipy (on the `scipy.special` module), or the `mpmath` module already have what I'm requesting but since `cmath` module is the complementary of `math`. I think that if others functions such as `sin`, `cos`, `sqrt` are implemented on both modules, why shouldn't gamma function?
I don't know, but maybe you can look into submitting a PR that adds cmath.gamma? (I would first create an issue on bugs.python.org where you can have more discussion about the PR.) Maybe when implementing it you'll find the reason why it isn't defined yet...
On Sun, Sep 8, 2019 at 1:45 PM davidgmorillop@gmail.com wrote:
Since the gamma function (see https://en.wikipedia.org/wiki/Gamma_function) is defined for complex numbers too, wouldn't it be normal to have it implemented on the `cmath` module? The `math` module has this function, but it doesn't support complex numbers (as expected). I know that others libraries such as scipy (on the `scipy.special` module), or the `mpmath` module already have what I'm requesting but since `cmath` module is the complementary of `math`. I think that if others functions such as `sin`, `cos`, `sqrt` are implemented on both modules, why shouldn't gamma function? _______________________________________________ Pythonideas mailing list  pythonideas@python.org To unsubscribe send an email to pythonideasleave@python.org https://mail.python.org/mailman3/lists/pythonideas.python.org/ Message archived at https://mail.python.org/archives/list/pythonideas@python.org/message/B62LJB... Code of Conduct: http://python.org/psf/codeofconduct/
Since cmath module is implemented on C, and my C level is really basic, I do not feel confident enough to submit a PR, but I encourage a more experienced developer to do it. I must say too that I'm new to the python community, therefore I don't know the following steps I should take. Thanks in advance.
Maybe you can start by publishing a Python implementation?
On Sun, Sep 8, 2019 at 16:48 David García davidgmorillop@gmail.com wrote:
Since cmath module is implemented on C, and my C level is really basic, I do not feel confident enough to submit a PR, but I encourage a more experienced developer to do it. I must say too that I'm new to the python community, therefore I don't know the following steps I should take. Thanks in advance. _______________________________________________ Pythonideas mailing list  pythonideas@python.org To unsubscribe send an email to pythonideasleave@python.org https://mail.python.org/mailman3/lists/pythonideas.python.org/ Message archived at https://mail.python.org/archives/list/pythonideas@python.org/message/JZYHOV... Code of Conduct: http://python.org/psf/codeofconduct/
On Sep 7, 2019, at 18:07, davidgmorillop@gmail.com wrote:
Since the gamma function (see https://en.wikipedia.org/wiki/Gamma_function) is defined for complex numbers too, wouldn't it be normal to have it implemented on the `cmath` module? The `math` module has this function, but it doesn't support complex numbers (as expected).
I believe this is just because math and cmath started off mostly thin wrappers around the C stdlib functions, and C had a gamma for double but not for complex.
(Actually, IIRC, it’s a bit more complicated, more like “what POSIX guaranteed that Windows also provided as of the mid 90s”, which goes beyond the C89 standard but doesn’t match the C99 standard.)
But that doesn’t mean it couldn’t be added. The `math` and `cmath` modules have added lots of things over the decades that are useful and aren’t thin wrappers, like `fsum` and `isclose`, and hasn’t included everything that was added in later versions of C or POSIX.
In fact, math.gamma itself is effectively one of those things; it’s no longer a wrapper around a libm function, but a custom Lancsoz implementation that gives the same values on all platforms.
But on the third hand, you’d presumably want cmath.gamma to give the same values as math.gamma for compatible inputs. And the algorithm in mathmodule.c doesn’t translate smoothly to complex. I believe libraries like GSL deal with this by using a different algorithm that does translate smoothly, for both real and complex values, but that means giving up either speed or accuracy or both.
I did some quick tests on scipy.special.gamma. It takes roughly 12x as long as math.gamma, and gives larger errors (within 3 ulp instead of 1 even near 1, and as much as 117ulp instead of no more than 10 for extreme values), and doesn’t give the same values for float and complex (e.g., for 1/3, they differ by 6ulp). Is that good enough for the stdlib?
That's a question for Tim Peters.
On Sun, Sep 8, 2019 at 9:48 PM Andrew Barnert via Pythonideas < pythonideas@python.org> wrote:
On Sep 7, 2019, at 18:07, davidgmorillop@gmail.com wrote:
Since the gamma function (see
https://en.wikipedia.org/wiki/Gamma_function) is defined for complex numbers too, wouldn't it be normal to have it implemented on the `cmath` module? The `math` module has this function, but it doesn't support complex numbers (as expected).
I believe this is just because math and cmath started off mostly thin wrappers around the C stdlib functions, and C had a gamma for double but not for complex.
(Actually, IIRC, it’s a bit more complicated, more like “what POSIX guaranteed that Windows also provided as of the mid 90s”, which goes beyond the C89 standard but doesn’t match the C99 standard.)
But that doesn’t mean it couldn’t be added. The `math` and `cmath` modules have added lots of things over the decades that are useful and aren’t thin wrappers, like `fsum` and `isclose`, and hasn’t included everything that was added in later versions of C or POSIX.
In fact, math.gamma itself is effectively one of those things; it’s no longer a wrapper around a libm function, but a custom Lancsoz implementation that gives the same values on all platforms.
But on the third hand, you’d presumably want cmath.gamma to give the same values as math.gamma for compatible inputs. And the algorithm in mathmodule.c doesn’t translate smoothly to complex. I believe libraries like GSL deal with this by using a different algorithm that does translate smoothly, for both real and complex values, but that means giving up either speed or accuracy or both.
I did some quick tests on scipy.special.gamma. It takes roughly 12x as long as math.gamma, and gives larger errors (within 3 ulp instead of 1 even near 1, and as much as 117ulp instead of no more than 10 for extreme values), and doesn’t give the same values for float and complex (e.g., for 1/3, they differ by 6ulp). Is that good enough for the stdlib?
Pythonideas mailing list  pythonideas@python.org To unsubscribe send an email to pythonideasleave@python.org https://mail.python.org/mailman3/lists/pythonideas.python.org/ Message archived at https://mail.python.org/archives/list/pythonideas@python.org/message/SXQ3V4... Code of Conduct: http://python.org/psf/codeofconduct/
More a question for Mark Dickinson  he added math.gamma, not me ;)
There was a bpo issue opened about this over 8 years ago, but it was closed 6 years ago "due to lack of interest":
https://bugs.python.org/issue11012
In general, adding hairy stuff to cmath is painful, and just minimizing the cardinality of
set(dir(math))  set(dir(cmath))
isn't sufficient justification.
From my POV, the audience for complex gamma is relatively tiny and is already served by popular, solid packages (like scipy and mpmath). If someone really needs complex gamma, they probably need all sorts of other specialized stuff too! I prefer to keep such stuff _out_ of the core.
But people can reasonably disagree about that. In the bpo issue linked to above, Mark said he wouldn't work on it himself, but would be happy to review patches. Which is more than I'd be willing to do ;)
On Sun, Sep 8, 2019 at 4:02 PM Guido van Rossum guido@python.org wrote:
That's a question for Tim Peters.
On Sun, Sep 8, 2019 at 9:48 PM Andrew Barnert via Pythonideas pythonideas@python.org wrote:
On Sep 7, 2019, at 18:07, davidgmorillop@gmail.com wrote:
Since the gamma function (see https://en.wikipedia.org/wiki/Gamma_function) is defined for complex numbers too, wouldn't it be normal to have it implemented on the `cmath` module? The `math` module has this function, but it doesn't support complex numbers (as expected).
I believe this is just because math and cmath started off mostly thin wrappers around the C stdlib functions, and C had a gamma for double but not for complex.
(Actually, IIRC, it’s a bit more complicated, more like “what POSIX guaranteed that Windows also provided as of the mid 90s”, which goes beyond the C89 standard but doesn’t match the C99 standard.)
But that doesn’t mean it couldn’t be added. The `math` and `cmath` modules have added lots of things over the decades that are useful and aren’t thin wrappers, like `fsum` and `isclose`, and hasn’t included everything that was added in later versions of C or POSIX.
In fact, math.gamma itself is effectively one of those things; it’s no longer a wrapper around a libm function, but a custom Lancsoz implementation that gives the same values on all platforms.
But on the third hand, you’d presumably want cmath.gamma to give the same values as math.gamma for compatible inputs. And the algorithm in mathmodule.c doesn’t translate smoothly to complex. I believe libraries like GSL deal with this by using a different algorithm that does translate smoothly, for both real and complex values, but that means giving up either speed or accuracy or both.
I did some quick tests on scipy.special.gamma. It takes roughly 12x as long as math.gamma, and gives larger errors (within 3 ulp instead of 1 even near 1, and as much as 117ulp instead of no more than 10 for extreme values), and doesn’t give the same values for float and complex (e.g., for 1/3, they differ by 6ulp). Is that good enough for the stdlib?
Pythonideas mailing list  pythonideas@python.org To unsubscribe send an email to pythonideasleave@python.org https://mail.python.org/mailman3/lists/pythonideas.python.org/ Message archived at https://mail.python.org/archives/list/pythonideas@python.org/message/SXQ3V4... Code of Conduct: http://python.org/psf/codeofconduct/
 Guido van Rossum (python.org/~guido) Pronouns: he/him/his (why is my pronoun here?) _______________________________________________ Pythonideas mailing list  pythonideas@python.org To unsubscribe send an email to pythonideasleave@python.org https://mail.python.org/mailman3/lists/pythonideas.python.org/ Message archived at https://mail.python.org/archives/list/pythonideas@python.org/message/SIK5VC... Code of Conduct: http://python.org/psf/codeofconduct/
On Sep 8, 2019, at 14:44, Tim Peters tim.peters@gmail.com wrote:
From my POV, the audience for complex gamma is relatively tiny
Agreed. Especially people who need complex gamma who aren’t dealing with arrays (in which case you’d have to use scipy anyway).
Also, I suspect different uses might actually need different tradeoffs between performance, accuracy, and consistency with math.gamma, which would make the audience for a stdlib function even smaller.
Digging through my pile of code, I found a few places where I use the scipy function, but all with arrays. And I found two places where I don’t use scipy, but I don’t think cmath would have helped there either.
My infinitesimalcalculator toy has a gamma function, which uses the simple but inaccurate Stirling algorithm for both (extended) real and complex values. Probably because it extends trivially to LeviCivita series. I have a notes.md file that mentions other algorithms to try if I ever need a better gamma, and ones that I tried and rejected, but (a) apparently I never needed a better gamma, and (b) working out how to extend finite math.gamma was one of the things I already tried and rejected.
And I’ve got some other code where I implemented the Spouge approximation (using only operators rather than sqrt and exp for some reason, so it probably would have worked out of the box for LC extended numbers, just as it does for most other numberlike types from an array of complex64 to a quarternion…), with a comment that says “# don’t use scipy.gamma because it” and cuts off there, which isn’t very helpful. I’m _guessing_ I needed identical values for float and complex. Anyway, it’s slower than scipy even with a small table, and less accurate even with a large one (as in `gamma(1.0+0j)` gives you 0.9999995 instead of 1.0), so presumably, whatever my reason was eclipsed both of those considerations, and likely the same would have been true if cmath.gamma had existed, except I would have had a slightly longer useless comment saying “# don’t use cmath.gamma or scipy.gamma because they”. :)
participants (5)

Andrew Barnert

David García

davidgmorillop＠gmail.com

Guido van Rossum

Tim Peters