jump-dev / Ipopt.jl

A Julia interface to the Ipopt nonlinear solver
https://github.com/coin-or/ipopt
Other
149 stars 58 forks source link

Parsing an NLP #381

Closed matheusdiogenesandrade closed 10 months ago

matheusdiogenesandrade commented 10 months ago

Hello.

I am trying to code a C++ program for the following workflow:

  1. Parsing an NLP;
  2. Solving it through Ipopt; And
  3. Attaining the results.
using JuMP
using Ipopt

### 1) Parsing an NLP
# creating model
model = Model(Ipopt.Optimizer)
set_silent(model)

# vars
@variable(model, x, lower_bound=0, upper_bound=1)
@variable(model, y, lower_bound=0, upper_bound=1)

# contraints
@NLobjective(model, Min, 5 * x * y)
@NLconstraint(model, x + y == 1)
#@NLconstraint(model, x >= 1)

### 2) Solving it through Ipopt
optimize!(model)

### 3) Attaining the results
@show value(x)
@show value(y)

And it seems that this library successfully managed this by wrapping the Ipopt C API, please correct me case I am wrong about my conclusions. So, I would like to know how you managed to perform the parsing phase, that is, how you could transform the simple snippet:

@variable(model, x, lower_bound=0, upper_bound=1)
@variable(model, y, lower_bound=0, upper_bound=1)

# contraints
@NLobjective(model, Min, 5 * x * y)
@NLconstraint(model, x + y == 1)

into the implementation of the functions:

bool get_nlp_info(
        Index&          n,
        Index&          m,
        Index&          nnz_jac_g,
        Index&          nnz_h_lag,
        IndexStyleEnum& index_style
        );

bool get_bounds_info(
        Index   n,
        Number* x_l,
        Number* x_u,
        Index   m,
        Number* g_l,
        Number* g_u
        );

bool get_starting_point(
        Index   n,
        bool    init_x,
        Number* x,
        bool    init_z,
        Number* z_L,
        Number* z_U,
        Index   m,
        bool    init_lambda,
        Number* lambda
        );

bool eval_f(
        Index         n,
        const Number* x,
        bool          new_x,
        Number&       obj_value
        );

bool eval_grad_f(
        Index         n,
        const Number* x,
        bool          new_x,
        Number*       grad_f
        );

bool eval_g(
        Index         n,
        const Number* x,
        bool          new_x,
        Index         m,
        Number*       g
        );

bool eval_jac_g(
        Index         n,
        const Number* x,
        bool          new_x,
        Index         m,
        Index         nele_jac,
        Index*        iRow,
        Index*        jCol,
        Number*       values
        );

bool eval_h(
        Index         n,
        const Number* x,
        bool          new_x,
        Number        obj_factor,
        Index         m,
        const Number* lambda,
        bool          new_lambda,
        Index         nele_hess,
        Index*        iRow,
        Index*        jCol,
        Number*       values
        );

void finalize_solution(
        SolverReturn               status,
        Index                             n,
        const Number*              x,
        const Number*              z_L,
        const Number*              z_U,
        Index                      m,
        const Number*              g,
        const Number*              lambda,
        Number                     obj_value,
        const IpoptData*           ip_data,
        IpoptCalculatedQuantities* ip_cq
        );

Are you delegating the task to some parsing library or are you using some automatic differentiation lib? I tried to read the code, but, honestly, I do not have the expertise with this type of tools, at least not yet.

Thanks for the attention, and BR.

mlubin commented 10 months ago

JuMP implements automatic differentiation. See Section 5 of https://mlubin.github.io/pdf/jump-sirev.pdf. I'm closing as this isn't an issue with Ipopt.jl. Feel free to discuss more at https://discourse.julialang.org/c/domain/opt/13.