41
41
quantile_bisect (d:: ContinuousUnivariateDistribution , p:: Real ) =
42
42
quantile_bisect (d, p, minimum (d), maximum (d))
43
43
44
+ mutable struct ValueAndPredecessor{T}
45
+ storage:: Tuple{T,T}
46
+
47
+ function ValueAndPredecessor {T} (storage:: Tuple{T,T} ) where {T}
48
+ return new (storage)
49
+ end
50
+
51
+ function ValueAndPredecessor {T} () where {T}
52
+ storage = Tuple {T,T} ((T (NaN ),T (NaN )))
53
+ return new (storage)
54
+ end
55
+
56
+ function Base. push! (huh:: ValueAndPredecessor{T} , e:: T ) where {T}
57
+ huh. storage = Tuple {T,T} ((huh. storage[2 ], e))
58
+ end
59
+
60
+ function Base. getindex (ValueAndPredecessor:: ValueAndPredecessor{T} , delay:: Int ):: T where {T}
61
+ return ValueAndPredecessor. storage[length (ValueAndPredecessor. storage) + delay]
62
+ end
63
+ end
64
+
44
65
# if starting at mode, Newton is convergent for any unimodal continuous distribution, see:
45
66
# Göknur Giner, Gordon K. Smyth (2014)
46
67
# A Monotonically Convergent Newton Iteration for the Quantiles of any Unimodal
@@ -49,14 +70,15 @@ quantile_bisect(d::ContinuousUnivariateDistribution, p::Real) =
49
70
50
71
function newton (f, xs:: T = mode (d), tol:: Real = 1e-12 ) where {T}
51
72
converged (a,b) = abs (a- b) <= max (abs (a),abs (b)) * tol
52
- x = xs + f (xs)
53
- @assert typeof (x) === T
54
- x0 = T (xs)
55
- while ! converged (x, x0)
56
- x0 = x
57
- x = x0 + f (x0)
73
+ x = ValueAndPredecessor {T} ()
74
+ push! (x, xs)
75
+ push! (x, x[0 ] + f (x[0 ]))
76
+ while ! converged (x[0 ], x[- 1 ])
77
+ df = f (x[0 ])
78
+ r = x[0 ] + df
79
+ push! (x, r)
58
80
end
59
- return x
81
+ return x[ 0 ]
60
82
end
61
83
62
84
function quantile_newton (d:: ContinuousUnivariateDistribution , p:: Real , xs:: Real = mode (d), tol:: Real = 1e-12 )
0 commit comments