From 88086e81483da13d5d232b46b09ed552fbc45577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Tue, 19 Dec 2023 12:38:08 +0100 Subject: [PATCH 1/6] Use SlackBridgePrimalDualStart --- Project.toml | 2 +- src/copy_dual.jl | 79 +++--------------------------------------------- 2 files changed, 6 insertions(+), 75 deletions(-) diff --git a/Project.toml b/Project.toml index d73a81b42..b8ec5c553 100644 --- a/Project.toml +++ b/Project.toml @@ -20,6 +20,6 @@ ChainRulesCore = "1" IterativeSolvers = "0.9" JuMP = "1" LazyArrays = "0.21, 0.22, 1" -MathOptInterface = "1.14.1" +MathOptInterface = "1.18" MathOptSetDistances = "0.2.7" julia = "1.6" diff --git a/src/copy_dual.jl b/src/copy_dual.jl index acb203ff4..8f5f2fa25 100644 --- a/src/copy_dual.jl +++ b/src/copy_dual.jl @@ -11,45 +11,6 @@ struct ObjectiveFunctionAttribute{A,F} <: MOI.AbstractModelAttribute attr::A end -""" - struct ObjectiveDualStart <: MOI.AbstractModelAttribute end - -If the objective function had a dual, it would be `-1` for the Lagrangian -function to be the same. -When the `MOI.Bridges.Objective.SlackBridge` is used, it creates a constraint. -The dual of this constraint is therefore `-1` as well. -When setting this attribute, it allows to set the constraint dual of this -constraint. -""" -struct ObjectiveDualStart <: MOI.AbstractModelAttribute end -# Defining it for `MOI.set` leads to ambiguity -function MOI.throw_set_error_fallback( - ::MOI.ModelLike, - ::ObjectiveDualStart, - value, -) - return nothing -end - -""" - struct ObjectiveSlackGapPrimalStart <: MOI.AbstractModelAttribute end - -If the objective function had a dual, it would be `-1` for the Lagrangian -function to be the same. -When the `MOI.Bridges.Objective.SlackBridge` is used, it creates a constraint. -The dual of this constraint is therefore `-1` as well. -When setting this attribute, it allows to set the constraint dual of this -constraint. -""" -struct ObjectiveSlackGapPrimalStart <: MOI.AbstractModelAttribute end -function MOI.throw_set_error_fallback( - ::MOI.ModelLike, - ::ObjectiveSlackGapPrimalStart, - value, -) - return nothing -end - function MOI.get( b::MOI.Bridges.AbstractBridgeOptimizer, attr::ObjectiveFunctionAttribute{A,F}, @@ -100,11 +61,7 @@ end function MOI.set( b::MOI.Bridges.AbstractBridgeOptimizer, - attr::Union{ - ObjectiveDualStart, - ObjectiveSlackGapPrimalStart, - ForwardObjectiveFunction, - }, + attr::ForwardObjectiveFunction, value, ) if MOI.Bridges.is_objective_bridged(b) @@ -121,34 +78,6 @@ function MOI.set( end end -function MOI.set( - model::MOI.ModelLike, - ::ObjectiveFunctionAttribute{ObjectiveDualStart}, - b::MOI.Bridges.Objective.SlackBridge, - value, -) - return MOI.set(model, MOI.ConstraintDualStart(), b.constraint, value) -end - -function MOI.set( - model::MOI.ModelLike, - ::ObjectiveFunctionAttribute{ObjectiveSlackGapPrimalStart}, - b::MOI.Bridges.Objective.SlackBridge{T}, - value, -) where {T} - # `f(x) - slack = value` so `slack = f(x) - value` - fun = MOI.get(model, MOI.ConstraintFunction(), b.constraint) - set = MOI.get(model, MOI.ConstraintSet(), b.constraint) - MOI.Utilities.operate!(-, T, fun, MOI.constant(set)) - # `fun = f - slack` so we remove the term `-slack` to get `f` - f = MOI.Utilities.remove_variable(fun, b.slack) - f_val = MOI.Utilities.eval_variables(f) do v - return MOI.get(model, MOI.VariablePrimalStart(), v) - end - MOI.set(model, MOI.VariablePrimalStart(), b.slack, f_val - value) - return MOI.set(model, MOI.ConstraintPrimalStart(), b.constraint, value) -end - function _copy_dual(dest::MOI.ModelLike, src::MOI.ModelLike, index_map) vis_src = MOI.get(src, MOI.ListOfVariableIndices()) MOI.set( @@ -173,8 +102,10 @@ function _copy_dual(dest::MOI.ModelLike, src::MOI.ModelLike, index_map) MOI.ConstraintDual(), ) end - MOI.set(dest, ObjectiveDualStart(), -1.0) - return MOI.set(dest, ObjectiveSlackGapPrimalStart(), 0.0) + # Same as in `JuMP.set_start_values` + # Needed for models which bridge `min f(x)` into `min t; t >= f(x)`. + MOI.set(dest, MOI.Bridges.Objective.SlackBridgePrimalDualStart(), nothing) + return end function _copy_constraint_start( From f721cf0296cc5323729de3c72c199b75a3b2a6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Tue, 7 Jan 2025 20:53:39 +0100 Subject: [PATCH 2/6] Update src/copy_dual.jl --- src/copy_dual.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/copy_dual.jl b/src/copy_dual.jl index 8f5f2fa25..a7c24d23b 100644 --- a/src/copy_dual.jl +++ b/src/copy_dual.jl @@ -103,7 +103,7 @@ function _copy_dual(dest::MOI.ModelLike, src::MOI.ModelLike, index_map) ) end # Same as in `JuMP.set_start_values` - # Needed for models which bridge `min f(x)` into `min t; t >= f(x)`. + # Needed for models which bridge `min f(x)` into `min t such that t >= f(x)`. MOI.set(dest, MOI.Bridges.Objective.SlackBridgePrimalDualStart(), nothing) return end From 0cb1a4b992f0adb1005656191622d2f5944d8dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 8 Jan 2025 17:47:31 +0100 Subject: [PATCH 3/6] Remove test_broken --- test/jump.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jump.jl b/test/jump.jl index cacb27aed..8055f1f10 100644 --- a/test/jump.jl +++ b/test/jump.jl @@ -465,7 +465,7 @@ function test_differentiating_simple_socp() db = zeros(5) dc = zeros(3) MOI.set.(model, DiffOpt.ReverseVariablePrimal(), vv, 1.0) - @test_broken DiffOpt.reverse_differentiate!(model) + DiffOpt.reverse_differentiate!(model) # TODO add tests return end From cede80ac27fc9945d73d2419ccc7268e5253854a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 8 Jan 2025 19:55:13 +0100 Subject: [PATCH 4/6] Add supports --- src/ConicProgram/ConicProgram.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/ConicProgram/ConicProgram.jl b/src/ConicProgram/ConicProgram.jl index 69df7e096..37b4bcd56 100644 --- a/src/ConicProgram/ConicProgram.jl +++ b/src/ConicProgram/ConicProgram.jl @@ -155,6 +155,22 @@ function MOI.set( ) end +function MOI.supports( + ::Model, + ::Union{MOI.VariablePrimalStart}, + ::Type{<:MOI.VariableIndex}, +) + return true +end + +function MOI.supports( + ::Model, + ::Union{MOI.ConstraintDualStart,MOI.ConstraintPrimalStart}, + ::Type{<:MOI.ConstraintIndex}, +) + return true +end + function MOI.set( model::Model, ::MOI.ConstraintDualStart, From 6a7831f3c56d8de54833d7a981c8e747c01c6c99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 8 Jan 2025 19:57:35 +0100 Subject: [PATCH 5/6] Add comment --- src/ConicProgram/ConicProgram.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ConicProgram/ConicProgram.jl b/src/ConicProgram/ConicProgram.jl index 37b4bcd56..f5cdd0b84 100644 --- a/src/ConicProgram/ConicProgram.jl +++ b/src/ConicProgram/ConicProgram.jl @@ -155,6 +155,9 @@ function MOI.set( ) end +# The following `supports` methods are needed because +# `MOI.set(::MOI.ModelLike, ::SlackBridgePrimalDualStart, ::SlackBridge, ::Nothing)` +# checks that the model supports these starting value attributes. function MOI.supports( ::Model, ::Union{MOI.VariablePrimalStart}, From 027c99ed57de3c19aa5d76149a29b32f67a6e125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 8 Jan 2025 20:08:31 +0100 Subject: [PATCH 6/6] Move to AbstractModel --- src/ConicProgram/ConicProgram.jl | 19 ------------------- src/diff_opt.jl | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/ConicProgram/ConicProgram.jl b/src/ConicProgram/ConicProgram.jl index f5cdd0b84..69df7e096 100644 --- a/src/ConicProgram/ConicProgram.jl +++ b/src/ConicProgram/ConicProgram.jl @@ -155,25 +155,6 @@ function MOI.set( ) end -# The following `supports` methods are needed because -# `MOI.set(::MOI.ModelLike, ::SlackBridgePrimalDualStart, ::SlackBridge, ::Nothing)` -# checks that the model supports these starting value attributes. -function MOI.supports( - ::Model, - ::Union{MOI.VariablePrimalStart}, - ::Type{<:MOI.VariableIndex}, -) - return true -end - -function MOI.supports( - ::Model, - ::Union{MOI.ConstraintDualStart,MOI.ConstraintPrimalStart}, - ::Type{<:MOI.ConstraintIndex}, -) - return true -end - function MOI.set( model::Model, ::MOI.ConstraintDualStart, diff --git a/src/diff_opt.jl b/src/diff_opt.jl index 77ba7d968..22781eec3 100644 --- a/src/diff_opt.jl +++ b/src/diff_opt.jl @@ -257,6 +257,25 @@ function _enlarge_set(vec::Vector, idx, value) return end +# The following `supports` methods are needed because +# `MOI.set(::MOI.ModelLike, ::SlackBridgePrimalDualStart, ::SlackBridge, ::Nothing)` +# checks that the model supports these starting value attributes. +function MOI.supports( + ::AbstractModel, + ::MOI.VariablePrimalStart, + ::Type{<:MOI.VariableIndex}, +) + return true +end + +function MOI.supports( + ::AbstractModel, + ::Union{MOI.ConstraintDualStart,MOI.ConstraintPrimalStart}, + ::Type{<:MOI.ConstraintIndex}, +) + return true +end + function MOI.get( model::AbstractModel, ::MOI.VariablePrimalStart,