Skip to content
This repository was archived by the owner on Apr 16, 2025. It is now read-only.

Commit bdfe12f

Browse files
Merge pull request #155 from DaniGlez/main
Default ITP parameters update
2 parents 342afe0 + c035945 commit bdfe12f

File tree

1 file changed

+22
-16
lines changed

1 file changed

+22
-16
lines changed

src/bracketing/itp.jl

+22-16
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,20 @@ I. F. D. Oliveira and R. H. C. Takahashi.
1515
The following keyword parameters are accepted.
1616
1717
- `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
1919
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`.
2121
Lower values produce tighter asymptotic behaviour, while higher values improve the
2222
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
2424
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.
2732
2833
### Worst Case Performance
2934
@@ -35,19 +40,19 @@ n½ + `n₀` iterations, where n½ is the number of iterations using bisection
3540
If `f` is twice differentiable and the root is simple, then with `n₀` > 0 the convergence
3641
rate is √`κ₂`.
3742
"""
38-
struct ITP{T} <: AbstractBracketingAlgorithm
39-
k1::T
40-
k2::T
43+
struct ITP{T₁, T₂} <: AbstractBracketingAlgorithm
44+
scaled_k1::T
45+
k2::T
4146
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")
4450
n0 < 0 && error("Hyper-parameter n₀ should not be negative")
4551
if k2 < 1 || k2 > (1.5 + sqrt(5) / 2)
4652
throw(ArgumentError("Hyper-parameter κ₂ should be between 1 and 1 + ϕ where \
4753
ϕ ≈ 1.618... is the golden ratio"))
4854
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)
5156
end
5257
end
5358

@@ -72,8 +77,8 @@ function SciMLBase.solve(prob::IntervalNonlinearProblem, alg::ITP, args...;
7277
end
7378
ϵ = abstol
7479
#defining variables/cache
75-
k1 = alg.k1
7680
k2 = alg.k2
81+
k1 = alg.scaled_k1 * abs(right - left)^(1 - k2)
7782
n0 = alg.n0
7883
n_h = ceil(log2(abs(right - left) / (2 * ϵ)))
7984
mid = (left + right) / 2
@@ -88,7 +93,7 @@ function SciMLBase.solve(prob::IntervalNonlinearProblem, alg::ITP, args...;
8893
while i <= maxiters
8994
span = abs(right - left)
9095
r = ϵ_s - (span / 2)
91-
δ = k1 * (span^k2)
96+
δ = k1 * ((k2 == 2) ? span^2 : (span^k2))
9297

9398
## Interpolation step ##
9499
x_f = left + (right - left) * (fl / (fl - fr))
@@ -119,10 +124,11 @@ function SciMLBase.solve(prob::IntervalNonlinearProblem, alg::ITP, args...;
119124
xp <= tmin && (xp = nextfloat(tmin))
120125
yp = f(xp)
121126
yps = yp * sign(fr)
122-
if yps > 0
127+
T0 = zero(yps)
128+
if yps > T0
123129
right = xp
124130
fr = yp
125-
elseif yps < 0
131+
elseif yps < T0
126132
left = xp
127133
fl = yp
128134
else

0 commit comments

Comments
 (0)