# Using MathOptInterface with custom NL objective

**URL:** <https://discourse.julialang.org/t/using-mathoptinterface-with-custom-nl-objective/69823>\
**Category:** Optimization (Mathematical)\
**Created:** [October 15, 2021, 12:14pm UTC](https://discourse.julialang.org/t/using-mathoptinterface-with-custom-nl-objective/69823 "2021-10-15T12:14:22Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![egvila](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/egvila/32/21626_2.png) [@egvila](https://discourse.julialang.org/u/egvila)\
**Post date:** [October 15, 2021, 12:14pm UTC](https://discourse.julialang.org/t/using-mathoptinterface-with-custom-nl-objective/69823/1 "2021-10-15T12:14:22Z")

</div>

I am having trouble passing a custom objective function to MOI. Here’s an example:

```julia
struct dumbEval <: MOI.AbstractNLPEvaluator end

e = dumbEval();

nlpBlockData = MOI.NLPBlockData([], e, true);

o = Ipopt.Optimizer();

x = MOI.add_variable(o);

MOI.set(o, MOI.NLPBlock(), nlpBlockData)

function MOI.initialize(e::dumbEval, requested_features::Vector{Symbol})
    return nothing
end

function MOI.features_available(e::dumbEval)
    return []
end

function MOI.eval_objective(e::dumbEval, x)
    return 1.0
end

MOI.optimize!(o)

```

Ipopt evaluates the objective at 0.0, instead of 1.0. What am I doing wrong?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [October 15, 2021, 9:46pm UTC](https://discourse.julialang.org/t/using-mathoptinterface-with-custom-nl-objective/69823/2 "2021-10-15T21:46:42Z")

</div>

I strongly encourage you to use JuMP instead of MOI directly (or other Julia packages like Optim, GalacticOptim, etc.).

The MathOptInterface API is complex to implement, and even more so for nonlinear problems.  
You had a few things missing:

- You did not check `requested_features` to see what Ipopt asked for (it asked for `:grad`)
- Thus `features_available` should return `[:grad]`, and you needed to implement `eval_objective_gradient`
- You need to set an `ObjectiveSense`

Here’s is the example working, but again, I would encourage you to use JuMP instead.

```nohighlight
using Ipopt
const MOI = Ipopt.MOI
struct dumbEval <: MOI.AbstractNLPEvaluator end
MOI.initialize(::dumbEval, ::Vector{Symbol}) = nothing
MOI.features_available(::dumbEval) = [:Grad]
MOI.eval_objective(::dumbEval, ::Vector{Float64}) = 1.0
function MOI.eval_objective_gradient(
    ::dumbEval, 
    g::Vector{Float64}, 
    x::Vector{Float64},
)
    g .= 0.0
    return
end
o = Ipopt.Optimizer()
x = MOI.add_variable(o)
MOI.set(o, MOI.NLPBlock(), MOI.NLPBlockData([], dumbEval(), true))
MOI.set(o, MOI.ObjectiveSense(), MOI.MIN_SENSE)
MOI.optimize!(o)

```

---

<div class="post-metadata">

**Author:** ![egvila](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/egvila/32/21626_2.png) [@egvila](https://discourse.julialang.org/u/egvila)\
**Post date:** [October 29, 2021, 12:51pm UTC](https://discourse.julialang.org/t/using-mathoptinterface-with-custom-nl-objective/69823/3 "2021-10-29T12:51:56Z")

</div>

Thank you for the clarification. I was missing

```julia
MOI.set(optimizer, MOI.ObjectiveSense(), MOI.MIN_SENSE)

```

which I was assuming would just default to MIN…  
I appreciate how much easier JuMP is to use, but I want (custom) Hessians of nonlinear, multivariate functions, which only seem to be possible through MOI directly.
