Add lgamma#2417
Conversation
|
Thank you very much for reviving an old PR, yifanwww! It will be great to get this in. Some feedback/questions before we review this PR in more detail:
Thanks for making these changes and then we will go through the PR in detail. If you need further assistance with the calculation for complex inputs, please just let us know. Finally, I note that the prior PR had a stub for computing the log of the multivariate Gamma function. Did you have any interest in including that as well? If not, there is not a particular need to incorporate it into this PR -- I just thought I would bring that up in case it is a function that's of interest to you, since there is some code for it in the old PR. |
|
Excellent changes, @yifanwww -- thank you so much for the updates. The last major ingredient needed is a decent implementation for complex numbers. Please let us know if you are able to take a stab at that, yifanwww (which would likely be quicker), or if you're hoping that a maintainer can supply a complex implementation (will probably take a bit longer). Thanks! |
|
Well, I'd like to try to provide an implementation for complex numbers, but I don't think that would be quicker because I'm not very good at math and not familiar with the mathematical calculations in computer languages. Anyway, I want to challenge it. I'll leave comments if I need further help for complex implementation. For the multivariate Gamma function, I don't want to incorporate it into this PR, since in this PR I only want to supply |
That's great. We'll look forward to your efforts and hold off on further action on this PR until you make another commit.
That's perfectly reasonable.
I think Thanks for all of your efforts. |
|
@yifanwww are you still planning to try to provide an implementation for complex numbers? @kmdrGroch given your digamma submission, any chance you'd be interested in lending a hand? |
Conflicts: - src/expression/embeddedDocs/embeddedDocs.js
|
@gwhitney yeah... I'm still trying, but cannot pass all the tests. |
|
@yifanwww I see there is only one test failing, it related to testing |
|
@josdejong ah not that one, I fixed it but haven't pushed yet. I'm trying to write an implementation for complex numbers, but cannot pass all the tests. Some results are very different from the reference results. |
Ah ok, so that needs some careful examination whether the old or the new results are wrong. I regularly use https://www.wolframalpha.com/ for example to double check what the right result should be. |
|
At my first try, I chose Lanczos method to implement log gamma for complex numbers, but somehow it didn't give the correct results. So I changed the solution, now the implementation is based on Stirling series and it seems to work fine. But there is a problem in If we try it in Python >>> import cmath
>>> cmath.log(-9.87654321e50 + 1.23456789e70j)
(161.39167753179885+1.5707963267948966j)Do we have any alternate utilities to get the logarithm of complex numbers to work correctly? |
|
Yes, you've uncovered something very wrong with the mathjs implementation of complex logarithm. I will file an issue and mention that this PR is blocked by it. Hopefully then someone involved can track down the problem and fix it and thereby get this great PR back on track -- thanks for all of your work on this! |
|
The difficulty turns out to be in the complex library mathjs is using; I have filed upstream issue rawify/Complex.js#40. Hopefully Robert Eisele will be able to be responsive. |
|
OK, if you want to experiment you can try this on top of branch |
Indeed. It is fine if there just is no |
|
I don't know what's wrong, now I cannot get a TypeError if I try to compute console.log(math.lgamma(new BigNumber(0)))
console.log(math.lgamma(math.bignumber(0)))
// output:
// { re: Infinity, im: 0 }
// { re: Infinity, im: 0 } |
|
There's an automatic conversion from BigNumber to Complex. So if you have a Complex implementation and want BigNumber to throw, you have to make a BigNumber implementation that throws. Sorry I didn't realize this before. |
|
Ready for merge, please check it. |
|
|
||
| return signa ^ signb ? -a : a | ||
| } | ||
|
|
There was a problem hiding this comment.
@josdejong does this not exist already somewhere in mathjs? If not, is there a utility module it belongs in rather than here?
There was a problem hiding this comment.
I don't think there is already such a util function. We could indeed move it to a util file like src/utils/number.js.
|
My apologies for doing all those as individual comments rather than a cohesive review, I was distracted by another task and did not realize that there would be several comments. Thanks for understanding. One last item that coudn't be attached to a file: please add a test or test in types/index.ts that lgamma types and executes correctly. Thanks so much for taking care of all of these details! The submission is now looking good and we are looking forward to getting it in. (We will just need feedback from Jos when he has a chance on the best location for the copysign utility function, or maybe something equivalent already exists somewhere in mathjs.) |
Thanks for reminding. I added a type test for lgamma at the end of types/index.ts, but don't know if it's correct since we don't yet have similar type test cases for probability functions that I can refer to. |
|
The TypeScript test looks fine to me. Basically anything that does anything substantive with the function is good. And yes, they are missing for other functions, but that doesn't mean we should compound the problem when a new function is added, so thank you for your understanding on that. I just had one last documentation point I just commented above, and we are just waiting for feedback from Jos on a couple of small points for you to act on if necessary, and then this should be good to merge. Thank you so much for all of your efforts and seeing it through the long process, it's much appreciated. |
|
Thanks guys for all the hard work, this PR is looking very good now! I've commented on the conversations where you tagged me @gwhitney. |
I noticed that there was already a PR #320 for
gammaln, but it's too old. Since mathjs has refactored itself several times, the code in that PR cannot be merged any more. And it seems that @nfoti is rarely active on Github over the past few years.So I created a new PR to support
gammaln.This implementation is the same as that in that PR, using Lanczos method to compute the logarithm of the gamma function since
log(gamma(x))can result in numerical problems.I don't know how
gammalnworks when it receivesComplexorBigNumber, so I only write the implementation for numbers. If an array or matrix only contains numbers,gammalncan also work.Compare to the results calculated from https://keisan.casio.com/exec/system/1180573442, the precision of this implementation is high enough.