Skip to content

Commit f3d5bd7

Browse files
Sumeghtechsimonbyrne
authored andcommitted
Fix beta/logabsbeta for negative args (#169)
1 parent 032048a commit f3d5bd7

File tree

2 files changed

+59
-16
lines changed

2 files changed

+59
-16
lines changed

src/gamma.jl

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -719,18 +719,38 @@ Euler integral of the first kind ``\\operatorname{B}(x,y) = \\Gamma(x)\\Gamma(y)
719719
"""
720720
function beta end
721721

722-
function beta(x::Real, w::Real)
723-
yx, sx = logabsgamma(x)
724-
yw, sw = logabsgamma(w)
725-
yxw, sxw = logabsgamma(x+w)
726-
return exp(yx + yw - yxw) * (sx*sw*sxw)
722+
function beta(a::Real, b::Real)
723+
#Special case for negative integer argument
724+
if a <= 0.0
725+
if isinteger(a) && 1-a-b > 0
726+
sgn = isinteger(b/2) ? 1 : -1
727+
return sgn* beta(1-a-b,b)
728+
end
729+
end
730+
if b <= 0.0
731+
if isinteger(b) && 1-a-b > 0
732+
sgn = isinteger(a/2) ? 1 : -1
733+
return sgn* beta(1-a-b,a)
734+
end
735+
end
736+
if a < b
737+
a,b = b,a
738+
end
739+
#asymptotic expansion for log(B(a,b)) for |a| >> |b|
740+
if abs(a) > 1e5*abs(b) && abs(a) > 1e5
741+
return exp(loggammadiv(b,a) + loggamma(b))
742+
end
743+
ya, sa = logabsgamma(a)
744+
yb, sb = logabsgamma(b)
745+
yab, sab = logabsgamma(a+b)
746+
return exp(ya + yb - yab) * (sa*sb*sab)
727747
end
728748

729-
function beta(x::Number, w::Number)
730-
yx = loggamma(x)
731-
yw = loggamma(w)
732-
yxw = loggamma(x+w)
733-
return exp(yx + yw - yxw)
749+
function beta(a::Number, b::Number)
750+
ya = loggamma(a)
751+
yb = loggamma(b)
752+
yab = loggamma(a+b)
753+
return exp(ya + yb - yab)
734754
end
735755

736756
"""
@@ -740,7 +760,7 @@ Natural logarithm of the [`beta`](@ref) function ``\\log(|\\operatorname{B}(x,y)
740760
741761
See also [`logabsbeta`](@ref).
742762
"""
743-
logbeta(x::Number, w::Number) = loggamma(x)+loggamma(w)-loggamma(x+w)
763+
logbeta(a::Number, b::Number) = loggamma(a)+loggamma(b)-loggamma(a+b)
744764

745765
"""
746766
logabsbeta(x, y)
@@ -749,11 +769,30 @@ Compute the natural logarithm of the absolute value of the [`beta`](@ref) functi
749769
750770
See also [`logbeta`](@ref).
751771
"""
752-
function logabsbeta(x::Real, w::Real)
753-
yx, sx = logabsgamma(x)
754-
yw, sw = logabsgamma(w)
755-
yxw, sxw = logabsgamma(x+w)
756-
(yx + yw - yxw), (sx*sw*sxw)
772+
function logabsbeta(a::Real, b::Real)
773+
if a <= 0.0
774+
if isinteger(a) && 1-a-b > 0
775+
sgn = isinteger(b/2) ? 1 : -1
776+
return logabsbeta(1-a-b,b)
777+
end
778+
end
779+
if b <= 0.0
780+
if isinteger(b) && 1-a-b > 0
781+
sgn = isinteger(a/2) ? 1 : -1
782+
return logabsbeta(1-a-b,a)
783+
end
784+
end
785+
if a < b
786+
a,b = b,a
787+
end
788+
#asymptotic expansion for log(B(a,b)) for |a| >> |b|
789+
if abs(a) > 1e5*abs(b) && abs(a) > 1e5
790+
return (loggammadiv(b,a) + loggamma(b)), 1
791+
end
792+
ya, sa = logabsgamma(a)
793+
yb, sb = logabsgamma(b)
794+
yab, sab = logabsgamma(a+b)
795+
(ya + yb - yab), (sa*sb*sab)
757796
end
758797
## from base/mpfr.jl
759798

test/runtests.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,10 @@ end
850850
@test beta(3,5) 1/105
851851
@test logbeta(5,4) log(beta(5,4))
852852
@test beta(5,4) beta(4,5)
853+
@test beta(-2.0,2.0) 0.5
854+
@test logabsbeta(-2.0,2.0)[1] -0.69314718055994529
855+
@test beta(1e8,0.5) 0.00017724538531210809
856+
@test logabsbeta(1e8,0.5)[1] -8.637975427801484
853857
@test beta(-1/2, 3) beta(-1/2 + 0im, 3 + 0im) -16/3
854858
@test logabsbeta(-1/2, 3)[1] log(16/3)
855859
@test beta(Float32(5),Float32(4)) == beta(Float32(4),Float32(5))

0 commit comments

Comments
 (0)