# Find zero of a nonlinear equation using Julia

**URL:** <https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974>\
**Category:** General Usage\
**Tags:** question, roots, nlsolve\
**Created:** [May 28, 2021, 5:24am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974 "2021-05-28T05:24:38Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![maoc](https://avatars.discourse-cdn.com/v4/letter/m/58956e/32.png) [@maoc](https://discourse.julialang.org/u/maoc)\
**Post date:** [May 28, 2021, 5:24am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/1 "2021-05-28T05:24:38Z")

</div>

After a process usyng the SymPy in Julia, I generated a system of nonlinear equations. For the sake of simplicity, I am going to put an approximation here for the case of just a non-linear equation. What I get is something like this equation:

```julia
R = (p) -> -5.0488*p + p^2.81 - 3.38/( p^(-1.0) )^2.0

```

I can plot the R function

```julia
using Plots
plot(R, 0,8)

```

We can see that the R function has two zeros: p = 0 and 5.850\< p \< 8.75. I would like to find the positive zero. For this, I tryed the nlsolve function but with error:

```julia
using NLsolve
nlsolve(R , 5.8)

MethodError: no method matching nlsolve(::var"#1337#1338", ::Float64)
Closest candidates are:
nlsolve(::Any, ::Any, !Matched::AbstractArray; inplace, kwargs...)

```

First, Where am I going wrong with the nlsolve function?

If possible, I will appreciate a solution using SymPy package in Julia.

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [May 28, 2021, 5:45am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/2 "2021-05-28T05:45:20Z")

</div>

> [@maoc](#):
>
> First, Where am I going wrong with the nlsolve function?
> 
> If possible, I will appreciate a solution using SymPy package in Julia.

mmm, if i remember correctly, nlsolve is for systems of more than variable, requiring a vector as an imput. the [example in their documentation](https://github.com/JuliaNLSolvers/NLsolve.jl) is that they accept a function of the form:

```julia
function f!(F, x)
    F[1] = (x[1]+3)*(x[2]^3-7)+18
    F[2] = sin(x[2]*exp(x[1])-1)
end

```

where `F` is a vector storing the output and `x` is the input. your function could be written as:

```julia
function R(F,p) 
F[1] = -5.0488*p + p^2.81 - 3.38/( p^(-1.0) )^2.0
end
nlsolve(R , [5.8])

```

---

<div class="post-metadata">

**Author:** ![EvoArt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evoart/32/25357_2.png) [@EvoArt](https://discourse.julialang.org/u/EvoArt)\
**Post date:** [May 28, 2021, 6:05am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/3 "2021-05-28T06:05:20Z")

</div>

Have you tried Roots.jl? I’ve never used NSolve. But Roots worked for me for a similar problem.

---

<div class="post-metadata">

**Author:** ![maoc](https://avatars.discourse-cdn.com/v4/letter/m/58956e/32.png) [@maoc](https://discourse.julialang.org/u/maoc)\
**Post date:** [May 28, 2021, 6:16am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/4 "2021-05-28T06:16:03Z")

</div>

This does not work. I think nlsolve works perfectly for one equation only.

---

<div class="post-metadata">

**Author:** ![maoc](https://avatars.discourse-cdn.com/v4/letter/m/58956e/32.png) [@maoc](https://discourse.julialang.org/u/maoc)\
**Post date:** [May 28, 2021, 6:18am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/5 "2021-05-28T06:18:28Z")

</div>

Yes, it works well, but I put just one equation for simplicity. In fact, I have N X S equations and N X S incognitas.

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [May 28, 2021, 6:22am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/6 "2021-05-28T06:22:21Z")

</div>

my function was written incorrectly, this runs without problem and finds a zero

```julia
function R(F,p) #p is a vector too, not a number
F[1] = -5.0488*p[1] + p[1]^2.81 - 3.38/( p[1]^(-1.0) )^2.0
end
nlsolve(R , [5.8])

```

the results are:

```julia
julia> nlsolve(R , [5.8])
Results of Nonlinear Solver Algorithm
 * Algorithm: Trust-region with dogleg and autoscaling
 * Starting Point: [5.8]
 * Zero: [5.934184191445043]
 * Inf-norm of residuals: 0.000000
 * Iterations: 3
 * Convergence: true
   * |x - x'| < 0.0e+00: false
   * |f(x)| < 1.0e-08: true
 * Function Calls (f): 4
 * Jacobian Calls (df/dx): 4

```

---

<div class="post-metadata">

**Author:** ![maoc](https://avatars.discourse-cdn.com/v4/letter/m/58956e/32.png) [@maoc](https://discourse.julialang.org/u/maoc)\
**Post date:** [May 28, 2021, 6:28am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/7 "2021-05-28T06:28:38Z")

</div>

it really works!

---

<div class="post-metadata">

**Author:** ![TheLateKronos](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thelatekronos/32/12824_2.png) [@TheLateKronos](https://discourse.julialang.org/u/TheLateKronos)\
**Post date:** [May 28, 2021, 6:45am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/8 "2021-05-28T06:45:20Z")

</div>

In the root-finding domain, I also want to highlight `IntervalRootFinding.jl`. It aims to find all the roots in the given interval (`0..2` is the interval from 0 to 2), _with a guarantee_:

julia\> using IntervalRootFinding, IntervalArithmetic

```julia
julia> R = (p) -> -5.0488*p + p^2.81 - 3.38/( p^(-1.0) )^2.0
#1 (generic function with 1 method)

julia> roots(R, -1e100..1e100)
2-element Vector{Root{Interval{Float64}}}:
 Root([5.93418, 5.93419], :unique)
 Root([-4.44703e-08, 2.6707e-08], :unknown)

#only positive roots

julia> roots(R, 0..1e100)
2-element Vector{Root{Interval{Float64}}}:
 Root([0, 6.89354e-08], :unknown)
 Root([5.93418, 5.93419], :unique)

```

The `:unknown` state of the root means that there are 0, 1, or multiple roots in the domain. Manual checking can be done after to investigate the root:

```julia
julia> found_roots = roots(R, 0..1e100)
2-element Vector{Root{Interval{Float64}}}:
 Root([0, 6.89354e-08], :unknown)
 Root([5.93418, 5.93419], :unique)

julia> fieldnames(Root)
(:interval, :status)

# finding the output interval for a given input interval:
julia> found_roots[1].interval |> R
[-3.48041e-07, 7.51661e-21]

julia> R(0)
0.0

# see value for the smallest positive incriment:
julia> R(eps())
-1.1210588013454983e-15

# See of the sign is the same when moving a little further from 0:
julia> R(eps()*10)
-1.1210588013454998e-14

# See value for sligthly negative values:
julia> R(-eps())
ERROR: DomainError with -2.220446049250313e-16:
Exponentiation yielding a complex result requires a complex argument.
Replace x^y with (x+0im)^y, Complex(x)^y, or similar.

```

But of course, we found that `R(0)` is a solution. What comes after is more for fun, and to show how one might conduct the investigation.

---

<div class="post-metadata">

**Author:** ![cvanaret](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cvanaret/32/11594_2.png) [@cvanaret](https://discourse.julialang.org/u/cvanaret)\
**Post date:** [May 28, 2021, 8:19am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/9 "2021-05-28T08:19:12Z")

</div>

Definitely!  
Interval methods produce rigorous bounds robust to round-off errors. In particular, the `IntervalRootFinding.jl` package is able to separate and bound all the zeros of the function on a given interval. The proof of existence and unicity of a single root within a sub-interval exploits the [interval Newton method](https://en.wikipedia.org/wiki/Newton%27s_method#Interval_Newton's_method).

---

<div class="post-metadata">

**Author:** ![photor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/photor/32/14343_2.png) [@photor](https://discourse.julialang.org/u/photor)\
**Post date:** [March 3, 2022, 4:33am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/10 "2022-03-03T04:33:03Z")

</div>

For polynomials, maybe PolynomialRoots.jl is the most relevant.

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [January 6, 2023, 8:05pm UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/11 "2023-01-06T20:05:57Z")

</div>

PolynomialRoots.jl works well, because it shows imaginary numbers, but it requires polynomials to be entered as a list. It would be much better if it allowed functions to be entered as functions.

---

<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:** [January 6, 2023, 8:15pm UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/12 "2023-01-06T20:15:29Z")

</div>

The list representation is way better for solving. If you use a function, you can’t recover the coefficients.

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [January 7, 2023, 12:40am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/13 "2023-01-07T00:40:12Z")

</div>

I’m not sure about that. It seems like an extra step.

---

<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:** [January 7, 2023, 12:45am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/14 "2023-01-07T00:45:12Z")

</div>

Consider a quadratic. From the coefficients you can just apply the quadratic formula, but with the function form, you won’t know that you have a quadratic and will have to use a generic nonlinear solve.

---

<div class="post-metadata">

**Author:** ![brett\_knoss](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brett_knoss/32/13050_2.png) [@brett\_knoss](https://discourse.julialang.org/u/brett_knoss)\
**Post date:** [January 7, 2023, 12:47am UTC](https://discourse.julialang.org/t/find-zero-of-a-nonlinear-equation-using-julia/61974/15 "2023-01-07T00:47:16Z")

</div>

Ok, that makes sense. Is there an NL solver that can find imaginary numbers?
