diff --git a/src/constraints.jl b/src/constraints.jl index e19d87db48c..cba95aca8a2 100644 --- a/src/constraints.jl +++ b/src/constraints.jl @@ -372,6 +372,29 @@ function set_coefficient(constraint::ConstraintRef{Model, MOICON{F, S}}, return end +""" + value(cref::ConstraintRef) + +Get the primal value of this constraint in the result returned by a solver. That +is, if `cref` is the reference of a constraint `func`-in-`set`, it returns the +value of `func` evaluated at the value of the variables (given by +[`value(::VariableRef)`](@ref)). +Use [`has_values`](@ref) to check if a result exists before asking for values. + +## Note + +For scalar contraints, the constant is moved to the `set` so it is not taken +into account in the primal value of the constraint. For instance, the constraint +`@constraint(model, 2x + 3y + 1 == 5)` is transformed into +`2x + 3y`-in-`MOI.EqualTo(4)` so the value returned by this function is the +evaluation of `2x + 3y`. +``` +""" +function value(cref::ConstraintRef{Model, <:MOICON}) + return reshape(MOI.get(cref.model, MOI.ConstraintPrimal(), cref), + cref.shape) +end + """ shadow_price(constraint::ConstraintRef) diff --git a/test/generate_and_solve.jl b/test/generate_and_solve.jl index 196a9e8021a..0924aaf363f 100644 --- a/test/generate_and_solve.jl +++ b/test/generate_and_solve.jl @@ -64,6 +64,7 @@ @test JuMP.value(x) == 1.0 @test JuMP.value(y) == 0.0 @test JuMP.value(x + y) == 1.0 + @test JuMP.value(c) == 1.0 @test JuMP.objective_value(m) == -1.0 @test JuMP.dual_status(m) == MOI.FEASIBLE_POINT @@ -335,6 +336,12 @@ @test JuMP.has_values(m) @test JuMP.value.(x) == [1.0 2.0; 2.0 4.0] + @test JuMP.value(var_psd) isa Symmetric + @test JuMP.value(var_psd) == [1.0 2.0; 2.0 4.0] + @test JuMP.value(sym_psd) isa Symmetric + @test JuMP.value(sym_psd) == [0.0 2.0; 2.0 3.0] + @test JuMP.value(con_psd) isa Matrix + @test JuMP.value(con_psd) == [0.0 2.0; 2.0 3.0] @test JuMP.has_duals(m) @test JuMP.dual(var_psd) isa Symmetric