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

log1pexp(x) when x < -37 #13

Closed
cossio opened this issue Jul 4, 2018 · 11 comments · Fixed by #37
Closed

log1pexp(x) when x < -37 #13

cossio opened this issue Jul 4, 2018 · 11 comments · Fixed by #37

Comments

@cossio
Copy link
Contributor

cossio commented Jul 4, 2018

I was reading R's implementation of log1pexp and they include one additional branch (see https://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf, equation 10).

Currently StatsFuns does this:

https://github.com/JuliaStats/StatsFuns.jl/blob/ae40bc1c6ee63a5624ba6cd168da5bf43f473e59/src/basicfuns.jl#L66

Whereas including the additional branch it would be:

log1pexp_v2(x::AbstractFloat) = x  -37. ? exp(x) : x  18. ? log1p(exp(x)) : x  33.3 ? x + exp(-x) : x

Apparently including the x < -37. check reduces the function's computation time by 25% (because it saves the call to log1p I guess). But I am no expert doing this kind of performance tests so please can someone else more knowledgeable check this? Here is the test I did:

using BenchmarkTools
@btime for x = -100. : 1. : 100., _ = 1 : 100
    log1pexp_v2(x)
end   #  310.471 μs (0 allocations: 0 bytes)
@btime for x = -100. : 1. : 100., _ = 1 : 100
    log1pexp(x)
end  #   423.671 μs (0 allocations: 0 bytes)

Both log1pexp_v2 and log1pexp give numerically identical results.

If this is worth it I can prepare a PR.

Update: Actually it seems much of the time is due to the oftype(exp(-x), x) bit in the final branch. I think specializing on AbstractFloat would take care of that. Even after this change the x ≤ -37. check is faster.

@cossio cossio changed the title log1pexp(x) for x < -37 log1pexp(x) when x < -37 Jul 4, 2018
@dmbates
Copy link
Contributor

dmbates commented Jul 4, 2018

I can see how your version will be faster because it avoids the exp(-x) in oftype(exp(-x), x). You may consider adding

log1pexp_v2(x::Number) = log1pexp_v2(float(x))

to get coverage for integer arguments.

@cossio
Copy link
Contributor Author

cossio commented Jul 4, 2018

I would do log1pexp_v2(x::Real) = log1pexp_v2(float(x)), since we don't want to cover complex arguments.

@dmbates
Copy link
Contributor

dmbates commented Jul 4, 2018

You're right. That's better.

@cossio
Copy link
Contributor Author

cossio commented Jul 23, 2018

Should I prepare a PR on this?

@dmbates
Copy link
Contributor

dmbates commented Jul 23, 2018

Yes, please.

cossio referenced this issue in cossio/StatsFuns.jl Oct 9, 2018
cossio referenced this issue in cossio/StatsFuns.jl May 21, 2019
log1pexp, use float
cossio referenced this issue in cossio/StatsFuns.jl May 21, 2019
log1pexp, use float
@cossio
Copy link
Contributor Author

cossio commented May 22, 2019

@dmbates Please see JuliaStats/StatsFuns.jl#70

@devmotion devmotion transferred this issue from JuliaStats/StatsFuns.jl Apr 19, 2021
@Uroc327
Copy link

Uroc327 commented May 4, 2021

If I may ask, what's the current state of this?

@devmotion
Copy link
Member

I don't know, I just transferred the issue when log1pexp was moved from StatsFuns to LogExpFunctions. @cossio, do you plan to open a PR to LogExpFunctions that preferably also addresses the comments in JuliaStats/StatsFuns.jl#70?

@tpapp
Copy link
Collaborator

tpapp commented Feb 18, 2022

JuliaStats/StatsFuns.jl#70 was just closed, but a PR here is welcome.

@cossio
Copy link
Contributor Author

cossio commented Mar 4, 2022

I'll do a PR right after #35 is done.

@tpapp
Copy link
Collaborator

tpapp commented Mar 5, 2022

Great, thanks!

@cossio cossio mentioned this issue Mar 7, 2022
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 a pull request may close this issue.

5 participants