# NLsolve with StaticArrays

I am wondering if there is a way to make `NLsolve` work with `StaticArrays`, because my function is written to take `SVector`.

I thought if I use the keyword argument `inplace=false` as described in here, I would be able to use a function and Jacobian that do not require in-place overwriting of intermediate states, and therefore I could define them as `F = f(x::SVector)` and `J = j(x::SVector)`. I tried this idea by modifying the example shown in `NLsolve`'s README as follows:

``````using NLsolve
using StaticArrays

function f(x::SVector{2})
return @SVector [(x+3)*(x^3-7)+18, sin(x*exp(x)-1)]
end

function j(x::SVector{2})
u = exp(x)*cos(x*exp(x)-1)

return @SMatrix [x^3-7 3*x^2*(x+3); x*u u]
end

nlsolve(f, j, @SVector([0.1,1.2]), inplace=false)
``````

However, `NLsolve` still attempts to overwrite the solution:

``````julia> nlsolve(f, j, @SVector([0.1,1.2]), inplace=false)
ERROR: setindex!(::SVector{2, Float64}, value, ::Int) is not defined.
Stacktrace:
 error(s::String)
@ Base ./error.jl:33
 setindex!(a::SVector{2, Float64}, value::Float64, i::Int64)
@ StaticArrays ~/.julia/packages/StaticArrays/OWJK7/src/indexing.jl:3
[...]
``````

So, I tried to change `SVector` and `SMatrix` in the above example to `MVector` and `MMatrix`, so that the vectors and matrices are modifiable:

``````using NLsolve
using StaticArrays

function f(x::MVector{2})
return @MVector [(x+3)*(x^3-7)+18, sin(x*exp(x)-1)]
end

function j(x::MVector{2})
u = exp(x)*cos(x*exp(x)-1)

return @MMatrix [x^3-7 3*x^2*(x+3); x*u u]
end

nlsolve(f, j, @MVector([0.1,1.2]), inplace=false)
``````

This change eliminates the errors, but generates a wrong solution: the solution doesn’t change from the initial guess `[0.1, 1.2]`:

``````julia> nlsolve(f, j, @MVector([0.1,1.2]), inplace=false)
Results of Nonlinear Solver Algorithm
* Algorithm: Trust-region with dogleg and autoscaling
* Starting Point: [0.1, 1.2]
* Zero: [0.1, 1.2]
* Inf-norm of residuals: 1.656800
* Iterations: 1000
* Convergence: false
* |x - x'| < 0.0e+00: false
* |f(x)| < 1.0e-08: false
* Function Calls (f): 2
* Jacobian Calls (df/dx): 1
``````

Any suggestions?

Here you are creating a new vector, so you lost the track of the original one. Probably this should be:

``````function f(x::MVector{2})
x .= @MVector [(x+3)*(x^3-7)+18, sin(x*exp(x)-1)]
return x # redundant here
end
``````

Thanks for the suggestion. It makes my second example to find the correct solution. But isn’t this effectively making `f` in-place? Such a change doesn’t seem to serve the purpose of using the keyword argument `inplace=false`.

Yes, it is. No, it does not solve your original problem. I would bet (without really knowing) that `inplace=false`, if working, is only creating a copy of the original array to start with. You can do that yourself in a simple interface that copies the `SVector` to an `MVector` if the goal is to preserve the initial point.