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

Some fixes and simplications to the beta function(s). #316

Merged
merged 11 commits into from
May 19, 2021
Merged

Conversation

andreasnoack
Copy link
Member

The handling of large magnitude differences was only applied to logabsbeta but
not logbeta. They now share code so the special handling applies to
both functions. The cutoff for special handling has also been lowered
to avoid loss of precision for intermediate argument size differences.
Finally, helper functions for the beta function now have assertions
to ensure that they are only applied for the ranges they are written for.

@devmotion Would be great if you could review this one as well. The issue showed up when I tried to use native Julia implementations for the beta and binomial distributions in JuliaStats/StatsFuns.jl#113.

@andreasnoack
Copy link
Member Author

Hm. So the assertions were triggered in the incomplete beta tests. I'll look into it.

Copy link
Member

@devmotion devmotion left a comment

Choose a reason for hiding this comment

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

Looks mostly fine. I had some questions regarding the use of @assert and the changes in logabsbeta. In general, I wonder if it would be beneficial to use Float64 literals in all comparisons where the involved variables are guaranteed to be of type Float64 (apart from consistency).

@@ -13,6 +13,7 @@ loggammadiv(a::Number, b::Number) = _loggammadiv(float(a), float(b))

_loggammadiv(a::T, b::T) where {T<:Base.IEEEFloat} = T(_loggammadiv(Float64(a), Float64(b))) # handle Float16, Float32
function _loggammadiv(a::Float64, b::Float64)
@assert b >= 8
Copy link
Member

Choose a reason for hiding this comment

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

I usually try to avoid @assert and use error instead, mainly due to the warning in the docstring of @assert that the assert statement might be disabled at various optimization levels and that it should be used only as a debugging tool. However, I guess you are more familiar with these Julia internals and I assume it does not matter as long as the behaviour does not depend critically on the assert statements.

Copy link
Member Author

Choose a reason for hiding this comment

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

I do think it's only for debugging here. These function are only supposed to be used as part of other functions and it will actually be useful that they can be removed by optimization passes.

src/beta_inc.jl Outdated Show resolved Hide resolved
src/beta_inc.jl Outdated
@@ -348,6 +355,9 @@ External links: [DLMF](https://dlmf.nist.gov/8.17.22), [Wikipedia](https://en.wi
See also: [`beta_inc`](@ref)
"""
function beta_inc_asymptotic_asymmetric(a::Float64, b::Float64, x::Float64, y::Float64, w::Float64, epps::Float64)
@assert a >= 15
@assert b <= 1
Copy link
Member

Choose a reason for hiding this comment

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

Again, the docstring seems to indicate that also b < epps is required (a >= 15 and hence min(epps, epps * a) = epps). I assume that usually epps <= 1 and thus

Suggested change
@assert b <= 1
@assert b < epps

would be sufficient but probably safest would be

Suggested change
@assert b <= 1
@assert b <= 1.0 && b < epps

(b < min(1, epps) would be "incorrect" if epps > 1 and b <= min(1, epps) would be "incorrect" if epps < 1).

Copy link
Member Author

Choose a reason for hiding this comment

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

This was the one that triggered the test failure so I had to check the Fortran source. First part of the comment here was simply wrong and I believe the assertion are correct.

src/beta_inc.jl Outdated Show resolved Hide resolved
src/beta_inc.jl Outdated Show resolved Hide resolved
src/gamma.jl Outdated Show resolved Hide resolved
# asymptotic expansion for large `b` and positive arguments
# FIXME! We probably lose precision for negative arguments. However, `loggammadiv`
# is based on the NSWC code which doesn't bother with negative arguments
if a > 0 && b > 8
Copy link
Member

Choose a reason for hiding this comment

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

Are these thresholds based on the NSWC code?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. All the beta functions in NSWC assume positive arguments and the cutoff used there is b>8.

src/gamma.jl Outdated Show resolved Hide resolved
src/gamma.jl Outdated Show resolved Hide resolved
of large magnitude differences was only applied to logabsbeta but
not logbeta. They now share code so the special handling applies to
both functions. The cutoff for special handling has also been lowered
to avoid loss of precision for intermediate argument size differences.
Finally, helper functions for the beta function now have assertions
to ensure that they are only applied for the ranges they are written for.
Co-authored-by: David Widmann <devmotion@users.noreply.github.com>
@codecov
Copy link

codecov bot commented May 17, 2021

Codecov Report

Merging #316 (d87a95e) into master (feccbf4) will increase coverage by 2.61%.
The diff coverage is 84.87%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #316      +/-   ##
==========================================
+ Coverage   89.28%   91.90%   +2.61%     
==========================================
  Files          12       12              
  Lines        2633     2645      +12     
==========================================
+ Hits         2351     2431      +80     
+ Misses        282      214      -68     
Flag Coverage Δ
unittests 91.90% <84.87%> (+2.61%) ⬆️

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

Impacted Files Coverage Δ
src/beta_inc.jl 87.57% <82.10%> (+10.31%) ⬆️
src/gamma.jl 94.65% <95.23%> (+1.07%) ⬆️
src/gamma_inc.jl 92.46% <100.00%> (+0.02%) ⬆️
src/chainrules.jl 100.00% <0.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update feccbf4...d87a95e. Read the comment docs.

andreasnoack and others added 4 commits May 17, 2021 17:41
Co-authored-by: David Widmann <devmotion@users.noreply.github.com>
Co-authored-by: David Widmann <devmotion@users.noreply.github.com>
Co-authored-by: David Widmann <devmotion@users.noreply.github.com>
Co-authored-by: David Widmann <devmotion@users.noreply.github.com>
@andreasnoack
Copy link
Member Author

I believe I've addressed your comments but please let me know if I've missed anything. (I've added a few more tests to increase to coverage of some of the helper functions).

@andreasnoack
Copy link
Member Author

Bump. I've just added a commit that changes some of the comparisons to be using float literals.

x = aa/ (aa+bb*exp(w^2))
h = 2.0/(s + t)
w = pp_approx*sqrt(h + r)/h - (t - s)*(r + 5.0/6.0 - 2.0/(3.0*h))
x = aa/(aa + bb*exp(w + w))
Copy link
Member

@stevengj stevengj May 19, 2021

Choose a reason for hiding this comment

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

So the w^2 in the original code was a typo? exp(w^2) ≠ exp(w + w)

Copy link
Member Author

Choose a reason for hiding this comment

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

It is a typo. This is the line from the paper
Skærmbillede 2021-05-19 kl  20 34 20

Copy link
Member

@devmotion devmotion left a comment

Choose a reason for hiding this comment

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

Looks good to me, I just had one minor suggestion and was also wondering about @stevengj 's observation.

src/beta_inc.jl Outdated Show resolved Hide resolved
Co-authored-by: David Widmann <devmotion@users.noreply.github.com>
@andreasnoack andreasnoack merged commit fbb44fa into master May 19, 2021
@andreasnoack andreasnoack deleted the an/logbeta branch May 19, 2021 19:25
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.

3 participants