# How to call nonlinear solver in MathOptInterface

**URL:** <https://discourse.julialang.org/t/how-to-call-nonlinear-solver-in-mathoptinterface/36001>\
**Category:** Optimization (Mathematical)\
**Tags:** question\
**Created:** [March 15, 2020, 4:46am UTC](https://discourse.julialang.org/t/how-to-call-nonlinear-solver-in-mathoptinterface/36001 "2020-03-15T04:46:37Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![zxjroger](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zxjroger/32/11826_2.png) [@zxjroger](https://discourse.julialang.org/u/zxjroger)\
**Post date:** [March 15, 2020, 4:46am UTC](https://discourse.julialang.org/t/how-to-call-nonlinear-solver-in-mathoptinterface/36001/1 "2020-03-15T04:46:38Z")

</div>

I am trying to move from MathProgBase to MathOptInterface. My code works for the former package, but after I rewrote it using the latter package, I got an error saying `Ipopt: Failed to construct problem`. I believe it is because I could not find the correct way to construct the non-linear model. In MathProgBase, it is

```julia
model = MathProgBase.NonlinearModel(IpoptSolver())

```

But I couldn’t find the corresponding one in MathOptInterface. Currently, I wrote

```julia
model = Ipopt.Optimizer()

```

I think it should be something like `Ipopt.NLOptimizer()` instead. Just incase the other part of my code is wrong, I post all the codes below.

```julia
ipopt_gradient(x) = FiniteDiff.finite_difference_gradient(fun_objective, x)

mutable struct matching_ipopt <: MOI.AbstractNLPEvaluator
    enable_hessian::Bool
end

function MOI.initialize(d::matching_ipopt, requested_features::Vector{Symbol})
    for feat in requested_features
        if !(feat in MOI.features_available(d))
            error("Unsupported feature $feat")
        end
    end
end

function MOI.features_available(d::matching_ipopt)
    if d.enable_hessian
        return [:Grad, :Hess]
    else
        return [:Grad]
    end
end

MOI.eval_objective(d::matching_ipopt, x) = fun_objective(x)

MOI.eval_constraint(d::matching_ipopt, g, x) = nothing

function MOI.eval_objective_gradient(d::matching_ipopt, grad_f, x)
    gradient_temp = ipopt_gradient(x)
    grad_f[1] = gradient_temp[1]
    grad_f[2] = gradient_temp[2]
    grad_f[3] = gradient_temp[3]
    grad_f[4] = gradient_temp[4]
    grad_f[5] = gradient_temp[5]
end

model = Ipopt.Optimizer() # How to construct the nonlinear model?

l = [-20.0, 0.0, -20.0, -20.0, -20.0]
u = [20.0, 0.0, 20.0, 20.0, 20.0]
lb = Float64[]
ub = Float64[]
start = [1.0, 1.0, 1.0, 1.0, 1.0]
block_data = MOI.NLPBlockData(MOI.NLPBoundsPair.(lb, ub), matching_ipopt(0), true)
MOI.set(model, MOI.NLPBlock(), block_data)
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
MOI.optimize!(model)

```

---

<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:** [March 16, 2020, 7:38pm UTC](https://discourse.julialang.org/t/how-to-call-nonlinear-solver-in-mathoptinterface/36001/2 "2020-03-16T19:38:32Z")

</div>

`Ipopt.Optimizer` is correct.

In your example, you need to add some variables with `MOI.add_variables(model, 5)`.

Note that it’s easier to help if you can provide a complete working example: [Please read: make it easier to help you - #8](https://discourse.julialang.org/t/psa-make-it-easier-to-help-you/14757/8). In this case, I don’t know what `fun_objective` is, or which packages you are using.

---

<div class="post-metadata">

**Author:** ![zxjroger](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zxjroger/32/11826_2.png) [@zxjroger](https://discourse.julialang.org/u/zxjroger)\
**Post date:** [March 16, 2020, 9:12pm UTC](https://discourse.julialang.org/t/how-to-call-nonlinear-solver-in-mathoptinterface/36001/3 "2020-03-16T21:12:27Z")

</div>

Thank you. I believe you are correct. Now the code works.

---

<div class="post-metadata">

**Author:** ![zxjroger](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zxjroger/32/11826_2.png) [@zxjroger](https://discourse.julialang.org/u/zxjroger)\
**Post date:** [March 17, 2020, 3:06pm UTC](https://discourse.julialang.org/t/how-to-call-nonlinear-solver-in-mathoptinterface/36001/4 "2020-03-17T15:06:53Z")

</div>

Could you tell me what the following code means in the [nlp example](https://github.com/JuliaOpt/MathOptInterface.jl/blob/3f83e4b0da8ade37b312fe83cc6adbb1793214cb/src/Test/nlp.jl#L120)? Thank you.

```julia
MOI.supports(model, MOI.NLPBlock())
MOI.supports_constraint(model, MOI.SingleVariable, MOI.LessThan{Float64})
MOI.supports_constraint(model, MOI.SingleVariable, MOI.GreaterThan{Float64})
MOI.supports(model, MOI.VariablePrimalStart(), MOI.VariableIndex)

```

I am not sure if I should include it in my code.

* * *

It seems that I also forgot to `add_constraint`. I corrected it and attached the new code for anyone interested.

```julia
mutable struct matching_ipopt <: MOI.AbstractNLPEvaluator
    enable_hessian::Bool
end

function MOI.initialize(d::matching_ipopt, requested_features::Vector{Symbol})
    for feat in requested_features
        if !(feat in MOI.features_available(d))
            error("Unsupported feature $feat")
        end
    end
end

function MOI.features_available(d::matching_ipopt)
    if d.enable_hessian
        return [:Grad, :Hess]
    else
        return [:Grad]
    end
end

MOI.eval_objective(d::matching_ipopt, x) = fun_objective(x)

MOI.eval_constraint(d::matching_ipopt, g, x) = nothing

function MOI.eval_objective_gradient(d::matching_ipopt, grad_f, x)
    gradient_temp = fun_gradient(fun_objective, x)
    grad_f[1] = gradient_temp[1]
    grad_f[2] = gradient_temp[2]
    grad_f[3] = gradient_temp[3]
    grad_f[4] = gradient_temp[4]
    grad_f[5] = gradient_temp[5]
end

model = Ipopt.Optimizer(max_iter=1000)
lb = Float64[]
ub = Float64[]
block_data = MOI.NLPBlockData(MOI.NLPBoundsPair.(lb, ub), matching_ipopt(0), true)
v = MOI.add_variables(model, 5)
l = [-20.0, 0.0, -20.0, -20.0, -20.0]
u = [20.0, 20.0, 20.0, 20.0, 20.0]
start = [1.0, 1.0, 1.0, 1.0, 1.0] # starting value
for i in 1:5
    cub = MOI.add_constraint(model, MOI.SingleVariable(v[i]), MOI.LessThan(u[i]))
    clb = MOI.add_constraint(model, MOI.SingleVariable(v[i]), MOI.GreaterThan(l[i]))
    MOI.set(model, MOI.VariablePrimalStart(), v[i], start[i])
end

MOI.set(model, MOI.NLPBlock(), block_data)
MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)
@time MOI.optimize!(model)

#get results
ipopt_status = MOI.get(model, MOI.TerminationStatus())
ipopt_solution = MOI.get(model, MOI.VariablePrimal(), v)
ipopt_objval = MOI.get(model, MOI.ObjectiveValue())

```
