@@ -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 )
2 commit comments
andreasnoack commentedon May 13, 2021
@JuliaRegistrator register
JuliaRegistrator commentedon May 13, 2021
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: