Skip to content

log1pexp(x) when x < -37 #13

Closed
Closed
@cossio

Description

@cossio

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions