@@ -919,6 +919,17 @@ See also: [`gamma_inc(a,x,ind)`](@ref SpecialFunctions.gamma_inc).
919
919
gamma_inc_inv (a:: Real , p:: Real , q:: Real ) = _gamma_inc_inv (promote (float (a), float (p), float (q))... )
920
920
921
921
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
+
922
933
if p < 0.5
923
934
pcase = true
924
935
porq = p
@@ -943,41 +954,54 @@ function _gamma_inc_inv(a::Float64, p::Float64, q::Float64)
943
954
x0 = gamma_inc_inv_asmall (a, p, q, pcase)
944
955
else # large a
945
956
haseta = true
946
- ( x0,fp) = gamma_inc_inv_alarge (a, porq, s)
957
+ x0, fp = gamma_inc_inv_alarge (a, porq, s)
947
958
end
948
959
949
960
t = 1
950
961
x = x0
951
962
n = 1
952
963
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.
954
965
while t > 1.0e-15 && n < 15
955
966
x = x0
956
967
x² = x* x
957
968
if ! haseta
958
969
dlnr = (1.0 - a)* log (x) + x + logabsgam
959
970
if dlnr > log (floatmax (Float64)/ 1000.0 )
960
- n = 20
971
+ break
961
972
else
962
973
r = exp (dlnr)
963
974
end
964
975
else
965
976
r = - (1 / fp)* x
966
977
end
967
978
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)
978
1000
else
979
- x0 = x + r
1001
+ x0 = @horner (ck1, x, 1.0 , ck2)
980
1002
end
1003
+ else
1004
+ x0 = x + ck1
981
1005
end
982
1006
983
1007
t = abs (x/ x0 - 1.0 )
0 commit comments