@@ -15,15 +15,20 @@ I. F. D. Oliveira and R. H. C. Takahashi.
15
15
The following keyword parameters are accepted.
16
16
17
17
- `n₀::Int = 10`, the 'slack'. Must not be negative. When n₀ = 0 the worst-case is
18
- identical to that of bisection, but increacing n₀ provides greater oppotunity for
18
+ identical to that of bisection, but increasing n₀ provides greater opportunity for
19
19
superlinearity.
20
- - `κ ₁::Float64 = 0.007 `. Must not be negative. The recomended value is `0.2/(x₂ - x₁) `.
20
+ - `scaled_κ ₁::Float64 = 0.2 `. Must not be negative. The recommended value is `0.2`.
21
21
Lower values produce tighter asymptotic behaviour, while higher values improve the
22
22
steady-state behaviour when truncation is not helpful.
23
- - `κ₂::Real = 1.5 `. Must lie in [1, 1+ϕ ≈ 2.62). Higher values allow for a greater
23
+ - `κ₂::Real = 2 `. Must lie in [1, 1+ϕ ≈ 2.62). Higher values allow for a greater
24
24
convergence rate, but also make the method more succeptable to worst-case performance.
25
- In practice, κ=1,2 seems to work well due to the computational simplicity, as κ₂ is used
26
- as an exponent in the method.
25
+ In practice, κ₂=1, 2 seems to work well due to the computational simplicity, as κ₂ is
26
+ used as an exponent in the method.
27
+
28
+ ### Computation of κ₁
29
+
30
+ In the current implementation, we compute κ₁ = scaled_κ₁·|Δx₀|^(1 - κ₂); this allows κ₁ to
31
+ adapt to the length of the interval and keep the proposed steps proportional to Δx.
27
32
28
33
### Worst Case Performance
29
34
@@ -35,19 +40,19 @@ n½ + `n₀` iterations, where n½ is the number of iterations using bisection
35
40
If `f` is twice differentiable and the root is simple, then with `n₀` > 0 the convergence
36
41
rate is √`κ₂`.
37
42
"""
38
- struct ITP{T} <: AbstractBracketingAlgorithm
39
- k1 :: T
40
- k2:: T
43
+ struct ITP{T₁, T₂ } <: AbstractBracketingAlgorithm
44
+ scaled_k1 :: T₁
45
+ k2:: T₂
41
46
n0:: Int
42
- function ITP (; k1:: Real = 0.007 , k2:: Real = 1.5 , n0:: Int = 10 )
43
- k1 < 0 && error (" Hyper-parameter κ₁ should not be negative" )
47
+ function ITP (;
48
+ scaled_k1:: T₁ = 0.2 , k2:: T₂ = 2 , n0:: Int = 10 ) where {T₁ <: Real , T₂ <: Real }
49
+ scaled_k1 < 0 && error (" Hyper-parameter κ₁ should not be negative" )
44
50
n0 < 0 && error (" Hyper-parameter n₀ should not be negative" )
45
51
if k2 < 1 || k2 > (1.5 + sqrt (5 ) / 2 )
46
52
throw (ArgumentError (" Hyper-parameter κ₂ should be between 1 and 1 + ϕ where \
47
53
ϕ ≈ 1.618... is the golden ratio" ))
48
54
end
49
- T = promote_type (eltype (k1), eltype (k2))
50
- return new {T} (k1, k2, n0)
55
+ return new {T₁, T₂} (scaled_k1, k2, n0)
51
56
end
52
57
end
53
58
@@ -72,8 +77,8 @@ function SciMLBase.solve(prob::IntervalNonlinearProblem, alg::ITP, args...;
72
77
end
73
78
ϵ = abstol
74
79
# defining variables/cache
75
- k1 = alg. k1
76
80
k2 = alg. k2
81
+ k1 = alg. scaled_k1 * abs (right - left)^ (1 - k2)
77
82
n0 = alg. n0
78
83
n_h = ceil (log2 (abs (right - left) / (2 * ϵ)))
79
84
mid = (left + right) / 2
@@ -88,7 +93,7 @@ function SciMLBase.solve(prob::IntervalNonlinearProblem, alg::ITP, args...;
88
93
while i <= maxiters
89
94
span = abs (right - left)
90
95
r = ϵ_s - (span / 2 )
91
- δ = k1 * (span^ k2 )
96
+ δ = k1 * ((k2 == 2 ) ? span^ 2 : (span ^ k2) )
92
97
93
98
# # Interpolation step ##
94
99
x_f = left + (right - left) * (fl / (fl - fr))
@@ -119,10 +124,11 @@ function SciMLBase.solve(prob::IntervalNonlinearProblem, alg::ITP, args...;
119
124
xp <= tmin && (xp = nextfloat (tmin))
120
125
yp = f (xp)
121
126
yps = yp * sign (fr)
122
- if yps > 0
127
+ T0 = zero (yps)
128
+ if yps > T0
123
129
right = xp
124
130
fr = yp
125
- elseif yps < 0
131
+ elseif yps < T0
126
132
left = xp
127
133
fl = yp
128
134
else
0 commit comments