Skip to content

Commit e2013a9

Browse files
authored
Fix gamma_inc_inv for some subnormal results (#404) (#406)
1 parent 6fe017e commit e2013a9

File tree

3 files changed

+25
-17
lines changed

3 files changed

+25
-17
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "SpecialFunctions"
22
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
3-
version = "1.8.6"
3+
version = "1.8.7"
44

55
[deps]
66
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"

src/gamma_inc.jl

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -864,16 +864,13 @@ function _gamma_inc(a::Float64, x::Float64, ind::Integer)
864864
throw(DomainError((a, x, ind), "`a` and `x` must be greater than 0 ---- Domain : (0, Inf)"))
865865
elseif a == 0.0 && x == 0.0
866866
throw(DomainError((a, x, ind), "`a` and `x` must be greater than 0 ---- Domain : (0, Inf)"))
867-
elseif a*x == 0.0
868-
if x <= a
869-
return (0.0, 1.0)
870-
else
871-
return (1.0, 0.0)
872-
end
873867
elseif isnan(a) || isnan(x)
874-
return (a*x, a*x)
875-
elseif isinf(x)
868+
ax = a*x
869+
return (ax, ax)
870+
elseif a == 0.0 || isinf(x)
876871
return (1.0, 0.0)
872+
elseif x == 0.0
873+
return (0.0, 1.0)
877874
end
878875

879876
if a >= 1.0
@@ -1042,8 +1039,6 @@ function __gamma_inc_inv(a::Float64, minpq::Float64, pcase::Bool)
10421039
logabsgam = logabsgamma(a)[1]
10431040
# Newton-like higher order iteration with upper limit as 15.
10441041
while t > 1.0e-15 && n < 15
1045-
x = x0
1046-
= x*x
10471042
if !haseta
10481043
dlnr = (1.0 - a)*log(x) + x + logabsgam
10491044
if dlnr > log(floatmax(Float64)/1000.0)
@@ -1068,22 +1063,23 @@ function __gamma_inc_inv(a::Float64, minpq::Float64, pcase::Bool)
10681063
end
10691064

10701065
if a > 0.1
1071-
ck3 = (@horner(x, @horner(a, 1, -3, 2), @horner(a, 4, -4), 2))/(6*x²)
1066+
ck3 = (@horner(x, @horner(a, 1, -3, 2), @horner(a, 4, -4), 2))/(6*x^2)
10721067

10731068
# This check is not in the invincgam subroutine from IncgamFI but it probably
10741069
# should be since the routine fails to compute a finite value for very small p
10751070
if !isfinite(ck3)
10761071
break
10771072
end
1078-
x0 = @horner(ck1, x, 1.0, ck2, ck3)
1073+
Δx = ck1 * @horner(ck1, 1.0, ck2, ck3)
10791074
else
1080-
x0 = @horner(ck1, x, 1.0, ck2)
1075+
Δx = ck1 * @horner(ck1, 1.0, ck2)
10811076
end
10821077
else
1083-
x0 = x + ck1
1078+
Δx = ck1
10841079
end
10851080

1086-
t = abs(x/x0 - 1.0)
1081+
x0 = x + Δx
1082+
t = abs(Δx/x0)
10871083
n += 1
10881084
x = x0
10891085
end

test/gamma_inc.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,22 @@ end
202202
end
203203
end
204204

205-
@testset "Issue 390 part 1" begin
205+
@testset "Issue 390 + 403" begin
206206
a = 1.0309015068677239
207207
q = 0.020202020202020204
208208
@test last(gamma_inc(a, gamma_inc_inv(a, 1 - q, q))) q
209+
210+
a = 0.0016546512046778552
211+
q = 0.7070707070707071
212+
# Mathematica: InverseGammaRegularized[0.0016546512046778552, 0, 1-0.7070707070707071] = 3.04992226601142476643093`9.786272979013901*^-323
213+
@test gamma_inc_inv(a, 1 - q, q) 3e-323
214+
end
215+
216+
@testset "Distributions.jl: Issue 1567" begin
217+
a = 0.0030345129757232197
218+
p = 0.106
219+
# Mathematica: InverseGammaRegularized[0.0030345129757232197, 0, 0.106] = 3.5283979699566549210055643`10.308610719322063*^-322
220+
@test gamma_inc_inv(a, p, 1 - p) 3.5e-322
209221
end
210222
end
211223

0 commit comments

Comments
 (0)