# NonlinearSolve Falsi algorithm: Unexpected ReturnCode

**URL:** <https://discourse.julialang.org/t/nonlinearsolve-falsi-algorithm-unexpected-returncode/102296>\
**Category:** Numerics\
**Tags:** potential-bug, nonlinearsolve\
**Created:** [July 31, 2023, 9:20am UTC](https://discourse.julialang.org/t/nonlinearsolve-falsi-algorithm-unexpected-returncode/102296 "2023-07-31T09:20:15Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![laikq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laikq/32/51949_2.png) [@laikq](https://discourse.julialang.org/u/laikq)\
**Post date:** [July 31, 2023, 9:20am UTC](https://discourse.julialang.org/t/nonlinearsolve-falsi-algorithm-unexpected-returncode/102296/1 "2023-07-31T09:20:15Z")

</div>

I’m observing unexpected behavior in `SimpleNonlinearSolve`/`NonlinearSolve`’s algorithm `Falsi` (an algorithm for finding roots of nonlinear functions). I expect `Falsi` to return a successful return code if it converged, and an unsuccessful one if it couldn’t.

Here is a MWE that contradicts this behavior: For f(x) = 1, `Falsi` shouldn’t be able to converge, and for f(x) = x, `Falsi` should converge with result x=0. Here, exactly the opposite happens:

```julia
using SimpleNonlinearSolve, SciMLBase.ReturnCode
np1 = IntervalNonlinearProblem((x, p) -> 1., (0., 1.))
sol1 = solve(np1, Falsi(); abstol=1e-10)
SciMLBase.successful_retcode(sol1) # returns true (FloatingPointLimit)
np2 = IntervalNonlinearProblem((x, p) -> x, (-1., 1.))
sol2 = solve(np2, Falsi(); abstol=1e-10)
SciMLBase.successful_retcode(sol2) # returns false (MaxIters)

```

Executed using `SciMLBase` v1.94.0 and `SimpleNonlinearSolve` v0.1.18.

Is there something I’m missing/misusing here? I guess I could check for `sign(sol.left) == sign(sol.right)` as a workaround to see if a root could be found.

---

<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:** [July 31, 2023, 12:51pm UTC](https://discourse.julialang.org/t/nonlinearsolve-falsi-algorithm-unexpected-returncode/102296/2 "2023-07-31T12:51:29Z")

</div>

Falsi is not always numerically stable. We are switching the defaults and recommendations towards ITP which should just be better.

```julia
using SimpleNonlinearSolve, SciMLBase.ReturnCode
np1 = IntervalNonlinearProblem((x, p) -> 1., (0., 1.))
sol1 = solve(np1, ITP(); abstol=1e-10)
SciMLBase.successful_retcode(sol1) # returns true (FloatingPointLimit)

```

ITP mixes bisection and falsi to have the guarantees of Bisection but with the speedup potential of Falsi. See:

> <https://github.com/SciML/DiffEqBase.jl/pull/917>
>
> This PR interleaves the bisection and the regula falsi iterations to be able to …handle tricky callbacks without going into maxiters. See discussion in #916

The docs haven’t updated with all of this yet, but I hope it does soon because it’ll be the best choice for almost all situations.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [July 31, 2023, 1:35pm UTC](https://discourse.julialang.org/t/nonlinearsolve-falsi-algorithm-unexpected-returncode/102296/3 "2023-07-31T13:35:19Z")

</div>

I think there’s still a bug here. Falsi should converge in 1 step for linear equations.
