Skip to content

Commit 52b5b54

Browse files
committed
newton(): more closely match text-book method, which performs subtraction,
1 parent a319a7a commit 52b5b54

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

src/quantilealgs.jl

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using Roots
2+
13
# Various algorithms for computing quantile
24

35
function quantile_bisect(d::ContinuousUnivariateDistribution, p::Real, lx::T, rx::T) where {T<:Real}
@@ -48,20 +50,20 @@ quantile_bisect(d::ContinuousUnivariateDistribution, p::Real) =
4850
# http://www.statsci.org/smyth/pubs/qinvgaussPreprint.pdf
4951

5052
function newton(f, xs::T=mode(d), tol::Real=1e-12) where {T}
51-
x = xs + f(xs)
53+
x = xs - f(xs)
5254
@assert typeof(x) === T
5355
x0 = T(xs)
5456
while abs(x-x0) > max(abs(x),abs(x0)) * tol
5557
x0 = x
56-
x = x0 + f(x0)
58+
x = x0 - f(x0)
5759
end
5860
return x
5961
end
6062

6163
function quantile_newton(d::ContinuousUnivariateDistribution, p::Real, xs::Real=mode(d), tol::Real=1e-12)
62-
f(x) = (p - cdf(d, x)) / pdf(d, x)
64+
f(x) = -((p - cdf(d, x)) / pdf(d, x))
6365
# FIXME: can this be expressed via `promote_type()`? Test coverage missing.
64-
x = xs + f(xs)
66+
x = xs - f(xs)
6567
T = typeof(x)
6668
if 0 < p < 1
6769
return newton(f, T(xs), tol)
@@ -75,9 +77,9 @@ function quantile_newton(d::ContinuousUnivariateDistribution, p::Real, xs::Real=
7577
end
7678

7779
function cquantile_newton(d::ContinuousUnivariateDistribution, p::Real, xs::Real=mode(d), tol::Real=1e-12)
78-
f(x) = (ccdf(d, x)-p) / pdf(d, x)
80+
f(x) = -((ccdf(d, x)-p) / pdf(d, x))
7981
# FIXME: can this be expressed via `promote_type()`? Test coverage missing.
80-
x = xs + f(xs)
82+
x = xs - f(xs)
8183
T = typeof(x)
8284
if 0 < p < 1
8385
return newton(f, T(xs), tol)
@@ -92,8 +94,8 @@ end
9294

9395
function invlogcdf_newton(d::ContinuousUnivariateDistribution, lp::Real, xs::Real=mode(d), tol::Real=1e-12)
9496
T = typeof(lp - logpdf(d,xs))
95-
f_a(x) = -exp(lp - logpdf(d,x) + logexpm1(max(logcdf(d,x)-lp,0)))
96-
f_b(x) = exp(lp - logpdf(d,x) + log1mexp(min(logcdf(d,x)-lp,0)))
97+
f_a(x) = exp(lp - logpdf(d,x) + logexpm1(max(logcdf(d,x)-lp,0)))
98+
f_b(x) = -exp(lp - logpdf(d,x) + log1mexp(min(logcdf(d,x)-lp,0)))
9799
if -Inf < lp < 0
98100
x0 = T(xs)
99101
if lp < logcdf(d,x0)
@@ -113,8 +115,8 @@ end
113115

114116
function invlogccdf_newton(d::ContinuousUnivariateDistribution, lp::Real, xs::Real=mode(d), tol::Real=1e-12)
115117
T = typeof(lp - logpdf(d,xs))
116-
f_a(x) = exp(lp - logpdf(d,x) + logexpm1(max(logccdf(d,x)-lp,0)))
117-
f_b(x) = -exp(lp - logpdf(d,x) + log1mexp(min(logccdf(d,x)-lp,0)))
118+
f_a(x) = -exp(lp - logpdf(d,x) + logexpm1(max(logccdf(d,x)-lp,0)))
119+
f_b(x) = exp(lp - logpdf(d,x) + log1mexp(min(logccdf(d,x)-lp,0)))
118120
if -Inf < lp < 0
119121
x0 = T(xs)
120122
if lp < logccdf(d,x0)

0 commit comments

Comments
 (0)