Skip to content

Commit feccbf4

Browse files
authoredMay 13, 2021
Merge pull request #315 from JuliaMath/an/gamma_inc_inv
Some fixes for gamma_inc_inv
2 parents cd39372 + 7104036 commit feccbf4

File tree

2 files changed

+144
-28
lines changed

2 files changed

+144
-28
lines changed
 

‎src/gamma_inc.jl

+38-14
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,17 @@ See also: [`gamma_inc(a,x,ind)`](@ref SpecialFunctions.gamma_inc).
919919
gamma_inc_inv(a::Real, p::Real, q::Real) = _gamma_inc_inv(promote(float(a), float(p), float(q))...)
920920

921921
function _gamma_inc_inv(a::Float64, p::Float64, q::Float64)
922+
923+
if p + q != 1
924+
throw(ArgumentError("p + q must equal one but is $(p + q)"))
925+
end
926+
927+
if iszero(p)
928+
return 0.0
929+
elseif iszero(q)
930+
return Inf
931+
end
932+
922933
if p < 0.5
923934
pcase = true
924935
porq = p
@@ -943,41 +954,54 @@ function _gamma_inc_inv(a::Float64, p::Float64, q::Float64)
943954
x0 = gamma_inc_inv_asmall(a, p, q, pcase)
944955
else #large a
945956
haseta = true
946-
(x0,fp) = gamma_inc_inv_alarge(a, porq, s)
957+
x0, fp = gamma_inc_inv_alarge(a, porq, s)
947958
end
948959

949960
t = 1
950961
x = x0
951962
n = 1
952963
logabsgam = logabsgamma(a)[1]
953-
#Newton-like higher order iteration with upper limit as 15.
964+
# Newton-like higher order iteration with upper limit as 15.
954965
while t > 1.0e-15 && n < 15
955966
x = x0
956967
= x*x
957968
if !haseta
958969
dlnr = (1.0 - a)*log(x) + x + logabsgam
959970
if dlnr > log(floatmax(Float64)/1000.0)
960-
n = 20
971+
break
961972
else
962973
r = exp(dlnr)
963974
end
964975
else
965976
r = -(1/fp)*x
966977
end
967978

968-
(px, qx) = gamma_inc(a, x, 0)
969-
ck1 = pcase ? -r*(px-p) : r*(qx-q)
970-
ck2 = (x - a + 1.0)/(2.0*x)
971-
ck3 = (@horner(x, @horner(a, 1, -3, 2), @horner(a, 4, -4), 2))/(6*x²)
972-
r = ck1
973-
if a > 0.1
974-
x0 = @horner(r, x, 1.0, ck2, ck3)
975-
else
976-
if a > 0.05
977-
x0 = @horner(r, x, 1.0, ck2)
979+
px, qx = gamma_inc(a, x, 0)
980+
981+
ck1 = pcase ? -r*(px - p) : r*(qx - q)
982+
if a > 0.05
983+
ck2 = (x - a + 1.0)/(2.0*x)
984+
985+
# This check is not in the invincgam subroutine from IncgamFI but it probably
986+
# should be since the routine fails to compute a finite value for very small p
987+
if !isfinite(ck2)
988+
break
989+
end
990+
991+
if a > 0.1
992+
ck3 = (@horner(x, @horner(a, 1, -3, 2), @horner(a, 4, -4), 2))/(6*x²)
993+
994+
# This check is not in the invincgam subroutine from IncgamFI but it probably
995+
# should be since the routine fails to compute a finite value for very small p
996+
if !isfinite(ck3)
997+
break
998+
end
999+
x0 = @horner(ck1, x, 1.0, ck2, ck3)
9781000
else
979-
x0 = x + r
1001+
x0 = @horner(ck1, x, 1.0, ck2)
9801002
end
1003+
else
1004+
x0 = x + ck1
9811005
end
9821006

9831007
t = abs(x/x0 - 1.0)

2 commit comments

Comments
 (2)

andreasnoack commented on May 13, 2021

@andreasnoack
MemberAuthor

JuliaRegistrator commented on May 13, 2021

@JuliaRegistrator

Registration pull request created: JuliaRegistries/General/36685

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v1.4.0 -m "<description of version>" feccbf44f8a8caed9a8eb85d4025c8859b9ab537
git push origin v1.4.0
Please sign in to comment.