Use Roots.Brent() in fzero Roots.jl


I would like to use the method Brent-Dekker in Roots.jl without using the find_zero wrapper since I will only do one run of root-finding for the function of interest. fzero seems to be the way to go, but I don’t know how to provide the argument Roots.Brent()

fzero(z->u(z), zlim[1], zlim[2], Roots.Brent())

MethodError: no method matching fzero(::var"#60#62", ::Float64, ::Float64, ::Roots.Brent)
Closest candidates are:
fzero(::Any, ::Any, !Matched::Roots.AbstractUnivariateZeroMethod, ::Roots.AbstractBracketing; kwargs…) at /home/mat/.julia/packages/Roots/sNoys/src/fzero.jl:73
fzero(::Any, ::Number, ::Number; kwargs…) at /home/mat/.julia/packages/Roots/sNoys/src/fzero.jl:85
fzero(::Any, ::Number; kwargs…) at /home/mat/.julia/packages/Roots/sNoys/src/fzero.jl:63

A more mathematical question: which root-finding will you recommend for a monotone increasing function. I can only use bracketing methods since Newton’s method will have a non-convergent cycle.

It looks like x0 must be a tuple for a bracketing solver:

fzero(u, (zlim[1], zlim[2]), Roots.Brent())

As for which method to use, there’s no simple answer. Mathematically, it is best to have a higher \frac{\ln{(order)}}{\text{number of function evaluations per iteration}} ratio. In practice, that depends on the complexity of the function. Higher order methods may require more bookkeeping with a lot of conditionals, and the time per iteration may be mostly due to those conditionals, if the function is relatively cheap. In that case, you may actually save time by doing a few more evaluations of a theoretically “worse” method, but with a more straightforward bracket update logic.

So, try several methods and choose whichever is fastest for your problem.

1 Like

Thank you for your answer, however this is not the syntax written in the documentation of Roots.jl (Section Usage Examples)

f(x) = exp(x) - x^4
## bracketing
fzero(f, 8, 9)		          # 8.613169456441398
fzero(f, -10, 0)		      # -0.8155534188089606
fzeros(f, -10, 10)  

Vasily is correct, you should specify the initial value with a tuple. The fzero interface is not passing through that method argument. I’ll make an issue for that so that your invocation works as expected.