Skip to content

Commit

Permalink
add lbinomial
Browse files Browse the repository at this point in the history
  • Loading branch information
freeboson committed Jun 19, 2018
1 parent 1485740 commit f6b551a
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/SpecialFunctions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ else
end

export sinint,
cosint
cosint,
lbinomial

include("bessel.jl")
include("erf.jl")
Expand Down
22 changes: 22 additions & 0 deletions src/gamma.jl
Original file line number Diff line number Diff line change
Expand Up @@ -764,3 +764,25 @@ const lfactorial = lfact
export lfactorial

end # @static if

"""
lbinomial(n, k) = log(abs(binomial(n, k)))
Accurate natural logarithm of the absolute value of the [`binomial`](@ref)
coefficient `binomial(n, k)` for large `n` and `k` near `n/2`.
"""
function lbinomial(n::T, k::T) where {T<:Integer}
S = float(T)
(k < 0) && return typemin(S)
if n < 0
n = -n + k - 1
end
k > n && return typemin(S)
(k == 0 || k == n) && return zero(S)
(k == 1) && return log(abs(n))
if k > (n>>1)
k = n - k
end
-log1p(n) - lbeta(n - k + one(T), k + one(T))
end
lbinomial(n::Integer, k::Integer) = lbinomial(promote(n, k)...)
12 changes: 12 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -636,3 +636,15 @@ end

@test beta(big(1.0),big(1.2)) beta(1.0,1.2) rtol=4*eps()
end

@testset "lbinomial" begin
@test lbinomial(10, -1) == -Inf
@test lbinomial(10, 11) == -Inf
@test lbinomial(10, 0) == 0.0
@test lbinomial(10, 10) == 0.0

@test lbinomial(10, 1) log(10)
@test lbinomial(-6, 10) log(binomial(-6, 10))
@test lbinomial(-6, 11) log(abs(binomial(-6, 11)))
@test @. lbinomial(200, 0:200) log(binomial(BigInt(200), (0:200)))
end

0 comments on commit f6b551a

Please sign in to comment.