Bisections

Bisections work by moving an interval until we observe a sign change (either in the function or its derivative).

Example

We consider the same example as we had when demonstrating backtracking line search:

ls_obj = linesearch_problem(s)

Bracketing

Performing bisections requires providing an initial interval. If we are only given a single point instead of an interval we have to perform bracketing. For bracketing [3] we move an interval successively and simultaneously increase it in the hope that we observe a local minimum (see bracket_minimum).

α₀ = 0.0
(a, c) = bracket_minimum(alpha -> ls_obj.F(alpha, params), α₀)
(1.28, 5.12)

We then use this interval to start the bisection algorithm.

Potential Problem with Backtracking

We here illustrate a potential issue with backtracking. For this consider the following function:

f2(α::T) where {T <: Number} = α^2 - one(T)
α₀ = -10.0
(a, c) = bracket_root(f2, α₀)
(-7.44, 0.23999999999999932)

And when we plot this we find:

If the interval would contain $r_1$ and $r_2$ then we get an error:

bracket_root(f2, 30.)
MethodError: Cannot `convert` an object of type Nothing to an object of type Tuple{Float64, Float64}
The function `convert` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  (::Type{T})(::Any) where T<:Tuple
   @ Base tuple.jl:454
  convert(::Type{T}, !Matched::T) where T<:Tuple
   @ Base essentials.jl:600
  convert(::Type{T}, !Matched::NTuple{N, Any}) where {N, T<:Tuple}
   @ Base essentials.jl:601
  ...