# How to help nonlinear solvers by applying bounds

**URL:** https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484
**Category:** Optimization (Mathematical)
**Created:** [October 26, 2021, 4:58am UTC](https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484 "2021-10-26T04:58:13Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)
#### Post date: [October 26, 2021, 4:58am UTC](https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484/1 "2021-10-26T04:58:13Z")

</div>

Apart from `IntervalRootFinding.jl`, is there a way to “help” the solvers by providing bounds on the unknown variables? eg is there a way to inform `NLsolve.jl` or `NonlinearSolvers.jl` that `x[i] >= 0` so that the solver does not look in that region?

---

<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: [October 26, 2021, 4:04pm UTC](https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484/2 "2021-10-26T16:04:15Z")

</div>

No, but you can rewrite `f` to enforce it through change of variables formulae

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [October 26, 2021, 11:18pm UTC](https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484/3 "2021-10-26T23:18:00Z")

</div>

Not recommended if you can avoid it through e.g. change of variables as mentioned, but you could add something like `x[i] = (y[i])^2` or `x[i] = exp(y[i])` for a free real variable `y[i]`.

---

<div class="post-metadata">

### Author: ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)
#### Post date: [October 26, 2021, 11:21pm UTC](https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484/4 "2021-10-26T23:21:17Z")

</div>

Yes, I know those options. But what about providing the solver a box in which I know the zero is located?

EDIT: Now that I think about it, I could modify a logistic curve to map the reals to an interval.

---

<div class="post-metadata">

### Author: ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)
#### Post date: [October 27, 2021, 12:54am UTC](https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484/5 "2021-10-27T00:54:39Z")

</div>

How effective is to add penalty terms to the residuals of the system? something like:

```julia
function f!(res, x)
    res[1] = f(x) + 100*(x[1] > 0)
    res[2] = g(x) + 100*(x[2] > 0)
end

```

---

<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: [October 27, 2021, 10:50am UTC](https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484/6 "2021-10-27T10:50:56Z")

</div>

Those penalties have zero derivative so they won’t naturally pull things back into the good set.

---

<div class="post-metadata">

### Author: ![pkofod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pkofod/32/2179_2.png) [@pkofod](https://discourse.julialang.org/u/pkofod)
#### Post date: [October 27, 2021, 8:31pm UTC](https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484/7 "2021-10-27T20:31:35Z")

</div>

I don’t necessarily know if (aside from looking at interval methods) it makes sense to say that you’re “helping” the algorithm in any way. You can project, etc to enforce it, but the bounds don’t really help any method that I can think of if we’re talking about multivariate problems. If you’re thinking about something like bisection/Brent’s method for root finding or some other univariate method that starts with a bracket/interval and shrinks it, sure, but otherwise no. There’s no guarantee that imposing a box known to contain the solution (by projection for example) will make something like Newton’s method converge in fewer iterations. It might actually get stuck trying to go beyond the boundary to look for a root/zero of a function, and end up stopping without finding a root if you do so.

---

<div class="post-metadata">

### Author: ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)
#### Post date: [October 27, 2021, 9:10pm UTC](https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484/8 "2021-10-27T21:10:04Z")

</div>

I see, but there is a case for it enforcing bounds to prevent the algorithm from going into regions in which the system is not defined. For example if the system has logarithms, we don’t want the algorithm to try negative numbers.

---

<div class="post-metadata">

### Author: ![liuyxpp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liuyxpp/32/9870_2.png) [@liuyxpp](https://discourse.julialang.org/u/liuyxpp)
#### Post date: [October 28, 2021, 2:57am UTC](https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484/9 "2021-10-28T02:57:39Z")

</div>

In chemical physics, the volume fraction, \phi, is strictly in the range [0,1]. And it is very common that we have equations containing terms like \log{\phi} or \log{(1-\phi)}. It is really helpful if we can tell the algorithm that we should really stay in the range [0,1], otherwise, the algorithm will simply fail due to the evaluation of \log if a bad initial value is provided. I have many root finding problems which really need algorithms free of being afraid of this issue.

---

<div class="post-metadata">

### Author: ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)
#### Post date: [October 28, 2021, 3:55am UTC](https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484/10 "2021-10-28T03:55:17Z")

</div>

I don’t know why parameterizing variables is not recommended, but you can parameterize `ϕ` with a logistic transform that maps the reals to [0, 1]:

```julia
logistic(x) = inv(1 + exp(-x))

function system(x)
    ϕ = logistic(x)
    f(ϕ)
end

```

The only problems I can imagine is that the logistic map is not very sensitive for values far away from 0.

---

<div class="post-metadata">

### Author: ![pkofod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pkofod/32/2179_2.png) [@pkofod](https://discourse.julialang.org/u/pkofod)
#### Post date: [October 28, 2021, 7:46am UTC](https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484/11 "2021-10-28T07:46:01Z")

</div>

Sure, if you just want it to stay in that region you can check before you evaluate, and if it’s outside return NaN of some other non-finite value. For the bad initial values, you can control that as a user by moving it inside the interval if you were otherwise going to start outside.

---

<div class="post-metadata">

### Author: ![ctkelley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ctkelley/32/10684_2.png) [@ctkelley](https://discourse.julialang.org/u/ctkelley)
#### Post date: [October 28, 2021, 9:59am UTC](https://discourse.julialang.org/t/how-to-help-nonlinear-solvers-by-applying-bounds/70484/12 "2021-10-28T09:59:24Z")

</div>

If \phi is not to close to 1, your solution should be fine. The risk is that you will push x to \infty and get near to singularity. The best way to tell is to do the experiment and see what happens for youur problem.

You could also reformulate the problem as a bound constrained nonlinear least squares problem. The danger there is you could wind up at a local minimum on the boundary.
