# Make \`find\_zero\` more robust

**URL:** <https://discourse.julialang.org/t/make-find-zero-more-robust/106983>\
**Category:** General Usage\
**Tags:** question, math\
**Created:** [December 1, 2023, 9:03am UTC](https://discourse.julialang.org/t/make-find-zero-more-robust/106983 "2023-12-01T09:03:28Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![rikh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rikh/32/204104_2.png) [@rikh](https://discourse.julialang.org/u/rikh)\
**Post date:** [December 1, 2023, 9:03am UTC](https://discourse.julialang.org/t/make-find-zero-more-robust/106983/1 "2023-12-01T09:03:28Z")

</div>

In my [PowerAnalyses.jl](https://github.com/rikhuijzer/PowerAnalyses.jl) package, I’m having trouble in finding a robust way to solve for zero. It works, but it’s not very robust. For example: [ArgumentError when effect size is small (\<=0.10) · Issue #21 · rikhuijzer/PowerAnalyses.jl · GitHub](https://github.com/rikhuijzer/PowerAnalyses.jl/issues/21).

This is the function (from [`Roots.jl`](https://github.com/JuliaMath/Roots.jl)) that crashes ([source](https://github.com/rikhuijzer/PowerAnalyses.jl/blob/main/src/power.jl)):

```julia
function get_n(T::StatisticalTest; alpha::Real, power::Real, es::Real)
    f(n) = get_alpha(T; es, power, n) - alpha
    initial_value = (2, 1000)
    return find_zero(f, initial_value)
end

```

Is there anyone here who has tips on making `find_zero` more robust?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [December 1, 2023, 9:19am UTC](https://discourse.julialang.org/t/make-find-zero-more-robust/106983/2 "2023-12-01T09:19:26Z")

</div>

Use NonlinearSolve.jl instead. ITP will be a more stable algorithm (and you should get a nice performance boost).

---

<div class="post-metadata">

**Author:** ![lrnv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lrnv/32/19373_2.png) [@lrnv](https://discourse.julialang.org/u/lrnv)\
**Post date:** [December 1, 2023, 10:01am UTC](https://discourse.julialang.org/t/make-find-zero-more-robust/106983/3 "2023-12-01T10:01:12Z")

</div>

> [@ChrisRackauckas](#):
>
> Use [NonlinearSolve.jl](https://juliahub.com/ui/Packages/NonlinearSolve) instead. ITP will be a more stable algorithm

This is weird because you suggest switching interface with an argument about a better algorithm. Roots.jl has ITP : [Reference/API · Roots](https://juliamath.github.io/Roots.jl/stable/reference/#Roots.ITP), so it’ll be IMHO largely easier to simply switch algorithm inside Roots.jl

> [@ChrisRackauckas](#):
>
> and you should get a nice performance boost

If the difference is so impressive, the fruit to make Roots.jl faster is probably low-hanging and we should open an issue on Roots.jl

---

<div class="post-metadata">

**Author:** ![j\_verzani](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/j_verzani/32/8551_2.png) [@j\_verzani](https://discourse.julialang.org/u/j_verzani)\
**Post date:** [December 1, 2023, 2:18pm UTC](https://discourse.julialang.org/t/make-find-zero-more-robust/106983/4 "2023-12-01T14:18:15Z")

</div>

I think the issue is the fixed choice of bracketing interval in the package. With 'Bisection(), these can be infinite, but I think the default is an Alefeld, Potra, Shi algorithm, which is much more efficient, but can have issues if the function evaluates to Inf. For robustness, you could use (0,Inf) with Bisection() at the cost of more function calls. If you have a reasonable starting guess, the default will be a hybrid of a secant method and a bracketing method. That might be more robust as well, but I’m not sure how you would get a working initial guess over all the cases considered in the package.

The ITP algorithm is also available in Roots. I wouldn’t expect much more, but you could experiment.

As for performance, Roots is a bit less performant than NonlinearSolve, but not markedly so. Any thoughts on closing that gap would be most welcome.
