Basic solving equation with NLsove

Total Julia noob here.

So I would like to ultimately solve an equation f(x,a)=0 for x many times as I vary a and plot the solution as a function of a. Before getting to that though, I am first trying to learn to use NLsolve in a very simple case of the function f(x)=x+1.

I am a bit confused on the usage of NLsolve.
Based on the example in the docs GitHub - JuliaNLSolvers/NLsolve.jl: Julia solvers for systems of nonlinear equations and mixed complementarity problems I try

function f!(F, x)
    F=x+1
end

function j!(J,x)
    J=1
end

NLsolve(f!, j!, 1)

(I am unsure of what to put in the third argument of NLsolve which I guess is the initial condition but I tried a couple things like 1 and [ 0.1; 1.2] which was in the example).

I get this error: https://paste.gg/p/anonymous/d15bfc129c704142888eebc455d3c82c

I would like this to tell me that x=-1.
Any recommendations on how to fix error?

Thanks!

NLsolve uses vectors, so you would need to do something like F[1] = x[1] + 1 and J[1] = 1. What you are doing just assigns new values locally.

Thanks. So now I try:

function f!(F, x)
    F[1]=x[1]+1
end

function j!(J,x)
    J[1]=1
end

NLsolve(f!, j!, 1)

I get:

MethodError: objects of type Module are not callable

Stacktrace:
[1] top-level scope at In[9]:8

NLsolve is the name of the module.
nlsolve is the function (all lower case).

The last argument should be [1], a single-element vector, since your function is 1-dimensional.

Looks like the argument should be [1.0] instead of the int [1], but that’s seems to work thanks.

But now I would like to get a parameter a so that I can solve:
x+a=0 for different a’s.
I try:


for a in range(-1, 1, length=9)
    # a = range(-1, 1, length=9)?
    # for i in length(a)?
    function f!(F, x)
        F[1]=x[1]+a
    end

    function j!(J,x)
        J[1]=1
    end

    nlsolve(f!, j!, 1.0) 
end

MethodError: no method matching nlsolve(::var"#f!#13"{Float64}, ::var"#j!#14", ::Float64)

Put the initial value in a vector: nlsolve(f!, j!, [1.0])

1 Like

Sorry about last embarrassment.
Now I have:

answer=zeros(9)
counter = 1
for a in range(-1, 1, length=9)
    

    function f!(F, x)
        F[1]=x[1]+a
    end

    function j!(J,x)
        J[1]=1
    end

    
    answer[counter]=nlsolve(f!, j!, [1.0]).zero
    counter = counter + 1
end

I get: MethodError: Cannot convert an object of type Array{Float64,1} to an object of type Float64

I guess the type of nlsolve().zero is not compatible with the type of the entries from zeros() function. How can I convert?

Tracking the solution x of f(x,a) = 0 under variations in parameter a is a continuation problem. You might want to use a package that implements continuation algorithms and detects bifurcations in solution curves, like GitHub - bifurcationkit/BifurcationKit.jl: A Julia package to perform Bifurcation Analysis

2 Likes

That’s interesting but I’m worried https://github.com/rveltz/BifurcationKit.jl will be too complicated for me at this stage of my learning. I am trying to do super basic things.

2 Likes

The same problem happens over and over. Nlsolve deals with vectors (multi-dimensional problems) and you keep treating inputs and outputs as scalars. Here you try to assign the result (a vector) to a scalar (answer[counter])

4 Likes

Try to run each command one by one in the REPL by hand, in order to be able to see what the output looks like, in particular what type of object it is.

Once you can run each line by hand and “run the loop by hand” then write the actual loop.

1 Like