From 62e91172ca5ca82662f31acb78ec2b526da8c453 Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Mon, 16 Feb 2026 12:56:30 +1300 Subject: [PATCH] Soft-deprecate POI.ParameterDual and POI.ParameterValue --- docs/src/index.md | 7 ++++--- docs/src/reference.md | 10 ---------- src/duals.jl | 27 ++++++++------------------- test/test_JuMP.jl | 6 ++++-- test/test_MathOptInterface.jl | 5 ++++- 5 files changed, 20 insertions(+), 35 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index bbf3d486..aa74a98c 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -215,7 +215,7 @@ choose the approach which works best for your model. In some applications you may need the dual of a parameter. The dual can be computed only if the parameter appears additively in the problem. Query the dual -assocaited with the parameter using [`ParameterDual`](@ref): +associated with the parameter as follows: ```@repl using JuMP, HiGHS import ParametricOptInterface as POI @@ -226,10 +226,11 @@ set_silent(model) @constraint(model, x + p >= 3); @objective(model, Min, 2x); optimize!(model) -get_attribute(p, POI.ParameterDual()) +dual(VariableInSetRef(p)) ``` -Note how the dual is the same as the `reduced_cost` of an equivalent fixed variable: +Note how the dual is the same as the `reduced_cost` of an equivalent fixed +variable: ```@repl using JuMP, HiGHS model = Model(HiGHS.Optimizer); diff --git a/docs/src/reference.md b/docs/src/reference.md index 42864d89..02cb56ef 100644 --- a/docs/src/reference.md +++ b/docs/src/reference.md @@ -21,13 +21,3 @@ Optimizer ```@docs ConstraintsInterpretation ``` - -## `ParameterDual` -```@docs -ParameterDual -``` - -## `ParameterValue` -```@docs -ParameterValue -``` diff --git a/src/duals.jl b/src/duals.jl index 0f871da8..b01633df 100644 --- a/src/duals.jl +++ b/src/duals.jl @@ -139,32 +139,21 @@ function MOI.get( ::ParameterDual, v::MOI.VariableIndex, ) where {T} - if !_is_additive( - model, - MOI.ConstraintIndex{MOI.VariableIndex,MOI.Parameter{T}}(v.value), - ) - error("Cannot compute the dual of a multiplicative parameter") - end - return model.dual_value_of_parameters[p_val(v)] + ci = MOI.ConstraintIndex{MOI.VariableIndex,MOI.Parameter{T}}(v.value) + return MOI.get(model, MOI.ConstraintDual(), ci) end function MOI.get( model::Optimizer{T}, - ::MOI.ConstraintDual, + attr::MOI.ConstraintDual, cp::MOI.ConstraintIndex{MOI.VariableIndex,MOI.Parameter{T}}, ) where {T} if !model.evaluate_duals - throw( - MOI.GetAttributeNotAllowed( - MOI.ConstraintDual(), - "$(MOI.ConstraintDual()) not available when " * - "evaluate_duals is set to false. " * - "Create an optimizer such as POI.Optimizer(HiGHS.Optimizer(); evaluate_duals = true) to enable this feature.", - ), - ) - end - if !_is_additive(model, cp) - error("Cannot compute the dual of a multiplicative parameter") + msg = "$attr not available when evaluate_duals is set to false. Create an optimizer such as `POI.Optimizer(HiGHS.Optimizer(); evaluate_duals = true)` to enable this feature." + throw(MOI.GetAttributeNotAllowed(attr, msg)) + elseif !_is_additive(model, cp) + msg = "Cannot compute the dual of a multiplicative parameter" + throw(MOI.GetAttributeNotAllowed(attr, msg)) end return model.dual_value_of_parameters[p_val(cp)] end diff --git a/test/test_JuMP.jl b/test/test_JuMP.jl index a44cbb44..8c3591b9 100644 --- a/test/test_JuMP.jl +++ b/test/test_JuMP.jl @@ -553,9 +553,11 @@ function test_jump_dual_multiplicative_fail() @constraint(model, cons, x * p >= 3) @objective(model, Min, 2x) optimize!(model) - @test_throws ErrorException( + err = MOI.GetAttributeNotAllowed( + MOI.ConstraintDual(), "Cannot compute the dual of a multiplicative parameter", - ) MOI.get(model, POI.ParameterDual(), p) + ) + @test_throws err MOI.get(model, POI.ParameterDual(), p) return end diff --git a/test/test_MathOptInterface.jl b/test/test_MathOptInterface.jl index 268e1b5f..b043de7c 100644 --- a/test/test_MathOptInterface.jl +++ b/test/test_MathOptInterface.jl @@ -2450,7 +2450,10 @@ function test_multiplicative_dual_error() p, pc = MOI.add_constrained_variable(model, MOI.Parameter(1.0)) f = 1.0 * x * p ci = MOI.add_constraint(model, f, MOI.EqualTo{Float64}(0.0)) - @test_throws ErrorException MOI.get(model, MOI.ConstraintDual(), pc) + @test_throws( + MOI.GetAttributeNotAllowed, + MOI.get(model, MOI.ConstraintDual(), pc), + ) return end