# NewtonRaphson from NonlinearSolve.jl is not throwing an error when convergence is not achieved

**URL:** https://discourse.julialang.org/t/newtonraphson-from-nonlinearsolve-jl-is-not-throwing-an-error-when-convergence-is-not-achieved/100780
**Category:** General Usage
**Tags:** question, package, bug
**Created:** [June 24, 2023, 2:35pm UTC](https://discourse.julialang.org/t/newtonraphson-from-nonlinearsolve-jl-is-not-throwing-an-error-when-convergence-is-not-achieved/100780 "2023-06-24T14:35:05Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![RayleighLord](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rayleighlord/32/33592_2.png) [@RayleighLord](https://discourse.julialang.org/u/RayleighLord)
#### Post date: [June 24, 2023, 2:35pm UTC](https://discourse.julialang.org/t/newtonraphson-from-nonlinearsolve-jl-is-not-throwing-an-error-when-convergence-is-not-achieved/100780/1 "2023-06-24T14:35:05Z")

</div>

I think I found a bug in the `NonlinearSolve.jl` package. Consider the problem

```julia
using NonlinearSolve, GLMakie
f(x, p) = tanh(x / 1e-3) + x - 0.5
x0 = 1.0

prob = NonlinearProblem(f, x0)
sol = solve(prob, NewtonRaphson(), abstol=1e-3)

```

which returns

```julia
julia> sol.u
1.5

julia> f(sol.u, nothing)
2.0

```

This is clearly not a converged solution, since it is far from a zero of the function. However, no error is thrown by the solver even though the Newton iterations are not converging. This non-convergence is due to the shape of this nonlinear function

 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/f/9fdd4fdcd9457e911cc6992caf6d6ac4640dc7c9.png)

in the case where the zero is in the steep part of the graph. For an initial condition on the regions of the function dominated by x, you just end up iterating between two different values and do not achieve convergence.

I understand that this is an expected behavior of the Newton Raphson method for this function, but I think `NonlinearSolve.jl` should throw and error instead of letting you think that convergence was achieved.

---

<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: [June 24, 2023, 4:06pm UTC](https://discourse.julialang.org/t/newtonraphson-from-nonlinearsolve-jl-is-not-throwing-an-error-when-convergence-is-not-achieved/100780/2 "2023-06-24T16:06:42Z")

</div>

But `sol.retcode`?

---

<div class="post-metadata">

### Author: ![RayleighLord](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rayleighlord/32/33592_2.png) [@RayleighLord](https://discourse.julialang.org/u/RayleighLord)
#### Post date: [June 24, 2023, 4:12pm UTC](https://discourse.julialang.org/t/newtonraphson-from-nonlinearsolve-jl-is-not-throwing-an-error-when-convergence-is-not-achieved/100780/3 "2023-06-24T16:12:08Z")

</div>

`sol.retcode` gives

```julia
julia> sol.retcode
ReturnCode.MaxIters = 4

```

which I don’t think is correct, right? Since if you look for `sol.stats` gives

```julia
julia> sol.stats
SciMLBase.NLStats(1001, 1000, 1000, 1000, 1000)

```

and it seems that the maximum of 1000 iterations has been reached (I assumed this number is the one by default on the package.

I was expecting an error similar to how it is handled when solving and ODE with `OrdinaryDiffEq`, where it is explicitly stated when the integration is not converging within tolerances for adaptive timesteps.

---

<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: [June 24, 2023, 4:13pm UTC](https://discourse.julialang.org/t/newtonraphson-from-nonlinearsolve-jl-is-not-throwing-an-error-when-convergence-is-not-achieved/100780/4 "2023-06-24T16:13:48Z")

</div>

> [@RayleighLord](#):
>
> which I don’t think is correct, right? Since if you look for `sol.stats` gives

It stopped at max iterations and exited early as a failure. That’s what you’re seeing?

> [@RayleighLord](#):
>
> I was expecting an error similar to how it is handled when solving and ODE with `OrdinaryDiffEq`, where it is explicitly stated when the integration is not converging within tolerances for adaptive timesteps.

OrdinaryDiffEq also returns a `retcode` that describes the solution, the same retcode actually. Indeed we should make NonlinearSolve.jl throw a warning for this case, but that’s a feature request for the repo (or a PR implementation) and not really a Discourse discussion.

---

<div class="post-metadata">

### Author: ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)
#### Post date: [June 24, 2023, 4:29pm UTC](https://discourse.julialang.org/t/newtonraphson-from-nonlinearsolve-jl-is-not-throwing-an-error-when-convergence-is-not-achieved/100780/5 "2023-06-24T16:29:03Z")

</div>

> [@RayleighLord](#):
>
> `ReturnCode.MaxIters = 4`

In case it’s not clear, this is the 4th kind of return code, it doesn’t mean there were only 4 iterations.

---

<div class="post-metadata">

### Author: ![RayleighLord](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rayleighlord/32/33592_2.png) [@RayleighLord](https://discourse.julialang.org/u/RayleighLord)
#### Post date: [June 24, 2023, 4:35pm UTC](https://discourse.julialang.org/t/newtonraphson-from-nonlinearsolve-jl-is-not-throwing-an-error-when-convergence-is-not-achieved/100780/6 "2023-06-24T16:35:04Z")

</div>

Oh, where could I see the meaning of these error codes?

---

<div class="post-metadata">

### Author: ![RayleighLord](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rayleighlord/32/33592_2.png) [@RayleighLord](https://discourse.julialang.org/u/RayleighLord)
#### Post date: [June 24, 2023, 4:39pm UTC](https://discourse.julialang.org/t/newtonraphson-from-nonlinearsolve-jl-is-not-throwing-an-error-when-convergence-is-not-achieved/100780/7 "2023-06-24T16:39:43Z")

</div>

> [@ChrisRackauckas](#):
>
> OrdinaryDiffEq also returns a `retcode` that describes the solution, the same retcode actually. Indeed we should make NonlinearSolve.jl throw a warning for this case, but that’s a feature request for the repo (or a PR implementation) and not really a Discourse discussion.

That would be nice, if I have time next week I may try to implement it myself. The problem is that even though the no convergence information was in the retcode, it did not seem obvious to me and I assumed that the nonlinear solver succeeded. It was not until I plotted the results that I noticed that truly there was no convergence, which I think it could be misleading when using the package.

Even better than a warning, I think that if the full description of the solution object was printed in the REPL would already be okay to see at a glance if convergence happened. Now I was only getting `sol.u` printed in the REPL.

Anyway, thank you a lot for the answers.

---

<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: [June 24, 2023, 4:47pm UTC](https://discourse.julialang.org/t/newtonraphson-from-nonlinearsolve-jl-is-not-throwing-an-error-when-convergence-is-not-achieved/100780/8 "2023-06-24T16:47:37Z")

</div>

> [@RayleighLord](#):
>
> Even better than a warning, I think that if the full description of the solution object was printed in the REPL would already be okay to see at a glance if convergence happened. Now I was only getting `sol.u` printed in the REPL

Yes. If you see the ODESolution in SciMLBase you will find the show overload. We should do the same to NonlinearSolution

---

<div class="post-metadata">

### Author: ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)
#### Post date: [June 24, 2023, 4:48pm UTC](https://discourse.julialang.org/t/newtonraphson-from-nonlinearsolve-jl-is-not-throwing-an-error-when-convergence-is-not-achieved/100780/9 "2023-06-24T16:48:50Z")

</div>

[https://docs.sciml.ai/SciMLBase/stable/interfaces/Solutions/#Specific-Return-Codes](https://docs.sciml.ai/SciMLBase/stable/interfaces/Solutions/#Specific-Return-Codes)
