Skip to content
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

Rewrite gamma_inc_taylor and gamma_inc_asym more concisely #443

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

BioTurboNick
Copy link

@BioTurboNick BioTurboNick commented May 4, 2023

Many functions were translated directly from Fortran. This PR rewrites two of them using more concise Julia forms.

Ideally would like to eliminate the array allocation as well. (See #442) And now does!

@codecov
Copy link

codecov bot commented May 4, 2023

Codecov Report

Patch coverage: 100.00% and project coverage change: +0.01 🎉

Comparison is base (ae35d10) 94.32% compared to head (8d37a34) 94.34%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #443      +/-   ##
==========================================
+ Coverage   94.32%   94.34%   +0.01%     
==========================================
  Files          14       14              
  Lines        2909     2881      -28     
==========================================
- Hits         2744     2718      -26     
+ Misses        165      163       -2     
Flag Coverage Δ
unittests 94.34% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/gamma_inc.jl 93.49% <100.00%> (+0.03%) ⬆️

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

src/gamma_inc.jl Outdated Show resolved Hide resolved
src/gamma_inc.jl Outdated Show resolved Hide resolved
src/gamma_inc.jl Outdated Show resolved Hide resolved
src/gamma_inc.jl Outdated Show resolved Hide resolved
src/gamma_inc.jl Outdated Show resolved Hide resolved
src/gamma_inc.jl Outdated Show resolved Hide resolved
@BioTurboNick
Copy link
Author

BioTurboNick commented May 4, 2023

Oops, left an nmc off that commit. Apologies to that person.

@heltonmc
Copy link
Member

heltonmc commented May 4, 2023

I know I originally suggested it but it would still be nice to know why it was implemented in this way to begin with as it is quite unusual and we are really just relying on the strength of the original test set here.

My last comment is just about the convergence check. My original suggestion (#442 (comment)) checked for relative tolerance where this just checks for absolute tolerance. It probably doesn't matter but if the final result is much smaller than 1 they could be different. (edit: relative check will be slower so not saying just to do it instead)

@BioTurboNick
Copy link
Author

BioTurboNick commented May 5, 2023

Alright, thanks! :-) I reverted to the original version, with your smaller suggestions. I kept the other one on another branch, gamma-fix2, just in case.

@heltonmc
Copy link
Member

heltonmc commented May 5, 2023

Sounds good 😊 I’ll let other people comment on what they think of the two versions.

This version will allocate though which might not solve your initial problem. If you want to sum in reverse order your probably best bet is to to use @nexprs to remove the array then can sum in any order you want. I’m not for sure it’s really needed here though but it would be nice since we are putting in the effort to make this allocation free !

Co-authored-by: David Widmann <[email protected]>
@BioTurboNick
Copy link
Author

Ah, found an allocation-free way! Before I commit it:

# compute first 21 terms
ts = cumprod(ntuple(i -> x / (a + i), Val(21)))
last_t = findfirst(<(1.0e-3), ts)
last_t = last_t === nothing ? 20 : last_t - 1
next_t = last_t + 1

@BioTurboNick
Copy link
Author

BioTurboNick commented May 9, 2023

Ah, cumprod for tuples doesn't exist in Julia 1.3... any chance of dropping support for Julia before 1.6? (It was introduced in 1.5)

EDIT: Or can just define it here. Nevermind, too much to bring in.

@BioTurboNick
Copy link
Author

Bumping - any more work needed on this?

@BioTurboNick
Copy link
Author

What do I need to do to get this in? I have a couple bits of code that would really benefit from this change, and I'd like not to have to disable precompilation.

@ViralBShah
Copy link
Member

@devmotion Is this good to merge?

@@ -22,7 +22,7 @@ IrrationalConstants = "0.1, 0.2"
LogExpFunctions = "0.3.2"
OpenLibm_jll = "0.7, 0.8"
OpenSpecFun_jll = "0.5"
julia = "1.3"
julia = "1.5"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to the use of cumprod(::Tuple) IIRC?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

break
end

# compute first 21 terms
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if summation in reverse order is necessary (something like #442 (comment) would be much simpler implementation-wise)? I wonder if there is any argument/comment regarding this choice in the original Fortran code - does anyone know where the current implementation was copied from?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory better for numerical stability and precision to do it this way, because otherwise you can lose the accumulated effect of the small components when they're very much smaller than the large components, but I don't know in practice if/when it affects results of this function.

Copy link
Author

@BioTurboNick BioTurboNick Feb 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've found a couple possible sources, but I think I'm gathering that the impetus was to support arbitrarily low precision. Maybe with Float64 it works pretty much fine, which this package forces. But with lower precision, maybe the errors would add up too much if floating point math wasn't carefully managed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like @Sumegh-git and @simonbyrne were writing/reviewing the PR that introduced them, if they can comment :-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does anyone know where the current implementation was copied from?

ACM TOMS (FREE ACCESS): https://dl.acm.org/doi/abs/10.1145/22721.23109
Fig. 2 in the paper shows the flowchart of the algorithm as a whole.

  • gamma_inc_taylor: Equ. 15
  • gamma_inc_asym: Equ. 16

The original paper is mentioned in the code comments.
Perhaps those comments should be moved to the function documentation.

# Reference : 'Computation of the incomplete gamma function ratios and their inverse' by Armido R DiDonato, Alfred H Morris.
# Published in Journal: ACM Transactions on Mathematical Software (TOMS)
# Volume 12 Issue 4, Dec. 1986 Pages 377-393
# doi>10.1145/22721.23109

Copy link
Author

@BioTurboNick BioTurboNick Feb 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! In that case maybe this is the FORTRAN code itself? https://jblevins.org/mirror/amiller/inc_gam.f90

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants