-
-
Notifications
You must be signed in to change notification settings - Fork 397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for constraint with unit coefficients #3786
base: master
Are you sure you want to change the base?
Conversation
Actually, the following requires no modification in JuMP nor MA: using JuMP, Unitful
struct UnitShape{U} <: JuMP.AbstractShape
unit::U
end
function JuMP._complex_convert(::Type{T}, u::Unitful.Quantity{U,A,B}) where {T,U,A,B}
return convert(Unitful.Quantity{T,A,B}, u)
end
JuMP.reshape_vector(v, s::UnitShape) = v[] * s.unit
JuMP.reshape_set(::MOI.Zeros, shape::UnitShape) = MOI.EqualTo(zero(shape.unit))
function JuMP.build_constraint(
::Function,
expr::GenericAffExpr{U},
set::MOI.EqualTo,
) where {U<:Unitful.Quantity}
return VectorConstraint([map_coefficients(c -> c.val, expr) - MOI.constant(set)], MOI.Zeros(1), UnitShape(oneunit(U)))
end
using JuMP, Unitful, HiGHS
model = Model(HiGHS.Optimizer)
@variable(model, x)
a = GenericAffExpr{typeof(1.0u"m"),typeof(x)}(0.0u"m", x => 1.0u"m")
@constraint(model, a == 1u"m")
optimize!(model)
value(x) We have to use |
The approach seems to work ok for constraints, but I can not see how to extend it to the objective function(s). I am not familiar with the use of shapes, but it seems to be designed for a different use and the code becomes a bit hard to understand. I think using bridges would be a more natural approach. It also opens up for the possibility of having (future) solvers that can accept units in their input. That said, I have so far been unable to get a bridge up and running for testing. |
I now have a working version with a constraint bridge (LessThan) and an objective bridge that strips off units at https://github.com/trulsf/UnitJuMP.jl/tree/tf/units_in_affexpr Still a bit simplistic and primitive, but at least it seems doable to use bridges.
|
To follow up a bit on the last comment. I see that a GenericModel has a type argument T<:Real. There are also similar requirements for e.g. LessThan and GreaterThan. Now Quantity<:Number, and it is therefore not possible to make a GenericModel{Quantity} which I guess would be the correct thing to do when using units. Is there a specific reason why coefficients are restricted to being Real? Working with a GenericModel{Float64} works for the model transformation, but e.g. implementing the |
If you have constraints with different units then what you be the type
Currently, only
I think this is the use case it is designed for. The MOI backend of a
We usually want to create new MOI sets in order for sets to support them natively. But for units, what would be the advantage of working with units ? I don't see how that would speed up the solving process. |
This solves an issue that @trulsf is facing in https://github.com/trulsf/UnitJuMP.jl/tree/tf/units_in_affexpr
Before the PR:
After using
MOI.EqualTo(MA.Zero())
:After commenting the lines in
model_convert
Requires jump-dev/MutableArithmetics.jl#294