-
Notifications
You must be signed in to change notification settings - Fork 100
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
Updated Lambert W function implementation #371
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## master #371 +/- ##
==========================================
- Coverage 94.25% 94.19% -0.07%
==========================================
Files 14 15 +1
Lines 2908 3031 +123
==========================================
+ Hits 2741 2855 +114
- Misses 167 176 +9
Flags with carried forward coverage won't be shown. Click here to find out more.
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
cc @jlapeyre |
03062c9
to
8f2cfd4
Compare
Can this be merged? Seems well tested and well documented |
No, I don't think it should be merged. My impression from the discussion in #84 was that there was a tendency/agreement to keep the function in a separate package. |
At this point I wonder if you are interested to improve the implementation of this function at all. |
There's a package with this function, and the general opinion (not just my personal one) was to keep the function there. So if it can be improved, I guess you should open a PR in that repo. |
The "general opinion" is a bit of a stretch. But thank you for your efforts to guard the quality of Julia ecosystem. As for me, I think trying to put this code elsewhere would be a waste of my resources, given that nobody have reviewed it here (I have noted "if it can be improved"). |
@alyst thanks for putting it together. It is generally true that it has been hard to get reviews here. |
I'm sorry for you that the PR is not reviewed, but I guess many people, including myself, are not eager to review a PR in detail if there's already a longer discussion that indicates that there is no general agreement that the Lambert W function should be added to SpecialFunctions but instead shows that people seem to be in favour of keeping it in LambertW.jl. Therefore my suggestion was to make a PR to LambertW.jl instead if you would like to improve its implementation. I think you will receive more reviews and comments there. |
It did seem that the original author @jlapeyre (IIRC, and if I have my facts straight) expressed interest in keeping it separate - and thus I feel that we should respect that opinion. |
Since I was the one who triggered the original thought of getting this in - I would like to apologize for causing wasted effort here. :-( |
I'm also sorry if I caused wasted effort. Like many people, I'm over-extended and this is not the highest priority. I was also reluctant to put effort into a PR because I made one (for the same question) a few years ago, and it sat around till it bitrotted. I'm not blaming anyone: Most of us are not paid for this and have other obligations. But, my best estimation was that the best first step is to put LambertW under the JuliaMath org. I asked how to do that in the appropriate (I think) channel in slack a few weeks ago. But, I never got a response. |
@jlapeyre I can help with moving LambertW.jl to the JuliaMath org. I'm inviting you as an owner of JuliaMath, and you should be able to then transfer the package. |
This copies the implementation of the Lambert W function and related functions and data from jlapeyre/LambertW.jl to SpecialFunctions.jl
- use Base.evalpoly() instead of horner macro reimplementation - use Val()-based dispatch instead of function generation
using the code from JuliaMath/IrrationalConstants.jl/issues/12 No __init__() section is required
|
||
### root finding, iterative solution | ||
|
||
# Use Halley's root-finding method to find |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth noting that there's a paper from Lóczi published last year in Applied Mathematics and Computation called "Guaranteed- and high-precision evaluation of the Lambert W function" that describes algorithms that improve significantly on e.g. Halley's method. I used it to implement W-1 for real arguments in (-1/e, 0) in https://github.com/JuliaStats/Distributions.jl/blob/master/src/univariate/continuous/lindley.jl#L137-L156.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've actually tried the iteration scheme evaluated in the paper, but it looks like it's on par with Halley or the latter requires 1-2 iterations less from the same starting point (but I have not tested very extensively).
IIUC the paper doesn't claim that the Iacono-Boyd method provides faster convergence than Halley method, it just proves the bounds for the Iacono-Boyd one (because it's a simpler formula).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah good to know, it's been a bit since I read it so the details have been largely GC'd. Probably should have reread the paper before attempting to summarize it. 😅 One thing I recall was that when I was testing things out for the -1 branch in (-1/e, 0), I was comparing LambertW.jl vs. Iacono-Boyd vs. Mathematica as "ground truth" and found that Iacono-Boyd produced more accurate results near -1/e and 0 but was otherwise the same. Your comment makes me realize that I had actually neglected to check the number of iterations that LambertW.jl required for convergence. LambertW.jl explicitly keeps track of the change between iterations and will stop early based on that, whereas my naive implementation of Iacono-Boyd just iterates a set number of times. In developing it, I was playing around with the number of iterations and found that most inputs required only 2 or so iterations to converge, so I'd be interested to see how that compares with LambertW.jl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tried to implement Iacono-Boyd scheme here: https://github.com/alyst/SpecialFunctions.jl/tree/lambertw_iacono_iters.
Actually, the iteration scheme is just an input parameter to the root finding function, so that code could be easily adopted for more comprehensive evaluation of efficiency of both schemes over the whole LambertW(x) domain and for different numeric types.
The separate package has been moved here https://github.com/JuliaMath/LambertW.jl |
This is a fork of #84. I did:
moved Omega and 1/e constants to IrrationalConstants.jl (PR Lambert's Omega constant IrrationalConstants.jl#12), so this PR requires that Omega constant PR is mergeduses inve = 1/e constant from Add 1/e constant IrrationalConstants.jl#13LambertW.Omega
orLambertW.Ω