@@ -919,6 +919,17 @@ See also: [`gamma_inc(a,x,ind)`](@ref SpecialFunctions.gamma_inc).
919919gamma_inc_inv (a:: Real , p:: Real , q:: Real ) = _gamma_inc_inv (promote (float (a), float (p), float (q))... )
920920
921921function _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* 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 )
0 commit comments