trulsf / UnitJuMP.jl

Julia package allowing unit modelling in JuMP using Unitful
MIT License
20 stars 1 forks source link

Implement constraint duals #7

Open odow opened 2 years ago

odow commented 2 years ago

Currently this is an error:

julia> using UnitJuMP, HiGHS

julia> model = Model(HiGHS.Optimizer);

julia> @variable(model, x, u"m/s")
x m s⁻¹

julia> c = @constraint(model, x >= 1.2u"m/s")
x ≥ 1.2 [m s⁻¹]

julia> @objective(model, Min, 2 * x + 1u"m/s")
2 x + 1 [m s⁻¹]

julia> optimize!(model)
Presolving model
0 rows, 0 cols, 0 nonzeros
0 rows, 0 cols, 0 nonzeros
Presolve : Reductions: rows 0(-1); columns 0(-1); elements 0(-1) - Reduced to empty
Solving the original LP from the solution after postsolve
Model   status      : Optimal
Objective value     :  3.4000000000e+00
HiGHS run time      :          0.00

julia> dual(c)
ERROR: MethodError: no method matching dual(::UnitJuMP.UnitConstraintRef{Unitful.FreeUnits{(m, s⁻¹), 𝐋 𝐓⁻¹, nothing}})
Closest candidates are:
  dual(::VariableRef) at /Users/oscar/.julia/packages/JuMP/0C6kd/src/variables.jl:1283
  dual(::NonlinearConstraintRef{Shape} where Shape<:AbstractShape) at /Users/oscar/.julia/packages/JuMP/0C6kd/src/nlp.jl:211
  dual(::ConstraintRef{var"#s90", var"#s89", Shape} where {var"#s90"<:AbstractModel, var"#s89"<:(MathOptInterface.ConstraintIndex), Shape<:AbstractShape}; result) at /Users/oscar/.julia/packages/JuMP/0C6kd/src/constraints.jl:922
Stacktrace:
 [1] top-level scope
   @ REPL[71]:1

One issue is that it isn't immediately obvious what units to make the duals. If we used the economic interpretation, then it would be [objective units / constraint units]

trulsf commented 2 years ago

Since the objective units are not easily available from the model under the current design, it would be hard to use these for the dual function. An alternative is to use the units of the variable/constraint with an indication to show it is the dual value, e.g. with an asterix: [m/s]*

odow commented 2 years ago

Hmm. Perhaps if we can't get the objective units then 1 / constraint units. Then if you multiply it by the objective units you'll get the right thing.