How to use named parameters in objective function in Optimization.jl?

I’d like to refer to my design variables (parameters) by name inside my objective function, like this:

objective(params, data::AbstractVector) =
    sum(@. (params.a * data + params.b)^2)

What’s the recommended way of doing this?


I tried ComponentArrays and Optimization.jl:

import Optimization, Ipopt
using OptimizationMOI, ComponentArrays

objective(params::ComponentVector, data::AbstractVector) = sum(@. (params.a * data + params.b)^2)
data = randn(1000)

# julia> objective(ComponentVector(a=0.2, b=0.1), data)
# 52.10612648965923

prob = Optimization.OptimizationProblem(objective, ComponentVector(a=0.2, b=0.1), data)
# OptimizationProblem. In-place: true
# u0: ComponentVector{Float64}(a = 0.2, b = 0.1)

Now I try to optimize this:

Code with Optimization.jl and ComponentArrays
julia> Optimization.solve(prob, Ipopt.Optimizer())

******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
 Ipopt is released as open source code under the Eclipse Public License (EPL).
         For more information visit https://github.com/coin-or/Ipopt
******************************************************************************

This is Ipopt version 3.14.4, running with linear solver MUMPS 5.4.1.

Number of nonzeros in equality constraint Jacobian...:        0
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:        3

ERROR: MethodError: objects of type Nothing are not callable
Stacktrace:
  [1] eval_objective_gradient(moiproblem::OptimizationMOI.MOIOptimizationProblem{Float64, OptimizationFunction{true, SciMLBase.NoAD, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(a = 1, b = 2)}}}, Vector{Float64}, Matrix{Float64}, Matrix{Float64}, Matrix{Float64}}, G::Vector{Float64}, x::Vector{Float64})
    @ OptimizationMOI ~/.julia/packages/OptimizationMOI/ZoxrV/src/OptimizationMOI.jl:87
  [2] eval_objective_gradient(model::Ipopt.Optimizer, grad::Vector{Float64}, x::Vector{Float64})
    @ Ipopt ~/.julia/packages/Ipopt/rQctM/src/MOI_wrapper.jl:525
  [3] (::Ipopt.var"#eval_grad_f_cb#2"{Ipopt.Optimizer})(x::Vector{Float64}, grad_f::Vector{Float64})
    @ Ipopt ~/.julia/packages/Ipopt/rQctM/src/MOI_wrapper.jl:598
  [4] _Eval_Grad_F_CB(n::Int32, x_ptr::Ptr{Float64}, #unused#::Int32, grad_f::Ptr{Float64}, user_data::Ptr{Nothing})
    @ Ipopt ~/.julia/packages/Ipopt/rQctM/src/C_wrapper.jl:54
  [5] IpoptSolve(prob::Ipopt.IpoptProblem)
    @ Ipopt ~/.julia/packages/Ipopt/rQctM/src/C_wrapper.jl:442
  [6] optimize!(model::Ipopt.Optimizer)
    @ Ipopt ~/.julia/packages/Ipopt/rQctM/src/MOI_wrapper.jl:727
  [7] __solve(prob::OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(a = 1, b = 2)}}}, Vector{Float64}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, opt::Ipopt.Optimizer; maxiters::Nothing, maxtime::Nothing, abstol::Nothing, reltol::Nothing, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ OptimizationMOI ~/.julia/packages/OptimizationMOI/ZoxrV/src/OptimizationMOI.jl:329
  [8] __solve
    @ ~/.julia/packages/OptimizationMOI/ZoxrV/src/OptimizationMOI.jl:276 [inlined]
  [9] #solve#540
    @ ~/.julia/packages/SciMLBase/QqtZA/src/solve.jl:84 [inlined]
 [10] solve(::OptimizationProblem{true, OptimizationFunction{true, SciMLBase.NoAD, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(a = 1, b = 2)}}}, Vector{Float64}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, ::Ipopt.Optimizer)
    @ SciMLBase ~/.julia/packages/SciMLBase/QqtZA/src/solve.jl:78
 [11] top-level scope
    @ REPL[10]:1

julia>

It fails saying “MethodError: objects of type Nothing are not callable”, but I have no idea what it tried to call…

Anyway, let’s enable autodiff:

Same code, but with ForwardDiff (long error message!)
julia> prob = Optimization.OptimizationProblem(Optimization.OptimizationFunction(objective, Optimization.AutoForwardDiff()), ComponentVector(a=0.2, b=0.1), data)
OptimizationProblem. In-place: true
u0: ComponentVector{Float64}(a = 0.2, b = 0.1)

julia> Optimization.solve(prob, Ipopt.Optimizer())
This is Ipopt version 3.14.4, running with linear solver MUMPS 5.4.1.

Number of nonzeros in equality constraint Jacobian...:        0
Number of nonzeros in inequality constraint Jacobian.:        0
Number of nonzeros in Lagrangian Hessian.............:        3

Total number of variables............................:        2
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        0
                     variables with only upper bounds:        0
Total number of equality constraints.................:        0
Total number of inequality constraints...............:        0
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

ERROR: MethodError: no method matching objective(::Vector{Float64}, ::Vector{Float64})

Closest candidates are:
  objective(::ComponentVector, ::AbstractVector)
   @ Main REPL[6]:1

Stacktrace:
  [1] (::OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Optimization.var"#57#74"{ForwardDiff.GradientConfig{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2, ComponentVector{ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2}}, Tuple{Axis{(a = 1, b = 2)}}}}, Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}}, Optimization.var"#60#77"{ForwardDiff.HessianConfig{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2, ComponentVector{ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2}, 2}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2}, 2}}, Tuple{Axis{(a = 1, b = 2)}}}, ComponentVector{ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2}}, Tuple{Axis{(a = 1, b = 2)}}}}, Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}}, Optimization.var"#63#80", Nothing, Optimization.var"#67#84"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Optimization.var"#72#89"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing})(::Vector{Float64}, ::Vararg{Vector{Float64}})
    @ SciMLBase ~/.julia/packages/SciMLBase/QqtZA/src/scimlfunctions.jl:3580
  [2] eval_objective(moiproblem::OptimizationMOI.MOIOptimizationProblem{Float64, OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Optimization.var"#57#74"{ForwardDiff.GradientConfig{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2, ComponentVector{ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2}}, Tuple{Axis{(a = 1, b = 2)}}}}, Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}}, Optimization.var"#60#77"{ForwardDiff.HessianConfig{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2, ComponentVector{ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2}, 2}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2}, 2}}, Tuple{Axis{(a = 1, b = 2)}}}, ComponentVector{ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Float64}, Float64, 2}}, Tuple{Axis{(a = 1, b = 2)}}}}, Optimization.var"#56#73"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}}, Optimization.var"#63#80", Nothing, Optimization.var"#67#84"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Optimization.var"#72#89"{OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(a = 1, b = 2)}}}, Vector{Float64}, Matrix{Float64}, Matrix{Float64}, Matrix{Float64}}, x::Vector{Float64})
    @ OptimizationMOI ~/.julia/packages/OptimizationMOI/ZoxrV/src/OptimizationMOI.jl:78
  [3] eval_objective(model::Ipopt.Optimizer, x::Vector{Float64})
    @ Ipopt ~/.julia/packages/Ipopt/rQctM/src/MOI_wrapper.jl:514
  [4] (::Ipopt.var"#eval_f_cb#1"{Ipopt.Optimizer})(x::Vector{Float64})
    @ Ipopt ~/.julia/packages/Ipopt/rQctM/src/MOI_wrapper.jl:597
  [5] _Eval_F_CB(n::Int32, x_ptr::Ptr{Float64}, x_new::Int32, obj_value::Ptr{Float64}, user_data::Ptr{Nothing})
    @ Ipopt ~/.julia/packages/Ipopt/rQctM/src/C_wrapper.jl:38
  [6] IpoptSolve(prob::Ipopt.IpoptProblem)
    @ Ipopt ~/.julia/packages/Ipopt/rQctM/src/C_wrapper.jl:442
  [7] optimize!(model::Ipopt.Optimizer)
    @ Ipopt ~/.julia/packages/Ipopt/rQctM/src/MOI_wrapper.jl:727
  [8] __solve(prob::OptimizationProblem{true, OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(a = 1, b = 2)}}}, Vector{Float64}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, opt::Ipopt.Optimizer; maxiters::Nothing, maxtime::Nothing, abstol::Nothing, reltol::Nothing, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ OptimizationMOI ~/.julia/packages/OptimizationMOI/ZoxrV/src/OptimizationMOI.jl:329
  [9] __solve
    @ ~/.julia/packages/OptimizationMOI/ZoxrV/src/OptimizationMOI.jl:276 [inlined]
 [10] #solve#540
    @ ~/.julia/packages/SciMLBase/QqtZA/src/solve.jl:84 [inlined]
 [11] solve(::OptimizationProblem{true, OptimizationFunction{true, Optimization.AutoForwardDiff{nothing}, typeof(objective), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, ComponentVector{Float64, Vector{Float64}, Tuple{Axis{(a = 1, b = 2)}}}, Vector{Float64}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, ::Ipopt.Optimizer)
    @ SciMLBase ~/.julia/packages/SciMLBase/QqtZA/src/solve.jl:78
 [12] top-level scope
    @ REPL[14]:1

julia>

Now the error is:

no method matching objective(::Vector{Float64}, ::Vector{Float64})

Well, yes, that’s the point: I don’t want the first argument to be a simple vector. I want something vector-like that lets me refer to its elements by name, like a ComponentVector.

However, ComponentVectors don’t seem to work here because the optimization routine needs a plain Vector

I can easily circumvent this by using a wrapper function whose first argument is a vector. It then creates a ComponentVector and calls the original objective function:

objective(params::Vector, data) =
    objective(ComponentVector(a=params[1], b=params[2]), data)

Then Optimization.solve(prob, Ipopt.Optimizer()) works completely fine.

But this is exactly what I’m trying to avoid: I don’t want to wrap each of my objective functions like this. I’ve been doing this for far too long and am now getting a little frustrated. It’s just boilerplate code and doesn’t get me much closer to solving the actual optimization problem.


What’s the recommended way of accessing design variables by name inside my objective functions?

Open an issue. The issue is that some of the optimizers (MOI here) are not robust to it, so we should create a test that loops through all of them and fix it one by one. I think MOI might be the only one (since it’s the one that doesn’t work by wrapping like this, and instead exposes the parameters to the lower level).

Done: `MethodError: objects of type Nothing are not callable` when optimizing basic function with `OptimizationMOI` and Ipopt · Issue #448 · SciML/Optimization.jl · GitHub. However, this only happens when I don’t use autodiff (so finite differences are used, I presume). When I enable autodiff, basic optimization (with a vector of parameters) works fine.
The main question was how to properly refer to my parameters by name. Thanks for replying literally on New Year’s eve, by the way, I really appreciate it!

ERROR: MethodError: objects of type Nothing are not callable
Stacktrace:
  [1] eval_objective_gradient(moiproblem::OptimizationMOI.MOIOptimizationProblem{Float64, OptimizationFunction{true, SciMLBase.NoAD, typeof(objective_basic), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED_NO_TIME), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Vector{Float64}, Vector{Float64}, Matrix{Float64}, Matrix{Float64}, Matrix{Float64}}, G::Vector{Float64}, x::Vector{Float64})
    @ OptimizationMOI ~/.julia/packages/OptimizationMOI/ZoxrV/src/OptimizationMOI.jl:87

oh that’s because IPOPT requires a gradient. We should make that throw a better error earlier.

1 Like