@@ -919,9 +919,6 @@ function beta_inc_inv(a::Real, b::Real, p::Real, q::Real)
919
919
end
920
920
921
921
function _beta_inc_inv (a:: Float64 , b:: Float64 , p:: Float64 , q:: Float64 = 1 - p)
922
-
923
- maxiter = 30
924
-
925
922
# change tail if necessary
926
923
if p > 0.5
927
924
y, x = _beta_inc_inv (b, a, q, p)
@@ -937,7 +934,6 @@ function _beta_inc_inv(a::Float64, b::Float64, p::Float64, q::Float64=1-p)
937
934
r = sqrt (- 2 * log (p))
938
935
p_approx = r - @horner (r, 2.30753e+00 , 0.27061e+00 ) / @horner (r, 1.0 , .99229e+00 , .04481e+00 )
939
936
fpu = floatmin (Float64)
940
- sae = log10 (fpu)
941
937
lb = logbeta (a, b)
942
938
943
939
if a > 1.0 && b > 1.0
@@ -971,12 +967,7 @@ function _beta_inc_inv(a::Float64, b::Float64, p::Float64, q::Float64=1-p)
971
967
sq = 1.0
972
968
prev = 1.0
973
969
974
- if x < 1e-200
975
- x = 1e-200
976
- end
977
- if x > .9999
978
- x = .9999
979
- end
970
+ x = clamp (x, fpu, prevfloat (1.0 ))
980
971
981
972
# This first argument was proposed in
982
973
#
@@ -1000,11 +991,11 @@ function _beta_inc_inv(a::Float64, b::Float64, p::Float64, q::Float64=1-p)
1000
991
# The idea with the -5.0/a^2 - 1.0/p^0.2 - 34.0 correction is to
1001
992
# use -2r - 2 (for 16 digits) for large values of a and p but use
1002
993
# a much smaller tolerance for small values of a and p.
1003
- iex = max ( - 5.0 / a^ 2 - 1.0 / p^ 0.2 - 34.0 , sae)
1004
- 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
1005
996
1006
997
# iterate
1007
- for i in 1 : maxiter
998
+ while true
1008
999
p_approx = beta_inc (a, b, x)[1 ]
1009
1000
xin = x
1010
1001
p_approx = (p_approx - p)* min (
@@ -1015,21 +1006,15 @@ function _beta_inc_inv(a::Float64, b::Float64, p::Float64, q::Float64=1-p)
1015
1006
if p_approx * p_approx_prev <= 0.0
1016
1007
prev = max (sq, fpu)
1017
1008
end
1018
- g = 1.0
1019
1009
1020
- tx = x - g * p_approx
1021
- while true
1022
- adj = g * p_approx
1023
- 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
1024
1014
tx = x - adj
1025
- if (prev > sq && tx >= 0.0 && tx <= 1.0 )
1026
- break
1027
- end
1028
- g /= 3.0
1029
1015
end
1030
1016
1031
1017
# check if current estimate is acceptable
1032
- prev, acu, p_approx, x, tx
1033
1018
if prev <= acu || p_approx^ 2 <= acu
1034
1019
x = tx
1035
1020
return (x, 1.0 - x)
@@ -1042,9 +1027,6 @@ function _beta_inc_inv(a::Float64, b::Float64, p::Float64, q::Float64=1-p)
1042
1027
x = tx
1043
1028
p_approx_prev = p_approx
1044
1029
end
1045
-
1046
- @debug " Newton iterations didn't converge in $maxiter iterations. The result might have reduced precision."
1047
- return (x, 1.0 - x)
1048
1030
end
1049
1031
1050
1032
function _beta_inc_inv (a:: T , b:: T , p:: T ) where {T<: Union{Float16, Float32} }
0 commit comments