Minimizing a numerical function

I am using Optim.jl to minimize a function:

optimize(δ-> nls_obj(δ, theta2, y, c, d, p0, B), 0, LBFGS(), Optim.Options(g_tol = 1e-2, iterations=100_000, show_trace=true, show_every=50))

Given other input values, function nls_obj maps delta to a real number, but this function does not have an analytical form. When I feed a value of delta into it, the function works as expected. However, the optimization reports error message:

ERROR: MethodError: no method matching optimize(::var"#382#383", ::Int64, ::LBFGS{Nothing,LineSearches.InitialStatic{Float64},LineSearches.HagerZhang{Float64,Base.RefValue{Bool}},Optim.var"#19#21"}, ::Optim.Options{Float64,Nothing})

Is it because I call the optimization in a wrong way?

I think Optim.jl expects your function to take a vector input. Does it work if you do:

optimize(δ-> nls_obj(δ[1], theta2, y, c, d, p0, B), [0.0], LBFGS(), Optim.Options(g_tol = 1e-2, iterations=100_000, show_trace=true, show_every=50))

or, in other words, if you treat the function being optimized as a function of a vector of length 1?

2 Likes

It reports a different error message:

ERROR: MethodError: no method matching -(::Tuple{Float64,Array{Float64,1}}, ::Tuple{Float64,Array{Float64,1}})

Ok, seems like an issue with the function you are minimizing, but it’s impossible to say without more information. Please at least post the full stacktrace and ideally a minimal reproducible example. See Please read: make it easier to help you for more information about making it easier for us to help you.

2 Likes

I think that it’s a problem that nls_obj returns two outputs (well, actually, it returns a length-2 tuple. How could you find the minimum among tuples?). Try making your anonymous objective function only return the first output (if that is what you need).

2 Likes

Good catch! I made a stupid mistake. It works once I make nls_obs returns only obj and incorporate rdeits’ suggestion.

Thank you!

But it seems that the solution differs when I set different start values of delta.

You don’t have to change nls_obj, just make the anonymous function capture the first output, like here

optimize(x->foo(x, a)[1], ...) 

Note the [1]

1 Like

This is a plot for the objective of minimization. Depending on initial value, the solution is either the global minimum or a very negative value which gives a local minimum.
image