# Differences between NLsolve and Optim in solving system of equations

**URL:** https://discourse.julialang.org/t/differences-between-nlsolve-and-optim-in-solving-system-of-equations/60467
**Category:** Optimization (Mathematical)
**Created:** [May 3, 2021, 3:17pm UTC](https://discourse.julialang.org/t/differences-between-nlsolve-and-optim-in-solving-system-of-equations/60467 "2021-05-03T15:17:40Z")
**Posts on this page:** 5
**Page:** 2

<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: [May 10, 2021, 6:18am UTC](https://discourse.julialang.org/t/differences-between-nlsolve-and-optim-in-solving-system-of-equations/60467/21 "2021-05-10T06:18:37Z")

</div>

Thank you!

---

<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: [May 10, 2021, 7:28am UTC](https://discourse.julialang.org/t/differences-between-nlsolve-and-optim-in-solving-system-of-equations/60467/22 "2021-05-10T07:28:59Z")

</div>

Does that solver have some type instability?

```julia
using NLSolvers,ForwardDiff

function F_rosenbrock!(Fx, x)
    Fx[1] = 1 - x[1]
    Fx[2] = 10(x[2]-x[1]^2)
    return Fx
end

function customnlsolve(f!,x0,method=TrustRegion(Newton(), Dogleg()),options=NEqOptions())
    len = length(x0)
    xcache = zeros(eltype(x0),len)
    Fcache = zeros(eltype(x0),len)
    JCache = zeros(eltype(x0),len,len)
    jconfig = ForwardDiff.JacobianConfig(f!,x0,x0)
    function j!(J,x)
        #@show J
        ForwardDiff.jacobian!(J,f!,Fcache,x,jconfig)
    end
    function fj!(F,J,x) 
        #@show J,F
        ForwardDiff.jacobian!(J,f!,F,x,jconfig)
        F,J
    end
    
    function jv!(x)
        function JacV(Fv,v)
            ForwardDiff.jacobian!(JCache,f!,Fcache,v,jconfig)
            Fv .= Jcache * v
        end
        return LinearMap(JacV,length(x))
    end
    vectorobj = NLSolvers.VectorObjective(f!,j!,fj!,jv!)
    vectorprob = NEqProblem(vectorobj)
    res = solve(vectorprob, x0,method , options)
end

@code_warntype customnlsolve(F_rosenbrock!, [0., 0.])

julia> @code_warntype customnlsolve(F_rosenbrock!, [0., 0.])
Variables
  #self#::Core.Const(customnlsolve)
  f!::Core.Const(F_rosenbrock!)
  x0::Vector{Float64}

Body::NLSolvers.ConvergenceInfo{TrustRegion{Newton{Direct, typeof(NLSolvers.DefaultNewtonLinsolve), Nothing, Nothing}, Dogleg{Nothing}, NLSolvers.BTR{Nothing}}, _A, NEqOptions{Float64, Int64, Nothing}} where _A
1 ─ %1 = Main.Newton()::Core.Const(Newton{Direct, typeof(NLSolvers.DefaultNewtonLinsolve), Nothing, Nothing}(Direct(), NLSolvers.DefaultNewtonLinsolve, nothing, nothing))
│ %2 = Main.Dogleg()::Core.Const(Dogleg{Nothing}(nothing))
│ %3 = Main.TrustRegion(%1, %2)::Core.Const(TrustRegion{Newton{Direct, typeof(NLSolvers.DefaultNewtonLinsolve), Nothing, Nothing}, Dogleg{Nothing}, NLSolvers.BTR{Nothing}}(Newton{Direct, typeof(NLSolvers.DefaultNewtonLinsolve), Nothing, Nothing}(Direct(), NLSolvers.DefaultNewtonLinsolve, nothing, nothing), Dogleg{Nothing}(nothing), NLSolvers.BTR{Nothing}(nothing)))
│ %4 = Main.NEqOptions()::Core.PartialStruct(NEqOptions{Float64, Int64, Nothing}, Any[Core.Const(0.0), Core.Const(1.0e-8), Core.Const(1.0e-12), Int64, Core.Const(nothing)])
│ %5 = (#self#)(f!, x0, %3, %4)::NLSolvers.ConvergenceInfo{TrustRegion{Newton{Direct, typeof(NLSolvers.DefaultNewtonLinsolve), Nothing, Nothing}, Dogleg{Nothing}, NLSolvers.BTR{Nothing}}, _A, NEqOptions{Float64, Int64, Nothing}} where _A
└── return %5

```

but if I delete the line that defines `jconfig` (and modify the subsequent internal functions), then becomes type stable:

```julia
julia> @code_warntype customnlsolve(F_rosenbrock!, [0., 0.])
Variables
  #self#::Core.Const(customnlsolve)
  f!::Core.Const(F_rosenbrock!)
  x0::Vector{Float64}

Body::NLSolvers.ConvergenceInfo{TrustRegion{Newton{Direct, typeof(NLSolvers.DefaultNewtonLinsolve), Nothing, Nothing}, Dogleg{Nothing}, NLSolvers.BTR{Nothing}}, NamedTuple{(:zero, :best_residual, :ρF0, :ρ2F0, :time, :iter), Tuple{Vector{Float64}, Vector{Float64}, Float64, Float64, Float64, Int64}}, NEqOptions{Float64, Int64, Nothing}}
1 ─ %1 = Main.Newton()::Core.Const(Newton{Direct, typeof(NLSolvers.DefaultNewtonLinsolve), Nothing, Nothing}(Direct(), NLSolvers.DefaultNewtonLinsolve, nothing, nothing))
│ %2 = Main.Dogleg()::Core.Const(Dogleg{Nothing}(nothing))
│ %3 = Main.TrustRegion(%1, %2)::Core.Const(TrustRegion{Newton{Direct, typeof(NLSolvers.DefaultNewtonLinsolve), Nothing, Nothing}, Dogleg{Nothing}, NLSolvers.BTR{Nothing}}(Newton{Direct, typeof(NLSolvers.DefaultNewtonLinsolve), Nothing, Nothing}(Direct(), NLSolvers.DefaultNewtonLinsolve, nothing, nothing), Dogleg{Nothing}(nothing), NLSolvers.BTR{Nothing}(nothing)))
│ %4 = Main.NEqOptions()::Core.PartialStruct(NEqOptions{Float64, Int64, Nothing}, Any[Core.Const(0.0), Core.Const(1.0e-8), Core.Const(1.0e-12), Int64, Core.Const(nothing)])
│ %5 = (#self#)(f!, x0, %3, %4)::NLSolvers.ConvergenceInfo{TrustRegion{Newton{Direct, typeof(NLSolvers.DefaultNewtonLinsolve), Nothing, Nothing}, Dogleg{Nothing}, NLSolvers.BTR{Nothing}}, NamedTuple{(:zero, :best_residual, :ρF0, :ρ2F0, :time, :iter), Tuple{Vector{Float64}, Vector{Float64}, Float64, Float64, Float64, Int64}}, NEqOptions{Float64, Int64, Nothing}}
└── return %5

```

---

<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 10, 2021, 7:31am UTC](https://discourse.julialang.org/t/differences-between-nlsolve-and-optim-in-solving-system-of-equations/60467/23 "2021-05-10T07:31:43Z")

</div>

Ah, yes!, of course, I remembered that on implace functions,ForwardDiff, is type stable,good to remember it again

---

<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: [May 10, 2021, 10:20am UTC](https://discourse.julialang.org/t/differences-between-nlsolve-and-optim-in-solving-system-of-equations/60467/24 "2021-05-10T10:20:49Z")

</div>

but this is coming from `jconfig`, no?

---

<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: [November 16, 2022, 4:04am UTC](https://discourse.julialang.org/t/differences-between-nlsolve-and-optim-in-solving-system-of-equations/60467/25 "2022-11-16T04:04:46Z")

</div>

Sorry for reviving this. I have to ask, isn’t that what GMM does? That is, GMM minimizes a quadratic form of the moment equations?

[Previous page](https://discourse.julialang.org/t/differences-between-nlsolve-and-optim-in-solving-system-of-equations/60467.md?page=1)
