Skip to content

Commit 6f0a9a5

Browse files
committed
exact left and right options in bisection
1 parent c998ed5 commit 6f0a9a5

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

src/bisection.jl

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
struct Bisection <: AbstractBracketingAlgorithm
2+
exact_left::Bool
3+
exact_right::Bool
4+
end
5+
6+
function Bisection(;exact_left=false, exact_right=false)
7+
Bisection(exact_left, exact_right)
28
end
39

410
mutable struct BisectionCache{uType}
@@ -95,7 +101,7 @@ function perform_step!(solver, alg::Bisection, cache)
95101
fl * fr > fzero && error("Bracket became non-containing in between iterations. This could mean that "
96102
+ "input function crosses the x axis multiple times. Bisection is not the right method to solve this.")
97103

98-
mid = (left + right) / 2.0
104+
mid = (left + right) / 2
99105

100106
if left == mid || right == mid
101107
solver.force_stop = true
@@ -106,9 +112,22 @@ function perform_step!(solver, alg::Bisection, cache)
106112
fm = f(mid, p)
107113

108114
if iszero(fm)
109-
cache.state = 1
110-
cache.right = mid
111-
cache.left = mid
115+
if alg.exact_left
116+
cache.state = 1
117+
cache.right = mid
118+
cache.left = mid
119+
elseif alg.exact_right
120+
solver.left = prevfloat_tdir(mid, left, right)
121+
sync_residuals!(solver)
122+
cache.state = 2
123+
cache.left = mid
124+
else
125+
solver.left = prevfloat_tdir(mid, left, right)
126+
solver.right = nextfloat_tdir(mid, left, right)
127+
sync_residuals!(solver)
128+
solver.force_stop = true
129+
return
130+
end
112131
else
113132
if sign(fm) == sign(fl)
114133
solver.left = mid
@@ -119,11 +138,18 @@ function perform_step!(solver, alg::Bisection, cache)
119138
end
120139
end
121140
elseif cache.state == 1
122-
mid = (left + cache.right) / 2.0
141+
mid = (left + cache.right) / 2
123142

124143
if cache.right == mid || left == mid
125-
cache.state = 2
126-
return
144+
if alg.exact_right
145+
cache.state = 2
146+
return
147+
else
148+
solver.right = nextfloat_tdir(mid, left, right)
149+
sync_residuals!(solver)
150+
solver.force_stop = true
151+
return
152+
end
127153
end
128154

129155
fm = f(mid, p)
@@ -135,7 +161,7 @@ function perform_step!(solver, alg::Bisection, cache)
135161
solver.fl = fm
136162
end
137163
else
138-
mid = (cache.left + right) / 2.0
164+
mid = (cache.left + right) / 2
139165

140166
if right == mid || cache.left == mid
141167
solver.force_stop = true

src/utils.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
Move `x` one floating point towards x0.
55
"""
66
function prevfloat_tdir(x::T, x0::T, x1::T)::T where {T}
7-
x1 > x0 : prevfloat(x) : nextfloat(x)
7+
x1 > x0 ? prevfloat(x) : nextfloat(x)
8+
end
9+
10+
function nextfloat_tdir(x::T, x0::T, x1::T)::T where {T}
11+
x1 > x0 ? nextfloat(x) : prevfloat(x)
812
end
9-

0 commit comments

Comments
 (0)