# Differences between NLsolve and Optim in solving system of equations

Thank you!

Does that solver have some type instability?

``````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> @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
``````
1 Like

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

but this is coming from `jconfig`, no?