JuliaSmoothOptimizers / QuadraticModels.jl

Data structures for linear and quadratic optimization problems based on NLPModels.jl
Other
16 stars 10 forks source link

Error with nonsensical dimensions #70

Closed tmigot closed 2 years ago

tmigot commented 2 years ago

I have a NLPModelMeta of this form:

  Problem name: Generic
   All variables: ████████████████████ 2      All constraints: ████████████████████ 2
            free: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0                 free: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0
           lower: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0                lower: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0
           upper: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0                upper: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0
         low/upp: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0              low/upp: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0
           fixed: ████████████████████ 2                fixed: ████████████████████ 2
          infeas: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0               infeas: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0
            nnzh: ( 33.33% sparsity)   2               linear: ████████████████████ 2
                                                    nonlinear: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0
                                                         nnzj: ( 50.00% sparsity)   2

but ripqp calls the function presolve from this package and returns

  Nonsensical dimensions
  Stacktrace:
    [1] error(s::String)
      @ Base .\error.jl:33
    [2] NLPModelMeta{Float64, Vector{Float64}}(nvar::Int64; x0::Vector{Float64}, lvar::Vector{Float64}, uvar::Vector{Float64}, nlvb::Int64, nlvo::Int64, nlvc::Int64, ncon::Int64, y0::Vector{Float64}, lcon::Vector{Float64}, ucon::Vector{Float64}, nnzo::Int64, nnzj::Int64, lin_nnzj::Int64, nln_nnzj::Int64, nnzh::Int64, lin::UnitRange{Int64}, minimize::Bool, islp::Bool, name::String)
      @ NLPModels .julia\packages\NLPModels\xTGGo\src\nlp\meta.jl:121
    [3] presolve(qm::QuadraticModels.QuadraticModel{Float64, Vector{Float64}, SparseMatricesCOO.SparseMatrixCOO{Float64, Int64}, SparseMatricesCOO.SparseMatrixCOO{Float64, Int64}}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
      @ QuadraticModels .julia\packages\QuadraticModels\etxWq\src\presolve\presolve.jl:61
    [4] presolve
      @ .julia\packages\QuadraticModels\etxWq\src\presolve\presolve.jl:23 [inlined]
geoffroyleconte commented 2 years ago

Can you give me your problem so that I can reproduce the error?

tmigot commented 2 years ago
using QuadraticModels, RipQP
qp = QuadraticModel(zeros(2), zeros(2,2), lvar = zeros(2), uvar = zeros(2))
ripqp(qp)
geoffroyleconte commented 2 years ago

https://github.com/JuliaSmoothOptimizers/NLPModels.jl/blob/94e14baa2cc8584eef2eeb6190b75fdecb7d4458/src/nlp/meta.jl#L120 The presolved problem has a size 0. Maybe we should be able create NLPModelsMeta with nvar = 0?

tmigot commented 2 years ago

Oh, I see. It would make sense to replace nvar < 1 by nvar < 0. Can you open a PR for this?

dpo commented 2 years ago

It's a bit weird to create a problem with 0 variables. Could you show the original problem?

tmigot commented 2 years ago

The origin problem comes from adapting https://github.com/JuliaSmoothOptimizers/SolverTest.jl/pull/26 to QuadraticModels

tmigot commented 2 years ago

After discussion, the solution is to let presolve detect this case.

geoffroyleconte commented 2 years ago

How? It is not an error if the presolved model has 0 variables but I don't know what should be the output in this case.

dpo commented 2 years ago

Please just use a different problem that isn't solved by presolve.

geoffroyleconte commented 2 years ago

I'm not sure I understand. Should we tell the user that he should not try to solve this problem since the presolve solved it with an error message? In any case, I don't see the drawbacks of creating QuadraticModels with 0 variables, since in julia it's possible to create empty Arrays without getting error messages. This will allow codes to be more generic, since if you're solving QuadraticModels in an automated way you don't want to check whether each presolved QuadraticModel has 1 or more variables.

tmigot commented 2 years ago

Without modifying NLPModels we can do 2 things:

@geoffroyleconte what do you think?

geoffroyleconte commented 2 years ago

In the future, if I add more operations to the presolve function, I could be possible that a problem that has initialy not all of its variables fixed became a problem with all its variables fixed after the presolve. That's why I prefer create a model with 0 variables.

tmigot commented 2 years ago

@geoffroyleconte @dpo Is this issue really closed? I believe we also need the RipQP update as I now have:

MethodError: no method matching allocate_workspace(::GenericExecutionStats{Float64, Vector{Float64}}, ::RipQP.InputConfig{Int64}, ::RipQP.InputTol{Float64, Int64}, ::Float64, ::Type{Float64})
  Closest candidates are:
    allocate_workspace(::QuadraticModels.AbstractQuadraticModel, ::RipQP.InputConfig, ::RipQP.InputTol, ::Any, ::DataType) at ~/.julia/packages/RipQP/6e6d0/src/data_initialization.jl:120
geoffroyleconte commented 2 years ago

Yes I have not changed RipQP yet, I'll try to do it today.

geoffroyleconte commented 2 years ago

I've made the changes, waiting for https://github.com/JuliaSmoothOptimizers/QuadraticModels.jl/pull/74 to open a PR in RipQP.

geoffroyleconte commented 2 years ago

This should be fixed with https://github.com/JuliaSmoothOptimizers/RipQP.jl/pull/175. I changed the output stats so that the output status is :first_order when the problem is solved, so I'm making a new major release (0.3).