From 7efd32439f1e47ca3f67ea1cadf85ace82b23025 Mon Sep 17 00:00:00 2001 From: "Klamkin, Michael" Date: Wed, 11 Jun 2025 14:03:51 -0400 Subject: [PATCH 1/7] add parameter set for MOI parameters --- src/constrained_variables.jl | 5 +++-- src/dual_model_variables.jl | 13 ++++++++++++- src/dualize.jl | 5 +++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/constrained_variables.jl b/src/constrained_variables.jl index 681a250..2f62741 100644 --- a/src/constrained_variables.jl +++ b/src/constrained_variables.jl @@ -89,10 +89,11 @@ function _get_parameter_variables(::PrimalDualMap{T}, primal_model) where {T} primal_model, MOI.ListOfConstraintIndices{MOI.VariableIndex,MOI.Parameter{T}}(), ) - parameters = Set{MOI.VariableIndex}() + parameters = Dict{MOI.VariableIndex,T}() for ci in cis vi = MOI.get(primal_model, MOI.ConstraintFunction(), ci) - push!(parameters, vi) + val = MOI.constant(MOI.get(primal_model, MOI.ConstraintSet(), ci)) + parameters[vi] = val end return parameters end diff --git a/src/dual_model_variables.jl b/src/dual_model_variables.jl index 980fb65..9eb96fb 100644 --- a/src/dual_model_variables.jl +++ b/src/dual_model_variables.jl @@ -114,6 +114,7 @@ function _add_primal_parameter_vars( primal_model::MOI.ModelLike, primal_dual_map::PrimalDualMap{T}, dual_names::DualNames, + moi_parameter_values::Dict{MOI.VariableIndex,T}, variable_parameters::Vector{MOI.VariableIndex}, primal_objective, ignore_objective::Bool, @@ -134,9 +135,19 @@ function _add_primal_parameter_vars( variable_parameters end vis = MOI.add_variables(dual_model, length(parameters)) + + moi_parameters = keys(moi_parameter_values) for i in eachindex(vis) + vi = vis[i] + if vi in moi_parameters + # TODO: use add_constrained_variables instead? + # TODO: store the ci somewhere? + MOI.add_constraint( + dual_model, vi, MOI.Parameter{T}(moi_parameter_values[vi]) + ) + end primal_dual_map.primal_parameter_to_dual_parameter[parameters[i]] = - vis[i] + vi if !is_empty(dual_names) vi_name = MOI.get(primal_model, MOI.VariableName(), parameters[i]) prefix = diff --git a/src/dualize.jl b/src/dualize.jl index f14a5db..a5ecda9 100644 --- a/src/dualize.jl +++ b/src/dualize.jl @@ -87,10 +87,10 @@ function dualize( supported_constraints(con_types) # Errors if constraint cant be dualized # merge user listed parameters and MOI.VariableIndex-in-MOI.Parameter{T} - moi_parameters = + moi_parameter_values = _get_parameter_variables(dual_problem.primal_dual_map, primal_model) all_parameters = Set{MOI.VariableIndex}(_variable_parameters) - for p in moi_parameters + for p in keys(moi_parameter_values) push!(all_parameters, p) end variable_parameters = collect(all_parameters) @@ -165,6 +165,7 @@ function dualize( primal_model, dual_problem.primal_dual_map, dual_names, + moi_parameter_values, variable_parameters, primal_objective, ignore_objective, From 9031561b54e6a038997de194341d5f7167873413 Mon Sep 17 00:00:00 2001 From: "Klamkin, Michael" Date: Wed, 18 Jun 2025 12:16:08 -0400 Subject: [PATCH 2/7] tests --- test/Tests/test_partial_dual_quadratic.jl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/Tests/test_partial_dual_quadratic.jl b/test/Tests/test_partial_dual_quadratic.jl index a064570..14af7ac 100644 --- a/test/Tests/test_partial_dual_quadratic.jl +++ b/test/Tests/test_partial_dual_quadratic.jl @@ -180,6 +180,7 @@ @test Set(list_of_cons) == Set( [ (MOI.VariableIndex, MOI.GreaterThan{Float64}) + (MOI.VariableIndex, MOI.Parameter{Float64}) (MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}) ], ) @@ -288,6 +289,18 @@ @test primal_parameter_to_dual_parameter[MOI.VariableIndex(3)] == MOI.VariableIndex(2 + 1) + @test MOI.get( + dual_model, + MOI.ConstraintSet(), + MOI.ConstraintIndex{MOI.VariableIndex,MOI.Parameter{Float64}}( + primal_parameter_to_dual_parameter[MOI.VariableIndex(3)].value, + ), + ) == MOI.get( + primal_model, + MOI.ConstraintSet(), + MOI.ConstraintIndex{MOI.VariableIndex,MOI.Parameter{Float64}}(3), + ) + primal_var_in_quad_obj_to_dual_slack_var = primal_dual_map.primal_var_in_quad_obj_to_dual_slack_var @test primal_var_in_quad_obj_to_dual_slack_var[MOI.VariableIndex(1)] == From de73becb845b78ed106fffa0bcdf1504705af4db Mon Sep 17 00:00:00 2001 From: "Klamkin, Michael" Date: Wed, 18 Jun 2025 12:21:13 -0400 Subject: [PATCH 3/7] format --- src/dual_model_variables.jl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/dual_model_variables.jl b/src/dual_model_variables.jl index 9eb96fb..06da2dd 100644 --- a/src/dual_model_variables.jl +++ b/src/dual_model_variables.jl @@ -140,14 +140,13 @@ function _add_primal_parameter_vars( for i in eachindex(vis) vi = vis[i] if vi in moi_parameters - # TODO: use add_constrained_variables instead? - # TODO: store the ci somewhere? MOI.add_constraint( - dual_model, vi, MOI.Parameter{T}(moi_parameter_values[vi]) + dual_model, + vi, + MOI.Parameter{T}(moi_parameter_values[vi]), ) end - primal_dual_map.primal_parameter_to_dual_parameter[parameters[i]] = - vi + primal_dual_map.primal_parameter_to_dual_parameter[parameters[i]] = vi if !is_empty(dual_names) vi_name = MOI.get(primal_model, MOI.VariableName(), parameters[i]) prefix = From 656726a3f48d41708febb51b9792296453f00f8f Mon Sep 17 00:00:00 2001 From: "Klamkin, Michael" Date: Wed, 18 Jun 2025 12:27:27 -0400 Subject: [PATCH 4/7] pass sets instead of values --- src/constrained_variables.jl | 6 +++--- src/dual_model_variables.jl | 6 +++--- src/dualize.jl | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/constrained_variables.jl b/src/constrained_variables.jl index 2f62741..89c1f31 100644 --- a/src/constrained_variables.jl +++ b/src/constrained_variables.jl @@ -89,11 +89,11 @@ function _get_parameter_variables(::PrimalDualMap{T}, primal_model) where {T} primal_model, MOI.ListOfConstraintIndices{MOI.VariableIndex,MOI.Parameter{T}}(), ) - parameters = Dict{MOI.VariableIndex,T}() + parameters = Dict{MOI.VariableIndex,MOI.Parameter{T}}() for ci in cis vi = MOI.get(primal_model, MOI.ConstraintFunction(), ci) - val = MOI.constant(MOI.get(primal_model, MOI.ConstraintSet(), ci)) - parameters[vi] = val + set = MOI.get(primal_model, MOI.ConstraintSet(), ci) + parameters[vi] = set end return parameters end diff --git a/src/dual_model_variables.jl b/src/dual_model_variables.jl index 06da2dd..bb80d78 100644 --- a/src/dual_model_variables.jl +++ b/src/dual_model_variables.jl @@ -114,7 +114,7 @@ function _add_primal_parameter_vars( primal_model::MOI.ModelLike, primal_dual_map::PrimalDualMap{T}, dual_names::DualNames, - moi_parameter_values::Dict{MOI.VariableIndex,T}, + moi_parameter_sets::Dict{MOI.VariableIndex,MOI.Parameter{T}}, variable_parameters::Vector{MOI.VariableIndex}, primal_objective, ignore_objective::Bool, @@ -136,14 +136,14 @@ function _add_primal_parameter_vars( end vis = MOI.add_variables(dual_model, length(parameters)) - moi_parameters = keys(moi_parameter_values) + moi_parameters = keys(moi_parameter_sets) for i in eachindex(vis) vi = vis[i] if vi in moi_parameters MOI.add_constraint( dual_model, vi, - MOI.Parameter{T}(moi_parameter_values[vi]), + moi_parameter_sets[vi], ) end primal_dual_map.primal_parameter_to_dual_parameter[parameters[i]] = vi diff --git a/src/dualize.jl b/src/dualize.jl index a5ecda9..d3dcdad 100644 --- a/src/dualize.jl +++ b/src/dualize.jl @@ -87,10 +87,10 @@ function dualize( supported_constraints(con_types) # Errors if constraint cant be dualized # merge user listed parameters and MOI.VariableIndex-in-MOI.Parameter{T} - moi_parameter_values = + moi_parameter_sets = _get_parameter_variables(dual_problem.primal_dual_map, primal_model) all_parameters = Set{MOI.VariableIndex}(_variable_parameters) - for p in keys(moi_parameter_values) + for p in keys(moi_parameter_sets) push!(all_parameters, p) end variable_parameters = collect(all_parameters) @@ -165,7 +165,7 @@ function dualize( primal_model, dual_problem.primal_dual_map, dual_names, - moi_parameter_values, + moi_parameter_sets, variable_parameters, primal_objective, ignore_objective, From 8707d9b4965df195a1cdef640d595a39bf295aec Mon Sep 17 00:00:00 2001 From: "Klamkin, Michael" Date: Wed, 18 Jun 2025 12:29:07 -0400 Subject: [PATCH 5/7] format --- src/dual_model_variables.jl | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/dual_model_variables.jl b/src/dual_model_variables.jl index bb80d78..731d551 100644 --- a/src/dual_model_variables.jl +++ b/src/dual_model_variables.jl @@ -140,11 +140,7 @@ function _add_primal_parameter_vars( for i in eachindex(vis) vi = vis[i] if vi in moi_parameters - MOI.add_constraint( - dual_model, - vi, - moi_parameter_sets[vi], - ) + MOI.add_constraint(dual_model, vi, moi_parameter_sets[vi]) end primal_dual_map.primal_parameter_to_dual_parameter[parameters[i]] = vi if !is_empty(dual_names) From 378eb6f9c828eb5ce6aa1e556de3fef76d6196ca Mon Sep 17 00:00:00 2001 From: "Klamkin, Michael" Date: Wed, 18 Jun 2025 12:38:50 -0400 Subject: [PATCH 6/7] primal vi as key --- src/dual_model_variables.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dual_model_variables.jl b/src/dual_model_variables.jl index 731d551..5a53efd 100644 --- a/src/dual_model_variables.jl +++ b/src/dual_model_variables.jl @@ -140,7 +140,11 @@ function _add_primal_parameter_vars( for i in eachindex(vis) vi = vis[i] if vi in moi_parameters - MOI.add_constraint(dual_model, vi, moi_parameter_sets[vi]) + MOI.add_constraint( + dual_model, + vi, + moi_parameter_sets[parameters[i]], + ) end primal_dual_map.primal_parameter_to_dual_parameter[parameters[i]] = vi if !is_empty(dual_names) From 530d47aff52649195fcd9040c63f7156302f73b1 Mon Sep 17 00:00:00 2001 From: "Klamkin, Michael" Date: Wed, 18 Jun 2025 12:40:22 -0400 Subject: [PATCH 7/7] make primal/dual vi clearer --- src/dual_model_variables.jl | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/dual_model_variables.jl b/src/dual_model_variables.jl index 5a53efd..73280be 100644 --- a/src/dual_model_variables.jl +++ b/src/dual_model_variables.jl @@ -138,21 +138,19 @@ function _add_primal_parameter_vars( moi_parameters = keys(moi_parameter_sets) for i in eachindex(vis) - vi = vis[i] - if vi in moi_parameters - MOI.add_constraint( - dual_model, - vi, - moi_parameter_sets[parameters[i]], - ) + pvi = parameters[i] + dvi = vis[i] + + if pvi in moi_parameters + MOI.add_constraint(dual_model, dvi, moi_parameter_sets[pvi]) end - primal_dual_map.primal_parameter_to_dual_parameter[parameters[i]] = vi + primal_dual_map.primal_parameter_to_dual_parameter[pvi] = dvi if !is_empty(dual_names) - vi_name = MOI.get(primal_model, MOI.VariableName(), parameters[i]) + pvi_name = MOI.get(primal_model, MOI.VariableName(), pvi) prefix = dual_names.parameter_name_prefix == "" ? "param_" : dual_names.parameter_name_prefix - MOI.set(dual_model, MOI.VariableName(), vis[i], prefix * vi_name) + MOI.set(dual_model, MOI.VariableName(), dvi, prefix * pvi_name) end end return