@@ -934,7 +934,6 @@ function _beta_inc_inv(a::Float64, b::Float64, p::Float64, q::Float64=1-p)
934
934
r = sqrt (- 2 * log (p))
935
935
p_approx = r - @horner (r, 2.30753e+00 , 0.27061e+00 ) / @horner (r, 1.0 , .99229e+00 , .04481e+00 )
936
936
fpu = floatmin (Float64)
937
- sae = log10 (fpu)
938
937
lb = logbeta (a, b)
939
938
940
939
if a > 1.0 && b > 1.0
@@ -968,12 +967,7 @@ function _beta_inc_inv(a::Float64, b::Float64, p::Float64, q::Float64=1-p)
968
967
sq = 1.0
969
968
prev = 1.0
970
969
971
- if x < 0.0001
972
- x = 0.0001
973
- end
974
- if x > .9999
975
- x = .9999
976
- end
970
+ x = clamp (x, fpu, prevfloat (1.0 ))
977
971
978
972
# This first argument was proposed in
979
973
#
@@ -997,8 +991,8 @@ function _beta_inc_inv(a::Float64, b::Float64, p::Float64, q::Float64=1-p)
997
991
# The idea with the -5.0/a^2 - 1.0/p^0.2 - 34.0 correction is to
998
992
# use -2r - 2 (for 16 digits) for large values of a and p but use
999
993
# a much smaller tolerance for small values of a and p.
1000
- iex = max ( - 5.0 / a^ 2 - 1.0 / p^ 0.2 - 34.0 , sae)
1001
- acu = exp10 (iex)
994
+ iex = - 5.0 / a^ 2 - 1.0 / p^ 0.2 - 34.0
995
+ acu = max ( exp10 (iex), 10 * fpu) # 10 * fpu instead of fpu avoids hangs for small values
1002
996
1003
997
# iterate
1004
998
while true
@@ -1012,21 +1006,15 @@ function _beta_inc_inv(a::Float64, b::Float64, p::Float64, q::Float64=1-p)
1012
1006
if p_approx * p_approx_prev <= 0.0
1013
1007
prev = max (sq, fpu)
1014
1008
end
1015
- g = 1.0
1016
1009
1017
- tx = x - g * p_approx
1018
- while true
1019
- adj = g * p_approx
1020
- sq = adj ^ 2
1010
+ adj = p_approx
1011
+ tx = x - adj
1012
+ while prev <= (sq = adj ^ 2 ) || tx < 0.0 || tx > 1.0
1013
+ adj /= 3.0
1021
1014
tx = x - adj
1022
- if (prev > sq && tx >= 0.0 && tx <= 1.0 )
1023
- break
1024
- end
1025
- g /= 3.0
1026
1015
end
1027
1016
1028
1017
# check if current estimate is acceptable
1029
-
1030
1018
if prev <= acu || p_approx^ 2 <= acu
1031
1019
x = tx
1032
1020
return (x, 1.0 - x)
0 commit comments