Convert nl file to mps file using JuMP

As in question: Why I can't read nl file with other solver · Issue #3637 · jump-dev/JuMP.jl · GitHub
When I using the code:

model = read_from_file("my_model.nl"; use_nlp_block = false)
A JuMP Model
Maximization problem with:
Variables: 1792
Objective function type: NonlinearExpr
`NonlinearExpr`-in-`MathOptInterface.EqualTo{Float64}`: 650 constraints
`NonlinearExpr`-in-`MathOptInterface.GreaterThan{Float64}`: 43 constraints
`NonlinearExpr`-in-`MathOptInterface.LessThan{Float64}`: 423 constraints
`VariableRef`-in-`MathOptInterface.GreaterThan{Float64}`: 1763 constraints
`VariableRef`-in-`MathOptInterface.LessThan{Float64}`: 764 constraints
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.
for (F, S) in list_of_constraint_types(model)
    if F == NonlinearExpr
        for ci in all_constraints(model, F, S)
            obj = constraint_object(ci)
            @constraint(model, convert_to_quad(model, obj.func) in obj.set)
            delete(model, ci)
        end
    end
end
InexactError: convert(MathOptInterface.ScalarAffineTerm, *(-1.0, *(MOI.VariableIndex(618), MOI.VariableIndex(63))))

Stacktrace:
 [1] convert(#unused#::Type{MathOptInterface.ScalarAffineTerm{Float64}}, f::MathOptInterface.ScalarNonlinearFunction)
   @ MathOptInterface D:\Julia-1.9.4\JuliaPKG\packages\MathOptInterface\IiXiU\src\functions.jl:1021
 [2] _add_to_function(f::MathOptInterface.ScalarQuadraticFunction{Float64}, arg::MathOptInterface.ScalarNonlinearFunction)
   @ MathOptInterface D:\Julia-1.9.4\JuliaPKG\packages\MathOptInterface\IiXiU\src\functions.jl:1155
 [3] convert(#unused#::Type{MathOptInterface.ScalarQuadraticFunction{Float64}}, f::MathOptInterface.ScalarNonlinearFunction)
   @ MathOptInterface D:\Julia-1.9.4\JuliaPKG\packages\MathOptInterface\IiXiU\src\functions.jl:1197
 [4] convert_to_quad
   @ .\In[2]:2 [inlined]
 [5] macro expansion
   @ D:\Julia-1.9.4\JuliaPKG\packages\MutableArithmetics\NIXlP\src\rewrite.jl:321 [inlined]
 [6] macro expansion
   @ D:\Julia-1.9.4\JuliaPKG\packages\JuMP\R53zo\src\macros.jl:721 [inlined]
 [7] top-level scope
   @ .\In[9]:5

How can I deal with that?
Thanks.

1 Like

Hi @rlacjfjin, thanks for posting here :smile:

Can you provide the my_model.nl file?

You could try:

function convert_to_quad(model::Model, f::NonlinearExpr)
    g = convert(MOI.ScalarQuadraticFunction{Float64}, moi_function(flatten!(f)))
    return jump_function(model, g)
end

But note that converting arbitrary nonlinear expressions to affine or quadratic isn’t explicitly supported by JuMP. At the moment we make a best effort, but we don’t match every case.

The real question is: why are you reading from a .nl file? What are you trying to achieve?

Yes, sure.
But I don’t know how send to you. It seems can’t upload nl file.

1 Like

It seems can’t upload nl file.

Ah, perhaps because you’re a new user. You can email it to me o.dowson@gmail.com

We are currently using IPOPT to solve our model, but it seems to be somewhat unstable. Although we have also provided initial values based on experience, it seems that there are some numerical issues with the model itself, so we want to see what the model looks like in detail.
I konw the model is bilinear, and the bilinear terms are apear in constraints.
Why I want to convert nl file?

  1. We use JuMP modeling, and it seems only can write to nl file, I tried to convert it to mps file, but has some error.
  2. I don’t familiar with nl file, but familiar with mps file, I want to see what’s wrong in the model.
  3. I want to compare the IPOPT and mosek solver, but mosek can’t read my nl file directly, but in small model what you show me the example, it convert mps file and can solve.
  4. If I convert it to mps file, I can try more solver, such as scip, gurobi, and I want to know how about my current solution.
    Thanks.
1 Like

Ok, I send it.

1 Like

If you currently use JuMP to create the NL file, then just swap the solver.

If everything is quadratic, then instead of @NLconstraint and @NLexpression, just use @constraint and @expression.

To use Mosek, do:

using JuMP, MosekTools
model = Model(Mosek.Optimizer)

You can also use any AMPL executable with the AmplNLWriter package:

using JuMP, AmplNLWriter
model = Model(() -> AmplNLWriter.Optimizer("/path/to/scip.exe"))

So the current convert implementation in MOI can’t handle your functions. But here is a different approach that works:

using JuMP
convert_to_quad(x) = x
function convert_to_quad(x::NonlinearExpr)
    head_to_operator = Dict(:+ => +, :* => *, :- => -)
    return reduce(head_to_operator[x.head], convert_to_quad.(x.args))
end
model = read_from_file("/Users/Oscar/Downloads/my_model.nl"; use_nlp_block = false)
for (F, S) in list_of_constraint_types(model)
    if F == NonlinearExpr
        for ci in all_constraints(model, F, S)
            obj = constraint_object(ci)
            @constraint(model, convert_to_quad(obj.func) in obj.set)
            delete(model, ci)
        end
    end
end
set_objective_function(model, convert_to_quad(objective_function(model)))

I think you should consider different approaches that don’t need to write the .nl file though.