-
-
Notifications
You must be signed in to change notification settings - Fork 396
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
Add value
for constraints with a custom var_value
function
#2317
Conversation
I think the reason being it isn't that hard to do obj = constraint_object(c)
value(obj.f, var_value) What were you trying to do that led to this? |
But why is it so complicated, while you can do I'm in the process of rebuilding a part of the constraint matrix for tight constraints. I think there are several blocks of that that might go into JuMP ( |
Codecov Report
@@ Coverage Diff @@
## master #2317 +/- ##
=======================================
Coverage 91.32% 91.33%
=======================================
Files 42 42
Lines 4255 4258 +3
=======================================
+ Hits 3886 3889 +3
Misses 369 369
Continue to review full report at Codecov.
|
Fair point. Do you have a concrete example of what this would be used for? |
I see two main uses:
|
Shall I include code like this in this PR or in a new one, or would you rather not see this in JuMP? (It's very rough right now.) The major goal is to make this kind of code much easier to write (getting the constant from a constraint reference is not straightforward, you have to lose yourself for quite some time in the code — for instance, I could not ask even master's students to find it out for mandatory coursework) and to understand from the user perspective. It's not really new functionality for JuMP, though. In a sense, it's similar to sensitivity analysis: you could already do it before the PRs, but it became very easy to do. function is_tight(con_ref::ConstraintRef{Model, <:_MOICON}, var_value::Function; ε::Float64=1.0e-6)
lhs = value(con_ref, var_value)
rhs = MOI.constant(moi_set(constraint_object(con_ref))) # Only for LessThan/GreaterThan
return abs(lhs - rhs) <= ε # Only for "standard" constraints, not things from constraint programming, of course
end
function coefficients(con_ref::ConstraintRef{Model, <:_MOICON})
nvars = MOI.get(m, MOI.NumberOfVariables())
v = spzeros(nvars) # Or a matrix for several constraints. Sparse works well for me, but not necessarily for others…
for (var, coeff) in jump_function(constraint_object(con_ref)).terms # Only for AffExpr
v[var_to_idx[var]] = coeff
end
return v
end |
Okay. Plugging in new solutions to evaluate a constraint is a reasonable use-case. I can see this being useful for callbacks and future feasibility checkers. Note that the constraint functions can also be vector-valued, so we probably need to ensure The |
So, for I'm improving this PR with documentation, tests, and genericity. |
I have just added a few tests for this functionality, including support for vectors of expressions. Is the current implementation OK? I'm wondering about |
I also have created the package for the functions you would rather see them ripen before inclusion: https://github.com/dourouc05/JuMPFeasibility.jl (tests pass locally, I don't have the bandwidth right now to configure anything online…). I think it would a rather simple extension to check for feasibility of a solution, which could solve #693, just by looping over the constraints (if linear algebra becomes a performance problem, the code could also be extended to generate a constraint matrix to bypass one call to |
This is the idea of MathOptSetDistances, which generalizes your |
I've updated the code in this PR, thanks for your comments! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just needs a docstring.
Better this way? I made a mix between |
This proposes a link between constraints and the
value
method that takes avar_value
argument (JuMP.jl/src/aff_expr.jl
Lines 149 to 162 in e2fd3eb
I was surprised that this was not supported; maybe there was a reason why? (It's the reason why I did not bother adding documentation or tests for now.)