# NLsolve with StaticArrays

**URL:** https://discourse.julialang.org/t/nlsolve-with-staticarrays/72465
**Category:** Numerics
**Created:** [December 2, 2021, 3:51pm UTC](https://discourse.julialang.org/t/nlsolve-with-staticarrays/72465 "2021-12-02T15:51:01Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)
#### Post date: [December 2, 2021, 3:51pm UTC](https://discourse.julialang.org/t/nlsolve-with-staticarrays/72465/1 "2021-12-02T15:51:02Z")

</div>

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](https://github.com/JuliaNLSolvers/NLsolve.jl/blob/62a7da8aec95e808fecae1a2a4427d8c2b9f2545/README.md#with-functions-returning-residuals-and-jacobian-as-output), 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](https://github.com/JuliaNLSolvers/NLsolve.jl#simple-example) as follows:

```julia
using NLsolve
using StaticArrays

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

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

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

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

```

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

```julia-repl
julia> nlsolve(f, j, @SVector([0.1,1.2]), inplace=false)
ERROR: setindex!(::SVector{2, Float64}, value, ::Int) is not defined.
Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:33
  [2] 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:

```julia
using NLsolve
using StaticArrays

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

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

    return @MMatrix [x[2]^3-7 3*x[2]^2*(x[1]+3); x[2]*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-repl
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?

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [December 2, 2021, 3:54pm UTC](https://discourse.julialang.org/t/nlsolve-with-staticarrays/72465/2 "2021-12-02T15:54:39Z")

</div>

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

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

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

```

---

<div class="post-metadata">

### Author: ![wsshin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsshin/32/360_2.png) [@wsshin](https://discourse.julialang.org/u/wsshin)
#### Post date: [December 2, 2021, 4:06pm UTC](https://discourse.julialang.org/t/nlsolve-with-staticarrays/72465/3 "2021-12-02T16:06:45Z")

</div>

> [@lmiq](#):
>
> Here you are creating a new vector, so you lost the track of the original one. Probably this should be:

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`.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [December 2, 2021, 4:10pm UTC](https://discourse.julialang.org/t/nlsolve-with-staticarrays/72465/4 "2021-12-02T16:10:44Z")

</div>

> [@wsshin](#):
>
> But isn’t this effectively making `f` in-place?

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.
