From 882e1f95bf5da5aa954ad1ab357e6bba3688e4e0 Mon Sep 17 00:00:00 2001 From: joaquimg Date: Sat, 12 Apr 2025 00:56:21 -0700 Subject: [PATCH 1/6] Better names --- src/constrained_variables.jl | 4 +++ src/structures.jl | 60 ++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/constrained_variables.jl b/src/constrained_variables.jl index 7b9dfdca..1f79c632 100644 --- a/src/constrained_variables.jl +++ b/src/constrained_variables.jl @@ -50,6 +50,8 @@ function _add_constrained_variables( for ci in cis f = MOI.get(primal_model, MOI.ConstraintFunction(), ci) if all( + # no element of the VectorOfVariables is a constrained variable + # and not a parameter vi -> !haskey(m.constrained_var_idx, vi) && !(vi in params), f.variables, ) @@ -76,6 +78,8 @@ function _add_constrained_variable( ) for ci in cis f = MOI.get(primal_model, MOI.ConstraintFunction(), ci) + # no element of the VectorOfVariables is a constrained variable + # and not a parameter if !haskey(m.constrained_var_idx, f) && !(f in params) set = MOI.get(primal_model, MOI.ConstraintSet(), ci) if !iszero(MOI.constant(set)) diff --git a/src/structures.jl b/src/structures.jl index 4f458f22..80697488 100644 --- a/src/structures.jl +++ b/src/structures.jl @@ -30,50 +30,76 @@ MOI.Utilities.@model( Maps information from all structures of the primal to the dual model. +Main user maps: + * `constrained_var_idx::Dict{MOI.VariableIndex,Tuple{MOI.ConstraintIndex,Int}}`: - maps original primal constrained variables to their primal original + maps primal constrained variables to their primal constraints (the special ones that makes them constrained variables) and - their internal index (if vector constraints, VectorOfVariables-in-Set), 1 - otherwise (VariableIndex-in-Set). + their internal index from 1 to dimension(set) (if vector constraints: + VectorOfVariables-in-Set), 1 otherwise (scalar: VariableIndex-in-Set). + # primal_convar_to_primal_convarcon_and_index * `constrained_var_dual::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}`: maps - the original primal constraint index of constrained variables to the dual - model's constraint index of the associated dual constraint. + the primal constraint index of constrained variables to the dual + model's constraint index of the associated dual constraint. This dual + constraint is a regular constraint (not a constrained variable constraint). + `VectorOfVariables`-in-`Zeros` and `VariableIndex`-in-`EqualTo(zero(T))` + are not in this map, as they are not dualized (See + # primal_convarcon_to_dual_function). + # primal_convarcon_to_dual_con - * `constrained_var_zero::Dict{MOI.ConstraintIndex,Unions{MOI.ScalarAffineFunction,MOI.VectorAffineFunction}}`: - caches scalar affine functions or vector affine functions associated with - constrained variables of type `VectorOfVariables`-in-`Zeros` or - `VariableIndex`-in-`EqualTo(zero(T))` as their duals would be `func`-in-`Reals`, - which are "irrelevant" to the model. This information is cached for - completeness of the `DualOptimizer` for `get`ting `ConstraintDuals`. + note: from the above two maps, we can get primal_convar_to_dual_con_and_index * `primal_var_dual_con::Dict{MOI.VariableIndex,MOI.ConstraintIndex}`: maps - "free" primal variables to their associated dual constraints. Free variables - as opposed to constrained variables. Note that Dualization will select - automatically which variables are free and which are constrained. + "free" primal variables to their associated dual (equality) constraints. + Free variables as opposed to constrained variables. Note that Dualization + will select automatically which variables are free and which are + constrained. + # primal_var_to_dual_con + + note: from the above three maps, we can get primal_var_to_dual_con_and_index * `primal_con_dual_var::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}`: maps primal constraint indices to vectors of dual variable indices. For scalar constraints those vectors will be single element vectors. + Primal Constrained variables constraints (the main ones) are not in this + map. + # primal_con_to_dual_var_vec * `primal_con_dual_con::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}`: maps - primal constraints to dual variable constraints (if there is such constraint - the dual dual variable is said to be constrained). If the primal + primal constraints to dual constrained variable. If the primal constraint's set is EqualTo or Zeros, no constraint is added in the dual variable (the dual variable is said to be free). + The keys are similar to the (# primal_con_to_dual_var_vec) map, except + that `VariableIndex`-in-`EqualTo(zero(T))` and `VectorOfVariables`-in-`Zeros` + are not in this map. + # primal_con_to_dual_convarcon + + Additional helper maps: * `primal_con_constants::Dict{MOI.ConstraintIndex,Vector{T}}`: maps primal constraints to their respective constants, which might be inside the set. This map is used in `MOI.get(::DualOptimizer,::MOI.ConstraintPrimal,ci)` that requires extra information in the case that the scalar set constrains a constant (`EqualtTo`, `GreaterThan`, `LessThan`). + # primal_con_to_primal_constants_vec * `primal_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex}`: maps parameters in the primal to parameters in the dual model. + # primal_parameter_to_dual_parameter + + * `constrained_var_zero::Dict{MOI.ConstraintIndex,Unions{MOI.ScalarAffineFunction,MOI.VectorAffineFunction}}`: + caches scalar affine functions or vector affine functions associated with + constrained variables of type `VectorOfVariables`-in-`Zeros` or + `VariableIndex`-in-`EqualTo(zero(T))` as their duals would be `func`-in-`Reals`, + which are "irrelevant" to the model. This information is cached for + completeness of the `DualOptimizer` for `get`ting `ConstraintDuals`. + # primal_convarcon_to_dual_function * `primal_var_dual_quad_slack::Dict{MOI.VariableIndex,MOI.VariableIndex}`: maps primal variables (that appear in quadratic objective terms) to dual - "slack" variables. + "slack" variables. These primal variables might appear in other maps. + # primal_var_in_quad_obj_to_dual_slack_var """ mutable struct PrimalDualMap{T} constrained_var_idx::Dict{MOI.VariableIndex,Tuple{MOI.ConstraintIndex,Int}} From 114fe2df2b14d7f8a4ae9e1cfd9d0ad8f7e5369e Mon Sep 17 00:00:00 2001 From: joaquimg Date: Sat, 12 Apr 2025 22:23:51 -0700 Subject: [PATCH 2/6] rm hashtags --- src/structures.jl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/structures.jl b/src/structures.jl index 80697488..029198d3 100644 --- a/src/structures.jl +++ b/src/structures.jl @@ -37,7 +37,7 @@ Main user maps: constraints (the special ones that makes them constrained variables) and their internal index from 1 to dimension(set) (if vector constraints: VectorOfVariables-in-Set), 1 otherwise (scalar: VariableIndex-in-Set). - # primal_convar_to_primal_convarcon_and_index + Future name: primal_convar_to_primal_convarcon_and_index * `constrained_var_dual::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}`: maps the primal constraint index of constrained variables to the dual @@ -45,8 +45,8 @@ Main user maps: constraint is a regular constraint (not a constrained variable constraint). `VectorOfVariables`-in-`Zeros` and `VariableIndex`-in-`EqualTo(zero(T))` are not in this map, as they are not dualized (See - # primal_convarcon_to_dual_function). - # primal_convarcon_to_dual_con + primal_convarcon_to_dual_function). + Future name: primal_convarcon_to_dual_con note: from the above two maps, we can get primal_convar_to_dual_con_and_index @@ -55,7 +55,7 @@ Main user maps: Free variables as opposed to constrained variables. Note that Dualization will select automatically which variables are free and which are constrained. - # primal_var_to_dual_con + Future name: primal_var_to_dual_con note: from the above three maps, we can get primal_var_to_dual_con_and_index @@ -64,7 +64,7 @@ Main user maps: scalar constraints those vectors will be single element vectors. Primal Constrained variables constraints (the main ones) are not in this map. - # primal_con_to_dual_var_vec + Future name: primal_con_to_dual_var_vec * `primal_con_dual_con::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}`: maps primal constraints to dual constrained variable. If the primal @@ -73,7 +73,7 @@ Main user maps: The keys are similar to the (# primal_con_to_dual_var_vec) map, except that `VariableIndex`-in-`EqualTo(zero(T))` and `VectorOfVariables`-in-`Zeros` are not in this map. - # primal_con_to_dual_convarcon + Future name: primal_con_to_dual_convarcon Additional helper maps: @@ -82,11 +82,11 @@ Main user maps: This map is used in `MOI.get(::DualOptimizer,::MOI.ConstraintPrimal,ci)` that requires extra information in the case that the scalar set constrains a constant (`EqualtTo`, `GreaterThan`, `LessThan`). - # primal_con_to_primal_constants_vec + Future name: primal_con_to_primal_constants_vec * `primal_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex}`: maps parameters in the primal to parameters in the dual model. - # primal_parameter_to_dual_parameter + Future name: primal_parameter_to_dual_parameter * `constrained_var_zero::Dict{MOI.ConstraintIndex,Unions{MOI.ScalarAffineFunction,MOI.VectorAffineFunction}}`: caches scalar affine functions or vector affine functions associated with @@ -94,12 +94,12 @@ Main user maps: `VariableIndex`-in-`EqualTo(zero(T))` as their duals would be `func`-in-`Reals`, which are "irrelevant" to the model. This information is cached for completeness of the `DualOptimizer` for `get`ting `ConstraintDuals`. - # primal_convarcon_to_dual_function + Future name: primal_convarcon_to_dual_function * `primal_var_dual_quad_slack::Dict{MOI.VariableIndex,MOI.VariableIndex}`: maps primal variables (that appear in quadratic objective terms) to dual "slack" variables. These primal variables might appear in other maps. - # primal_var_in_quad_obj_to_dual_slack_var + Future name: primal_var_in_quad_obj_to_dual_slack_var """ mutable struct PrimalDualMap{T} constrained_var_idx::Dict{MOI.VariableIndex,Tuple{MOI.ConstraintIndex,Int}} From 80b27b3486cb432f7c9849522a11d47149f473e1 Mon Sep 17 00:00:00 2001 From: joaquimg Date: Mon, 14 Apr 2025 17:38:01 -0700 Subject: [PATCH 3/6] apply rename --- src/MOI_wrapper.jl | 50 ++++---- src/constrained_variables.jl | 12 +- src/dual_equality_constraints.jl | 52 ++++---- src/dual_model_variables.jl | 58 ++++----- src/dualize.jl | 14 +-- src/objective_coefficients.jl | 12 +- src/structures.jl | 144 ++++++++++++++-------- test/Tests/test_dual_names.jl | 16 +-- test/Tests/test_dualize_conic_linear.jl | 38 +++--- test/Tests/test_dualize_exponential.jl | 16 +-- test/Tests/test_dualize_power.jl | 14 +-- test/Tests/test_dualize_quadratic.jl | 22 ++-- test/Tests/test_dualize_rsoc.jl | 10 +- test/Tests/test_dualize_sdp.jl | 14 +-- test/Tests/test_dualize_soc.jl | 14 +-- test/Tests/test_partial_dual_linear.jl | 30 ++--- test/Tests/test_partial_dual_quadratic.jl | 60 ++++----- test/Tests/test_structures.jl | 2 +- test/optimize_abstract_models.jl | 2 +- 19 files changed, 312 insertions(+), 268 deletions(-) diff --git a/src/MOI_wrapper.jl b/src/MOI_wrapper.jl index 2d1d8135..0586158c 100644 --- a/src/MOI_wrapper.jl +++ b/src/MOI_wrapper.jl @@ -159,15 +159,15 @@ function MOI.modify( constant = -constant end vi = obj_change.variable - if vi in keys(primal_dual_map.constrained_var_idx) - ci_primal, index = primal_dual_map.constrained_var_idx[vi] - ci_dual = primal_dual_map.constrained_var_dual[ci_primal] + if vi in keys(primal_dual_map.primal_convar_to_primal_convarcon_and_index) + ci_primal, index = primal_dual_map.primal_convar_to_primal_convarcon_and_index[vi] + ci_dual = primal_dual_map.primal_convarcon_to_dual_con[ci_primal] if ci_dual === NO_CONSTRAINT return end constant = -constant else - ci_dual = primal_dual_map.primal_var_dual_con[vi] + ci_dual = primal_dual_map.primal_var_to_dual_con[vi] index = 1 end _change_constant( @@ -237,11 +237,11 @@ end # MOI.get auxiliary functions function get_ci_dual_problem(optimizer::DualOptimizer, vi::MOI.VariableIndex) - return optimizer.dual_problem.primal_dual_map.primal_var_dual_con[vi] + return optimizer.dual_problem.primal_dual_map.primal_var_to_dual_con[vi] end function get_ci_dual_problem(optimizer::DualOptimizer, ci::MOI.ConstraintIndex) - return optimizer.dual_problem.primal_dual_map.primal_con_dual_con[ci] + return optimizer.dual_problem.primal_dual_map.primal_con_to_dual_convarcon[ci] end function get_primal_ci_constant( @@ -255,7 +255,7 @@ function get_primal_ci_constants( optimizer::DualOptimizer, ci::MOI.ConstraintIndex, ) - return optimizer.dual_problem.primal_dual_map.primal_con_constants[ci] + return optimizer.dual_problem.primal_dual_map.primal_con_to_primal_constants_vec[ci] end function get_vi_dual_problem(optimizer::DualOptimizer, ci::MOI.ConstraintIndex) @@ -263,7 +263,7 @@ function get_vi_dual_problem(optimizer::DualOptimizer, ci::MOI.ConstraintIndex) end function get_vis_dual_problem(optimizer::DualOptimizer, ci::MOI.ConstraintIndex) - return optimizer.dual_problem.primal_dual_map.primal_con_dual_var[ci] + return optimizer.dual_problem.primal_dual_map.primal_con_to_dual_var_vec[ci] end function MOI.get(optimizer::DualOptimizer, ::MOI.SolverName) @@ -296,7 +296,7 @@ function _get( ::MOI.ConstraintIndex{Nothing,Nothing}, ) where {T} n = MOI.output_dimension( - optimizer.dual_problem.primal_dual_map.constrained_var_zero[ci_primal], + optimizer.dual_problem.primal_dual_map.primal_convarcon_to_dual_function[ci_primal], ) return zeros(T, n) end @@ -328,9 +328,9 @@ function MOI.get( vi::MOI.VariableIndex, ) primal_dual_map = optimizer.dual_problem.primal_dual_map - if vi in keys(primal_dual_map.constrained_var_idx) - ci_primal, idx = primal_dual_map.constrained_var_idx[vi] - ci_dual = primal_dual_map.constrained_var_dual[ci_primal] + if vi in keys(primal_dual_map.primal_convar_to_primal_convarcon_and_index) + ci_primal, idx = primal_dual_map.primal_convar_to_primal_convarcon_and_index[vi] + ci_dual = primal_dual_map.primal_convarcon_to_dual_con[ci_primal] return _get_at_index( optimizer, MOI.ConstraintDual(), @@ -353,11 +353,11 @@ function MOI.get( ci::MOI.ConstraintIndex{F,S}, ) where {F<:MOI.AbstractScalarFunction,S<:MOI.AbstractScalarSet} primal_dual_map = optimizer.dual_problem.primal_dual_map - if ci in keys(primal_dual_map.constrained_var_dual) - ci_dual = primal_dual_map.constrained_var_dual[ci] + if ci in keys(primal_dual_map.primal_convarcon_to_dual_con) + ci_dual = primal_dual_map.primal_convarcon_to_dual_con[ci] if ci_dual === NO_CONSTRAINT return MOI.Utilities.eval_variables( - primal_dual_map.constrained_var_zero[ci], + primal_dual_map.primal_convarcon_to_dual_function[ci], ) do vi return MOI.get( optimizer.dual_problem.dual_model, @@ -391,11 +391,11 @@ function MOI.get( ci::MOI.ConstraintIndex{F,S}, ) where {F<:MOI.AbstractVectorFunction,S<:MOI.AbstractVectorSet} primal_dual_map = optimizer.dual_problem.primal_dual_map - if ci in keys(primal_dual_map.constrained_var_dual) - ci_dual = primal_dual_map.constrained_var_dual[ci] + if ci in keys(primal_dual_map.primal_convarcon_to_dual_con) + ci_dual = primal_dual_map.primal_convarcon_to_dual_con[ci] if ci_dual === NO_CONSTRAINT return MOI.Utilities.eval_variables( - primal_dual_map.constrained_var_zero[ci], + primal_dual_map.primal_convarcon_to_dual_function[ci], ) do vi return MOI.get( optimizer.dual_problem.dual_model, @@ -407,7 +407,7 @@ function MOI.get( return MOI.get( optimizer.dual_problem.dual_model, MOI.ConstraintPrimal(), - primal_dual_map.constrained_var_dual[ci], + primal_dual_map.primal_convarcon_to_dual_con[ci], ) else return MOI.get.( @@ -424,17 +424,17 @@ function MOI.get( ci::MOI.ConstraintIndex{F,S}, ) where {F<:MOI.AbstractScalarFunction,S<:MOI.AbstractScalarSet} primal_dual_map = optimizer.dual_problem.primal_dual_map - if ci in keys(primal_dual_map.constrained_var_dual) + if ci in keys(primal_dual_map.primal_convarcon_to_dual_con) return _get( optimizer, MOI.ConstraintDual(), ci, - primal_dual_map.constrained_var_dual[ci], + primal_dual_map.primal_convarcon_to_dual_con[ci], ) else primal_ci_constant = get_primal_ci_constant(optimizer, ci) # If it has no key then there is no dual constraint - if !haskey(primal_dual_map.primal_con_dual_con, ci) + if !haskey(primal_dual_map.primal_con_to_dual_convarcon, ci) return -primal_ci_constant end ci_dual_problem = get_ci_dual_problem(optimizer, ci) @@ -452,16 +452,16 @@ function MOI.get( ci::MOI.ConstraintIndex{F,S}, ) where {T,F<:MOI.AbstractVectorFunction,S<:MOI.AbstractVectorSet} primal_dual_map = optimizer.dual_problem.primal_dual_map - if ci in keys(primal_dual_map.constrained_var_dual) + if ci in keys(primal_dual_map.primal_convarcon_to_dual_con) return _get( optimizer, MOI.ConstraintDual(), ci, - primal_dual_map.constrained_var_dual[ci], + primal_dual_map.primal_convarcon_to_dual_con[ci], ) else # If it has no key then there is no dual constraint - if !haskey(primal_dual_map.primal_con_dual_con, ci) + if !haskey(primal_dual_map.primal_con_to_dual_convarcon, ci) # The number of dual variable associated with the primal constraint is the ci dimension ci_dimension = length(get_vis_dual_problem(optimizer, ci)) return zeros(T, ci_dimension) diff --git a/src/constrained_variables.jl b/src/constrained_variables.jl index 1f79c632..e4517d83 100644 --- a/src/constrained_variables.jl +++ b/src/constrained_variables.jl @@ -52,15 +52,15 @@ function _add_constrained_variables( if all( # no element of the VectorOfVariables is a constrained variable # and not a parameter - vi -> !haskey(m.constrained_var_idx, vi) && !(vi in params), + vi -> !haskey(m.primal_convar_to_primal_convarcon_and_index, vi) && !(vi in params), f.variables, ) for (i, vi) in enumerate(f.variables) - m.constrained_var_idx[vi] = (ci, i) + m.primal_convar_to_primal_convarcon_and_index[vi] = (ci, i) end # Placeholder to indicate this constraint is part of constrained variables, # it will be replaced later with a dual constraints - m.constrained_var_dual[ci] = NO_CONSTRAINT + m.primal_convarcon_to_dual_con[ci] = NO_CONSTRAINT end end return @@ -80,15 +80,15 @@ function _add_constrained_variable( f = MOI.get(primal_model, MOI.ConstraintFunction(), ci) # no element of the VectorOfVariables is a constrained variable # and not a parameter - if !haskey(m.constrained_var_idx, f) && !(f in params) + if !haskey(m.primal_convar_to_primal_convarcon_and_index, f) && !(f in params) set = MOI.get(primal_model, MOI.ConstraintSet(), ci) if !iszero(MOI.constant(set)) continue end - m.constrained_var_idx[f] = (ci, 1) + m.primal_convar_to_primal_convarcon_and_index[f] = (ci, 1) # Placeholder to indicate this constraint is part of constrained variables, # it will be replaced later with a dual constraints - m.constrained_var_dual[ci] = NO_CONSTRAINT + m.primal_convarcon_to_dual_con[ci] = NO_CONSTRAINT end end return diff --git a/src/dual_equality_constraints.jl b/src/dual_equality_constraints.jl index d63c78d6..29d13a51 100644 --- a/src/dual_equality_constraints.jl +++ b/src/dual_equality_constraints.jl @@ -26,7 +26,7 @@ function add_dual_equality_constraints( # TODO: flip these signs a priorie instead of require post processing later scalar_affine_terms = get_scalar_affine_terms( primal_model, - primal_dual_map.primal_con_dual_var, + primal_dual_map.primal_con_to_dual_var_vec, all_variables, con_types, T, @@ -42,7 +42,7 @@ function add_dual_equality_constraints( # TODO: unflip these signs add_scalar_affine_terms_from_quad_obj( scalar_affine_terms, - primal_dual_map.primal_var_dual_quad_slack, + primal_dual_map.primal_var_in_quad_obj_to_dual_slack_var, primal_objective, sense_change, ) @@ -52,13 +52,13 @@ function add_dual_equality_constraints( # TODO: unflip these signs add_scalar_affine_terms_from_quad_params( scalar_affine_terms, - primal_dual_map.primal_parameter, + primal_dual_map.primal_parameter_to_dual_parameter, primal_objective, sense_change, ) # Constrained variables - for ci in keys(primal_dual_map.constrained_var_dual) + for ci in keys(primal_dual_map.primal_convarcon_to_dual_con) # Add constraints associated with constrained variables # These are constraints that will not be regular equality constraints # they will be function-in-set, where set is the dual set of the @@ -67,8 +67,8 @@ function add_dual_equality_constraints( _add_constrained_variable_constraint( dual_model, primal_model, - primal_dual_map.constrained_var_zero, - primal_dual_map.constrained_var_dual, + primal_dual_map.primal_convarcon_to_dual_function, + primal_dual_map.primal_convarcon_to_dual_con, ci, scalar_affine_terms, scalar_terms, @@ -80,7 +80,7 @@ function add_dual_equality_constraints( # Free variables for primal_vi in non_parameter_variables - if primal_vi in keys(primal_dual_map.constrained_var_idx) + if primal_vi in keys(primal_dual_map.primal_convar_to_primal_convarcon_and_index) continue # constrained variable end # Add equality constraint @@ -109,7 +109,7 @@ function add_dual_equality_constraints( ) end # Add primal variable to dual contraint to the link dictionary - push!(primal_dual_map.primal_var_dual_con, primal_vi => dual_ci) + push!(primal_dual_map.primal_var_to_dual_con, primal_vi => dual_ci) end return scalar_affine_terms end @@ -240,26 +240,26 @@ function add_scalar_affine_terms_from_quad_obj( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_var_dual_quad_slack::Dict{MOI.VariableIndex,MOI.VariableIndex}, + primal_var_in_quad_obj_to_dual_slack_var::Dict{MOI.VariableIndex,MOI.VariableIndex}, primal_objective::PrimalObjective{T}, sense_change::T, ) where {T} for term in primal_objective.obj.quadratic_terms if term.variable_1 == term.variable_2 - dual_vi = primal_var_dual_quad_slack[term.variable_1] + dual_vi = primal_var_in_quad_obj_to_dual_slack_var[term.variable_1] push_to_scalar_affine_terms!( scalar_affine_terms[term.variable_1], -sense_change * MOI.coefficient(term), dual_vi, ) else - dual_vi_1 = primal_var_dual_quad_slack[term.variable_1] + dual_vi_1 = primal_var_in_quad_obj_to_dual_slack_var[term.variable_1] push_to_scalar_affine_terms!( scalar_affine_terms[term.variable_2], -sense_change * MOI.coefficient(term), dual_vi_1, ) - dual_vi_2 = primal_var_dual_quad_slack[term.variable_2] + dual_vi_2 = primal_var_in_quad_obj_to_dual_slack_var[term.variable_2] push_to_scalar_affine_terms!( scalar_affine_terms[term.variable_1], -sense_change * MOI.coefficient(term), @@ -275,13 +275,13 @@ function add_scalar_affine_terms_from_quad_params( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex}, + primal_parameter_to_dual_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex}, primal_objective::PrimalObjective{T}, sense_change::T, ) where {T} for (key, val) in primal_objective.quad_cross_parameters for term in val - dual_vi = primal_parameter[term.variable] + dual_vi = primal_parameter_to_dual_parameter[term.variable] push_to_scalar_affine_terms!( scalar_affine_terms[key], -sense_change * MOI.coefficient(term), @@ -324,7 +324,7 @@ function fill_scalar_affine_terms!( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_con_dual_var::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, primal_model::MOI.ModelLike, ::Type{F}, ::Type{S}, @@ -332,7 +332,7 @@ function fill_scalar_affine_terms!( for ci in MOI.get(primal_model, MOI.ListOfConstraintIndices{F,S}()) fill_scalar_affine_terms!( scalar_affine_terms, - primal_con_dual_var, + primal_con_to_dual_var_vec, primal_model, ci, ) @@ -342,7 +342,7 @@ end function get_scalar_affine_terms( primal_model::MOI.ModelLike, - primal_con_dual_var::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, variables::Vector{MOI.VariableIndex}, con_types::Vector{Tuple{Type,Type}}, ::Type{T}, @@ -354,7 +354,7 @@ function get_scalar_affine_terms( for (F, S) in con_types fill_scalar_affine_terms!( scalar_affine_terms, - primal_con_dual_var, + primal_con_to_dual_var_vec, primal_model, F, S, @@ -379,13 +379,13 @@ function fill_scalar_affine_terms!( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_con_dual_var::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, primal_model::MOI.ModelLike, ci::MOI.ConstraintIndex{MOI.ScalarAffineFunction{T},S}, ) where {T,S<:Union{MOI.GreaterThan{T},MOI.LessThan{T},MOI.EqualTo{T}}} moi_function = get_function(primal_model, ci) for term in moi_function.terms - dual_vi = primal_con_dual_var[ci][1] # In this case we only have one vi + dual_vi = primal_con_to_dual_var_vec[ci][1] # In this case we only have one vi push_to_scalar_affine_terms!( scalar_affine_terms[term.variable], MOI.coefficient(term), @@ -400,11 +400,11 @@ function fill_scalar_affine_terms!( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_con_dual_var::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, primal_model::MOI.ModelLike, ci::MOI.ConstraintIndex{MOI.VariableIndex,S}, ) where {T,S<:Union{MOI.GreaterThan{T},MOI.LessThan{T},MOI.EqualTo{T}}} - dual_var = get(primal_con_dual_var, ci, nothing) + dual_var = get(primal_con_to_dual_var_vec, ci, nothing) if dual_var === nothing # No variables created as the primal constraint is the constraint # of a constrained variable. Hence, its duality information goes to @@ -426,14 +426,14 @@ function fill_scalar_affine_terms!( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_con_dual_var::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, primal_model::MOI.ModelLike, ci::MOI.ConstraintIndex{MOI.VectorAffineFunction{T},S}, ) where {T,S<:MOI.AbstractVectorSet} moi_function = get_function(primal_model, ci) set = get_set(primal_model, ci) for term in moi_function.terms - dual_vi = primal_con_dual_var[ci][term.output_index] + dual_vi = primal_con_to_dual_var_vec[ci][term.output_index] # term.output_index is the row of the MOI.VectorAffineFunction, # it corresponds to the dual variable associated with this constraint push_to_scalar_affine_terms!( @@ -450,11 +450,11 @@ function fill_scalar_affine_terms!( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_con_dual_var::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, primal_model::MOI.ModelLike, ci::MOI.ConstraintIndex{MOI.VectorOfVariables,S}, ) where {T,S<:MOI.AbstractVectorSet} - dual_vars = get(primal_con_dual_var, ci, nothing) + dual_vars = get(primal_con_to_dual_var_vec, ci, nothing) if dual_vars === nothing # No variables created as the primal constraint is the constraint # of a constrained variable. Hence, its duality information goes to diff --git a/src/dual_model_variables.jl b/src/dual_model_variables.jl index ab43a11b..2437b3e5 100644 --- a/src/dual_model_variables.jl +++ b/src/dual_model_variables.jl @@ -15,28 +15,28 @@ function _add_dual_vars_in_dual_cones( for ci in MOI.get(primal_model, MOI.ListOfConstraintIndices{F,S}()) # If `F` not one of these two, we can skip the `in` check. if (F === MOI.VectorOfVariables || F === MOI.VariableIndex) && - haskey(primal_dual_map.constrained_var_dual, ci) + haskey(primal_dual_map.primal_convarcon_to_dual_con, ci) continue end # Add dual variable to dual cone # Fill a dual objective dictionary - # Fill the primal_con_dual_var dictionary + # Fill the primal_con_to_dual_var_vec dictionary ci_dual = add_dual_variable( dual_model, primal_model, dual_names, - primal_dual_map.primal_con_dual_var, + primal_dual_map.primal_con_to_dual_var_vec, dual_obj_affine_terms, ci, ) - push_to_primal_con_dual_con!( - primal_dual_map.primal_con_dual_con, + push_to_primal_con_to_dual_convarcon!( + primal_dual_map.primal_con_to_dual_convarcon, ci, ci_dual, ) - push_to_primal_con_constants!( + push_to_primal_con_to_primal_constants_vec!( primal_model, - primal_dual_map.primal_con_constants, + primal_dual_map.primal_con_to_primal_constants_vec, ci, ) end @@ -65,19 +65,19 @@ function add_dual_vars_in_dual_cones( return dual_obj_affine_terms end -# Utils for primal_con_constants dict -function push_to_primal_con_constants!( +# Utils for primal_con_to_primal_constants_vec dict +function push_to_primal_con_to_primal_constants_vec!( primal_model::MOI.ModelLike, - primal_con_constants::Dict{MOI.ConstraintIndex,Vector{T}}, + primal_con_to_primal_constants_vec::Dict{MOI.ConstraintIndex,Vector{T}}, ci::MOI.ConstraintIndex{F,S}, ) where {T,F<:MOI.AbstractScalarFunction,S<:MOI.AbstractScalarSet} - push!(primal_con_constants, ci => get_scalar_term(primal_model, ci)) + push!(primal_con_to_primal_constants_vec, ci => get_scalar_term(primal_model, ci)) return end -function push_to_primal_con_constants!( +function push_to_primal_con_to_primal_constants_vec!( primal_model::MOI.ModelLike, - primal_con_constants::Dict{MOI.ConstraintIndex,Vector{T}}, + primal_con_to_primal_constants_vec::Dict{MOI.ConstraintIndex,Vector{T}}, ci::MOI.ConstraintIndex{F,S}, ) where {T,F<:MOI.AbstractVectorFunction,S<:MOI.AbstractVectorSet} # No constants need to be passed to the DualOptimizer in this case, @@ -87,18 +87,18 @@ function push_to_primal_con_constants!( return end -# Utils for primal_con_dual_con dict -function push_to_primal_con_dual_con!( - primal_con_dual_con::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}, +# Utils for primal_con_to_dual_convarcon dict +function push_to_primal_con_to_dual_convarcon!( + primal_con_to_dual_convarcon::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}, ci::MOI.ConstraintIndex, ci_dual::MOI.ConstraintIndex, ) - push!(primal_con_dual_con, ci => ci_dual) + push!(primal_con_to_dual_convarcon, ci => ci_dual) return end -function push_to_primal_con_dual_con!( - primal_con_dual_con::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}, +function push_to_primal_con_to_dual_convarcon!( + primal_con_to_dual_convarcon::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}, ci::MOI.ConstraintIndex, ci_dual::Nothing, ) @@ -136,13 +136,13 @@ function add_dual_variable( dual_model::MOI.ModelLike, primal_model::MOI.ModelLike, dual_names::DualNames, - primal_con_dual_var::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, dual_obj_affine_terms::Dict{MOI.VariableIndex,T}, ci::MOI.ConstraintIndex{F,S}, ) where {T,F<:MOI.AbstractFunction,S<:MOI.AbstractSet} vis, con_index = add_dual_cone_constraint(dual_model, primal_model, ci) # Add the map of the added dual variable to the relationated constraint - push!(primal_con_dual_var, ci => vis) + push!(primal_con_to_dual_var_vec, ci => vis) # Get constraint name ci_name = MOI.get(primal_model, MOI.ConstraintName(), ci) # Add each vi to the dictionary @@ -205,8 +205,8 @@ function add_primal_parameter_vars( else push!(added, ind) vi = MOI.add_variable(dual_model) - push_to_primal_parameter!( - primal_dual_map.primal_parameter, + push_to_primal_parameter_to_dual_parameter!( + primal_dual_map.primal_parameter_to_dual_parameter, ind, vi, ) @@ -226,8 +226,8 @@ function add_primal_parameter_vars( elseif length(variable_parameters) > 0 vis = MOI.add_variables(dual_model, length(variable_parameters)) for i in eachindex(vis) - push_to_primal_parameter!( - primal_dual_map.primal_parameter, + push_to_primal_parameter_to_dual_parameter!( + primal_dual_map.primal_parameter_to_dual_parameter, variable_parameters[i], vis[i], ) @@ -250,12 +250,12 @@ function add_primal_parameter_vars( end # Save mapping between primal parameter and dual parameter -function push_to_primal_parameter!( - primal_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex}, +function push_to_primal_parameter_to_dual_parameter!( + primal_parameter_to_dual_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex}, vi::MOI.VariableIndex, vi_dual::MOI.VariableIndex, ) - push!(primal_parameter, vi => vi_dual) + push!(primal_parameter_to_dual_parameter, vi => vi_dual) return end @@ -291,7 +291,7 @@ function add_quadratic_slack_vars( push!(added, ind) vi = MOI.add_variable(dual_model) push_to_quad_slack!( - primal_dual_map.primal_var_dual_quad_slack, + primal_dual_map.primal_var_in_quad_obj_to_dual_slack_var, ind, vi, ) diff --git a/src/dualize.jl b/src/dualize.jl index ae2adf4c..467048e8 100644 --- a/src/dualize.jl +++ b/src/dualize.jl @@ -89,9 +89,9 @@ function dualize( get_primal_objective(primal_model, variable_parameters, T) # Cache information of which primal variables are `constrained_variables` - # creating a map: constrained_var_idx, from original primal vars to original + # creating a map: primal_convar_to_primal_convarcon_and_index, from original primal vars to original # constrains and their internal index (if vector constrains), 1 otherwise. - # Also, initializes the map: `constrained_var_dual`, from original primal ci + # Also, initializes the map: `primal_convarcon_to_dual_con`, from original primal ci # to the dual constraint (latter is initilized as empty at this point). # If the Set constant of a MOI.VariableIndex-in-Set constraint is non-zero, # the respective primal variable will not be a constrained variable (with @@ -112,14 +112,14 @@ function dualize( # * creates the dual variable associated with the primal constraint # * fills `dual_obj_affine_terms`, since we are already looping through # all constraints that might have constants. - # * fills `primal_con_dual_var` mapping the primal constraint and the dual + # * fills `primal_con_to_dual_var_vec` mapping the primal constraint and the dual # variable - # * fills `primal_con_dual_con` to map the primal constraint to a + # * fills `primal_con_to_dual_convarcon` to map the primal constraint to a # constraint in the dual variable (if there is such constraint the dual # dual variable is said to be constrained). If the primal constraint's set # is EqualTo or Zeros, no constraint is added in the dual variable (the # dual variable is said to be free). - # * fills `primal_con_constants` mapping primal constraints to their + # * fills `primal_con_to_primal_constants_vec` mapping primal constraints to their # respective constants, which might be inside the set. # this map is used in `MOI.get(::DualOptimizer,::MOI.ConstraintPrimal,ci)` # that requires extra information in the case that the scalar set @@ -134,7 +134,7 @@ function dualize( # Creates variables in the dual problem that represent parameters in the # primal model. - # Fills `primal_parameter` mapping parameters in the primal to parameters + # Fills `primal_parameter_to_dual_parameter` mapping parameters in the primal to parameters # in the dual model. add_primal_parameter_vars( dual_problem.dual_model, @@ -149,7 +149,7 @@ function dualize( # Add dual slack variables that are associated to the primal quadratic terms # All primal variables that appear in the objective products will have an # associated dual slack variable that is created here. - # also, `primal_var_dual_quad_slack` is filled, mapping primal variables + # also, `primal_var_in_quad_obj_to_dual_slack_var` is filled, mapping primal variables # (that appear in quadritc objective terms) to dual "slack" variables. add_quadratic_slack_vars( dual_problem.dual_model, diff --git a/src/objective_coefficients.jl b/src/objective_coefficients.jl index be5c04ba..97e17964 100644 --- a/src/objective_coefficients.jl +++ b/src/objective_coefficients.jl @@ -256,8 +256,8 @@ function get_dual_objective( quad_terms, MOI.ScalarQuadraticTerm{T}( -MOI.coefficient(term), - map.primal_var_dual_quad_slack[term.variable_1], - map.primal_var_dual_quad_slack[term.variable_2], + map.primal_var_in_quad_obj_to_dual_slack_var[term.variable_1], + map.primal_var_in_quad_obj_to_dual_slack_var[term.variable_2], ), ) end @@ -275,7 +275,7 @@ function get_dual_objective( lin_terms, MOI.ScalarAffineTerm{T}( MOI.coefficient(term), - map.primal_parameter[term.variable], + map.primal_parameter_to_dual_parameter[term.variable], ), ) end @@ -288,8 +288,8 @@ function get_dual_objective( quad_terms, MOI.ScalarQuadraticTerm{T}( MOI.coefficient(term), - map.primal_parameter[term.variable_1], - map.primal_parameter[term.variable_2], + map.primal_parameter_to_dual_parameter[term.variable_1], + map.primal_parameter_to_dual_parameter[term.variable_2], ), ) end @@ -301,7 +301,7 @@ function get_dual_objective( # and, thus, the go to the obj of the dual. # TODO? set_dot for vi in variable_parameters - param = map.primal_parameter[vi] + param = map.primal_parameter_to_dual_parameter[vi] for term in scalar_affine_terms[vi] push!( quad_terms, diff --git a/src/structures.jl b/src/structures.jl index 029198d3..4390295d 100644 --- a/src/structures.jl +++ b/src/structures.jl @@ -30,132 +30,176 @@ MOI.Utilities.@model( Maps information from all structures of the primal to the dual model. -Main user maps: +The following abbreviations are used in the maps: - * `constrained_var_idx::Dict{MOI.VariableIndex,Tuple{MOI.ConstraintIndex,Int}}`: +* `var`: variable index +* `con`: constraint index +* `convar`: constrained variable, variable index +* `convarcon`: constrained variable, constraint index + +Main maps: + + * `primal_convar_to_primal_convarcon_and_index::Dict{MOI.VariableIndex,Tuple{MOI.ConstraintIndex,Int}}`: maps primal constrained variables to their primal constraints (the special ones that makes them constrained variables) and their internal index from 1 to dimension(set) (if vector constraints: VectorOfVariables-in-Set), 1 otherwise (scalar: VariableIndex-in-Set). - Future name: primal_convar_to_primal_convarcon_and_index - * `constrained_var_dual::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}`: maps + note: this set is important to dualization can keep track of what it + decided to define as a constrained variable. + - consider index 0 to highlight scalars + + * `primal_convarcon_to_dual_con::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}`: maps the primal constraint index of constrained variables to the dual model's constraint index of the associated dual constraint. This dual constraint is a regular constraint (not a constrained variable constraint). `VectorOfVariables`-in-`Zeros` and `VariableIndex`-in-`EqualTo(zero(T))` are not in this map, as they are not dualized (See primal_convarcon_to_dual_function). - Future name: primal_convarcon_to_dual_con note: from the above two maps, we can get primal_convar_to_dual_con_and_index - * `primal_var_dual_con::Dict{MOI.VariableIndex,MOI.ConstraintIndex}`: maps + * `primal_var_to_dual_con::Dict{MOI.VariableIndex,MOI.ConstraintIndex}`: maps "free" primal variables to their associated dual (equality) constraints. Free variables as opposed to constrained variables. Note that Dualization will select automatically which variables are free and which are constrained. - Future name: primal_var_to_dual_con note: from the above three maps, we can get primal_var_to_dual_con_and_index - * `primal_con_dual_var::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}`: + # TODO: idea, for simmetry, keep only + - primal_convarcon_to_dual_con (as is), analogous to primal_con_to_dual_convarcon + - primal_var_to_dual_con_and_index, analogous to primal_con_to_dual_var_vec + -- the second implicitly tracks which vars were decided to be convar's + + * `primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}`: maps primal constraint indices to vectors of dual variable indices. For scalar constraints those vectors will be single element vectors. Primal Constrained variables constraints (the main ones) are not in this map. - Future name: primal_con_to_dual_var_vec - * `primal_con_dual_con::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}`: maps + note: possibly change this to + + * `primal_con_to_dual_convarcon::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}`: maps primal constraints to dual constrained variable. If the primal constraint's set is EqualTo or Zeros, no constraint is added in the dual variable (the dual variable is said to be free). The keys are similar to the (# primal_con_to_dual_var_vec) map, except that `VariableIndex`-in-`EqualTo(zero(T))` and `VectorOfVariables`-in-`Zeros` are not in this map. - Future name: primal_con_to_dual_convarcon Additional helper maps: - * `primal_con_constants::Dict{MOI.ConstraintIndex,Vector{T}}`: maps primal + * `primal_con_to_primal_constants_vec::Dict{MOI.ConstraintIndex,Vector{T}}`: maps primal constraints to their respective constants, which might be inside the set. This map is used in `MOI.get(::DualOptimizer,::MOI.ConstraintPrimal,ci)` that requires extra information in the case that the scalar set constrains a constant (`EqualtTo`, `GreaterThan`, `LessThan`). - Future name: primal_con_to_primal_constants_vec + # TODO is the vec ever really used??? - * `primal_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex}`: maps + * `primal_parameter_to_dual_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex}`: maps parameters in the primal to parameters in the dual model. - Future name: primal_parameter_to_dual_parameter - * `constrained_var_zero::Dict{MOI.ConstraintIndex,Unions{MOI.ScalarAffineFunction,MOI.VectorAffineFunction}}`: + * `primal_convarcon_to_dual_function::Dict{MOI.ConstraintIndex,Unions{MOI.ScalarAffineFunction,MOI.VectorAffineFunction}}`: caches scalar affine functions or vector affine functions associated with constrained variables of type `VectorOfVariables`-in-`Zeros` or `VariableIndex`-in-`EqualTo(zero(T))` as their duals would be `func`-in-`Reals`, which are "irrelevant" to the model. This information is cached for completeness of the `DualOptimizer` for `get`ting `ConstraintDuals`. - Future name: primal_convarcon_to_dual_function - * `primal_var_dual_quad_slack::Dict{MOI.VariableIndex,MOI.VariableIndex}`: + * `primal_var_in_quad_obj_to_dual_slack_var::Dict{MOI.VariableIndex,MOI.VariableIndex}`: maps primal variables (that appear in quadratic objective terms) to dual "slack" variables. These primal variables might appear in other maps. Future name: primal_var_in_quad_obj_to_dual_slack_var """ mutable struct PrimalDualMap{T} - constrained_var_idx::Dict{MOI.VariableIndex,Tuple{MOI.ConstraintIndex,Int}} - constrained_var_dual::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex} - constrained_var_zero::Dict{ + primal_convar_to_primal_convarcon_and_index::Dict{MOI.VariableIndex,Tuple{MOI.ConstraintIndex,Int}} + primal_convarcon_to_dual_con::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex} + primal_var_to_dual_con::Dict{MOI.VariableIndex,MOI.ConstraintIndex} + primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}} + primal_con_to_dual_convarcon::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex} + + primal_con_to_primal_constants_vec::Dict{MOI.ConstraintIndex,Vector{T}} + primal_parameter_to_dual_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex} + primal_convarcon_to_dual_function::Dict{ MOI.ConstraintIndex, Union{MOI.VectorAffineFunction{T},MOI.ScalarAffineFunction{T}}, } - primal_var_dual_con::Dict{MOI.VariableIndex,MOI.ConstraintIndex} - primal_con_dual_var::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}} - primal_con_dual_con::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex} - primal_con_constants::Dict{MOI.ConstraintIndex,Vector{T}} - - primal_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex} - primal_var_dual_quad_slack::Dict{MOI.VariableIndex,MOI.VariableIndex} + primal_var_in_quad_obj_to_dual_slack_var::Dict{MOI.VariableIndex,MOI.VariableIndex} function PrimalDualMap{T}() where {T} return new( Dict{MOI.VariableIndex,Tuple{MOI.ConstraintIndex,Int}}(), Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}(), - Dict{ - MOI.ConstraintIndex, - Union{MOI.VectorAffineFunction{T},MOI.ScalarAffineFunction{T}}, - }(), Dict{MOI.VariableIndex,MOI.ConstraintIndex}(), Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}(), Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}(), Dict{MOI.ConstraintIndex,Vector{T}}(), Dict{MOI.VariableIndex,MOI.VariableIndex}(), + Dict{ + MOI.ConstraintIndex, + Union{MOI.VectorAffineFunction{T},MOI.ScalarAffineFunction{T}}, + }(), Dict{MOI.VariableIndex,MOI.VariableIndex}(), ) end end +function Base.getproperty(m::PrimalDualMap{T}, name::Symbol) where {T} + if name === :constrained_var_idx + @warn "constrained_var_idx field is deprecated, use primal_convar_to_primal_convarcon_and_index instead" + return getfield(m, :primal_convar_to_primal_convarcon_and_index) + elseif name === :constrained_var_dual + @warn "constrained_var_dual field is deprecated, use primal_convarcon_to_dual_con instead" + return getfield(m, :primal_convarcon_to_dual_con) + elseif name === :primal_var_dual_con + @warn "primal_var_dual_con field is deprecated, use primal_var_to_dual_con instead" + return getfield(m, :primal_var_to_dual_con) + elseif name === :primal_con_dual_var + @warn "primal_con_dual_var field is deprecated, use primal_con_to_dual_var_vec instead" + return getfield(m, :primal_con_to_dual_var_vec) + elseif name === :primal_con_dual_con + @warn "primal_con_dual_con field is deprecated, use primal_con_to_dual_convarcon instead" + return getfield(m, :primal_con_to_dual_convarcon) + elseif name === :primal_con_constants + @warn "primal_con_constants field is deprecated, use primal_con_to_primal_constants_vec instead" + return getfield(m, :primal_con_to_primal_constants_vec) + elseif name === :primal_parameter + @warn "primal_parameter field is deprecated, use primal_parameter_to_dual_parameter instead" + return getfield(m, :primal_parameter_to_dual_parameter) + elseif name === :constrained_var_zero + @warn "constrained_var_zero field is deprecated, use primal_convarcon_to_dual_function instead" + return getfield(m, :primal_convarcon_to_dual_function) + elseif name === :primal_var_dual_quad_slack + @warn "primal_var_dual_quad_slack field is deprecated, use primal_var_in_quad_obj_to_dual_slack_var instead" + return getfield(m, :primal_var_in_quad_obj_to_dual_slack_var) + else + return getfield(m, name) + end +end + function is_empty(primal_dual_map::PrimalDualMap{T}) where {T} - return isempty(primal_dual_map.constrained_var_idx) && - isempty(primal_dual_map.constrained_var_dual) && - isempty(primal_dual_map.constrained_var_zero) && - isempty(primal_dual_map.primal_var_dual_con) && - isempty(primal_dual_map.primal_con_dual_var) && - isempty(primal_dual_map.primal_con_dual_con) && - isempty(primal_dual_map.primal_con_constants) && - isempty(primal_dual_map.primal_parameter) && - isempty(primal_dual_map.primal_var_dual_quad_slack) + return isempty(primal_dual_map.primal_convar_to_primal_convarcon_and_index) && + isempty(primal_dual_map.primal_convarcon_to_dual_con) && + isempty(primal_dual_map.primal_convarcon_to_dual_function) && + isempty(primal_dual_map.primal_var_to_dual_con) && + isempty(primal_dual_map.primal_con_to_dual_var_vec) && + isempty(primal_dual_map.primal_con_to_dual_convarcon) && + isempty(primal_dual_map.primal_con_to_primal_constants_vec) && + isempty(primal_dual_map.primal_parameter_to_dual_parameter) && + isempty(primal_dual_map.primal_var_in_quad_obj_to_dual_slack_var) end function empty!(primal_dual_map::PrimalDualMap) - Base.empty!(primal_dual_map.constrained_var_idx) - Base.empty!(primal_dual_map.constrained_var_dual) - Base.empty!(primal_dual_map.constrained_var_zero) - Base.empty!(primal_dual_map.primal_var_dual_con) - Base.empty!(primal_dual_map.primal_con_dual_var) - Base.empty!(primal_dual_map.primal_con_dual_con) - Base.empty!(primal_dual_map.primal_con_constants) - Base.empty!(primal_dual_map.primal_parameter) - Base.empty!(primal_dual_map.primal_var_dual_quad_slack) + Base.empty!(primal_dual_map.primal_convar_to_primal_convarcon_and_index) + Base.empty!(primal_dual_map.primal_convarcon_to_dual_con) + Base.empty!(primal_dual_map.primal_convarcon_to_dual_function) + Base.empty!(primal_dual_map.primal_var_to_dual_con) + Base.empty!(primal_dual_map.primal_con_to_dual_var_vec) + Base.empty!(primal_dual_map.primal_con_to_dual_convarcon) + Base.empty!(primal_dual_map.primal_con_to_primal_constants_vec) + Base.empty!(primal_dual_map.primal_parameter_to_dual_parameter) + Base.empty!(primal_dual_map.primal_var_in_quad_obj_to_dual_slack_var) return end diff --git a/test/Tests/test_dual_names.jl b/test/Tests/test_dual_names.jl index 0fd6bfaf..e9b45f51 100644 --- a/test/Tests/test_dual_names.jl +++ b/test/Tests/test_dual_names.jl @@ -32,13 +32,13 @@ dual_model = dual_problem.dual_model primal_dual_map = dual_problem.primal_dual_map # Query variable names - vi_1 = primal_dual_map.primal_con_dual_var[MOI.ConstraintIndex{ + vi_1 = primal_dual_map.primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.VariableIndex, MOI.GreaterThan{Float64}, }( 1, )][1] - vi_2 = primal_dual_map.primal_con_dual_var[MOI.ConstraintIndex{ + vi_2 = primal_dual_map.primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}, }( @@ -47,8 +47,8 @@ @test MOI.get(dual_model, MOI.VariableName(), vi_1) == "" @test MOI.get(dual_model, MOI.VariableName(), vi_2) == "" # Query constraint names - ci_1 = primal_dual_map.primal_var_dual_con[MOI.VariableIndex(1)] - ci_2 = primal_dual_map.primal_var_dual_con[MOI.VariableIndex(2)] + ci_1 = primal_dual_map.primal_var_to_dual_con[MOI.VariableIndex(1)] + ci_2 = primal_dual_map.primal_var_to_dual_con[MOI.VariableIndex(2)] @test MOI.get(dual_model, MOI.ConstraintName(), ci_1) == "" @test MOI.get(dual_model, MOI.ConstraintName(), ci_2) == "" @@ -59,13 +59,13 @@ dual_model = dual_problem.dual_model primal_dual_map = dual_problem.primal_dual_map # Query variable names - vi_1 = primal_dual_map.primal_con_dual_var[MOI.ConstraintIndex{ + vi_1 = primal_dual_map.primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.VariableIndex, MOI.GreaterThan{Float64}, }( 1, )][1] - vi_2 = primal_dual_map.primal_con_dual_var[MOI.ConstraintIndex{ + vi_2 = primal_dual_map.primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}, }( @@ -73,8 +73,8 @@ )][1] @test MOI.get(dual_model, MOI.VariableName(), vi_2) == "dualvar_lessthan_1" # Query constraint names - ci_1 = primal_dual_map.primal_var_dual_con[MOI.VariableIndex(1)] - ci_2 = primal_dual_map.primal_var_dual_con[MOI.VariableIndex(2)] + ci_1 = primal_dual_map.primal_var_to_dual_con[MOI.VariableIndex(1)] + ci_2 = primal_dual_map.primal_var_to_dual_con[MOI.VariableIndex(2)] @test MOI.get(dual_model, MOI.ConstraintName(), ci_1) == "dualcon_x1" @test MOI.get(dual_model, MOI.ConstraintName(), ci_2) == "dualcon_x2" end diff --git a/test/Tests/test_dualize_conic_linear.jl b/test/Tests/test_dualize_conic_linear.jl index be8e34d4..141e3edd 100644 --- a/test/Tests/test_dualize_conic_linear.jl +++ b/test/Tests/test_dualize_conic_linear.jl @@ -55,7 +55,7 @@ @test MOI.get(dual_model, MOI.ConstraintSet(), ci) == MOI.Nonnegatives(3) - primal_con_dual_var = primal_dual_map.primal_con_dual_var + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec ci_zero = first( MOI.get( primal_model, @@ -65,7 +65,7 @@ }(), ), ) - @test primal_con_dual_var[ci_zero] == MOI.VariableIndex.(1:2) + @test primal_con_to_dual_var_vec[ci_zero] == MOI.VariableIndex.(1:2) ci_nneg = first( MOI.get( primal_model, @@ -75,13 +75,13 @@ }(), ), ) - @test !haskey(primal_con_dual_var, ci_nneg) - @test primal_dual_map.constrained_var_dual[ci_nneg] == ci + @test !haskey(primal_con_to_dual_var_vec, ci_nneg) + @test primal_dual_map.primal_convarcon_to_dual_con[ci_nneg] == ci for i in 1:3 vi = MOI.VariableIndex(i) - @test !haskey(primal_dual_map.primal_var_dual_con, vi) - @test primal_dual_map.constrained_var_idx[vi] == (ci_nneg, i) + @test !haskey(primal_dual_map.primal_var_to_dual_con, vi) + @test primal_dual_map.primal_convar_to_primal_convarcon_and_index[vi] == (ci_nneg, i) end end @@ -187,14 +187,14 @@ @test MOI.coefficient.(eq_con3_fun.terms) == -[1.0] @test MOI.constant(eq_con3_fun) == [-4.0] - primal_con_dual_var = primal_dual_map.primal_con_dual_var + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec ci_zero = first( MOI.get( primal_model, MOI.ListOfConstraintIndices{MOI.VectorOfVariables,MOI.Zeros}(), ), ) - @test !haskey(primal_con_dual_var, ci_zero) + @test !haskey(primal_con_to_dual_var_vec, ci_zero) ci_nneg = first( MOI.get( primal_model, @@ -204,8 +204,8 @@ }(), ), ) - @test !haskey(primal_con_dual_var, ci_nneg) - @test primal_dual_map.constrained_var_dual[ci_nneg] == ci_nn + @test !haskey(primal_con_to_dual_var_vec, ci_nneg) + @test primal_dual_map.primal_convarcon_to_dual_con[ci_nneg] == ci_nn ci_npos = first( MOI.get( primal_model, @@ -215,8 +215,8 @@ }(), ), ) - @test !haskey(primal_con_dual_var, ci_npos) - @test primal_dual_map.constrained_var_dual[ci_npos] == ci_np + @test !haskey(primal_con_to_dual_var_vec, ci_npos) + @test primal_dual_map.primal_convarcon_to_dual_con[ci_npos] == ci_np ci_aff_zero = first( MOI.get( primal_model, @@ -226,19 +226,19 @@ }(), ), ) - @test primal_con_dual_var[ci_aff_zero] == MOI.VariableIndex.(1:3) + @test primal_con_to_dual_var_vec[ci_aff_zero] == MOI.VariableIndex.(1:3) - primal_var_dual_con = primal_dual_map.primal_var_dual_con - @test primal_var_dual_con[MOI.VariableIndex(1)] == ci_eq + primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con + @test primal_var_to_dual_con[MOI.VariableIndex(1)] == ci_eq for i in 2:4 vi = MOI.VariableIndex(i) - @test !haskey(primal_var_dual_con, vi) + @test !haskey(primal_var_to_dual_con, vi) end - @test primal_dual_map.constrained_var_idx[MOI.VariableIndex(2)] == + @test primal_dual_map.primal_convar_to_primal_convarcon_and_index[MOI.VariableIndex(2)] == (ci_npos, 1) - @test primal_dual_map.constrained_var_idx[MOI.VariableIndex(3)] == + @test primal_dual_map.primal_convar_to_primal_convarcon_and_index[MOI.VariableIndex(3)] == (ci_nneg, 1) - @test primal_dual_map.constrained_var_idx[MOI.VariableIndex(4)] == + @test primal_dual_map.primal_convar_to_primal_convarcon_and_index[MOI.VariableIndex(4)] == (ci_zero, 1) end end diff --git a/test/Tests/test_dualize_exponential.jl b/test/Tests/test_dualize_exponential.jl index 0a88e089..0e8aee9f 100644 --- a/test/Tests/test_dualize_exponential.jl +++ b/test/Tests/test_dualize_exponential.jl @@ -125,19 +125,19 @@ ) @test dual_exp_con.variables == MOI.VariableIndex.(3:5) - primal_con_dual_var = primal_dual_map.primal_con_dual_var - @test primal_con_dual_var[eq_con1] == [MOI.VariableIndex(1)] - @test primal_con_dual_var[eq_con2] == [MOI.VariableIndex(2)] - @test primal_con_dual_var[MOI.ConstraintIndex{ + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec + @test primal_con_to_dual_var_vec[eq_con1] == [MOI.VariableIndex(1)] + @test primal_con_to_dual_var_vec[eq_con2] == [MOI.VariableIndex(2)] + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.VectorAffineFunction{Float64}, MOI.ExponentialCone, }( 1, )] == MOI.VariableIndex.(3:5) - primal_var_dual_con = primal_dual_map.primal_var_dual_con - @test primal_var_dual_con[MOI.VariableIndex(1)] == eq_con1 - @test primal_var_dual_con[MOI.VariableIndex(2)] == eq_con2 - @test primal_var_dual_con[MOI.VariableIndex(3)] == eq_con3 + primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con + @test primal_var_to_dual_con[MOI.VariableIndex(1)] == eq_con1 + @test primal_var_to_dual_con[MOI.VariableIndex(2)] == eq_con2 + @test primal_var_to_dual_con[MOI.VariableIndex(3)] == eq_con3 end end diff --git a/test/Tests/test_dualize_power.jl b/test/Tests/test_dualize_power.jl index 5b1b5769..2d79afd5 100644 --- a/test/Tests/test_dualize_power.jl +++ b/test/Tests/test_dualize_power.jl @@ -125,13 +125,13 @@ dual_pow_con = MOI.get(dual_model, MOI.ConstraintFunction(), pow_con) - primal_con_dual_var = primal_dual_map.primal_con_dual_var - @test primal_con_dual_var[eq_con1] == [MOI.VariableIndex(1)] - @test primal_con_dual_var[eq_con2] == [MOI.VariableIndex(2)] + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec + @test primal_con_to_dual_var_vec[eq_con1] == [MOI.VariableIndex(1)] + @test primal_con_to_dual_var_vec[eq_con2] == [MOI.VariableIndex(2)] - primal_var_dual_con = primal_dual_map.primal_var_dual_con - @test primal_var_dual_con[MOI.VariableIndex(1)] == eq_con1 - @test primal_var_dual_con[MOI.VariableIndex(2)] == eq_con2 - @test primal_var_dual_con[MOI.VariableIndex(3)] == eq_con3 + primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con + @test primal_var_to_dual_con[MOI.VariableIndex(1)] == eq_con1 + @test primal_var_to_dual_con[MOI.VariableIndex(2)] == eq_con2 + @test primal_var_to_dual_con[MOI.VariableIndex(3)] == eq_con3 end end diff --git a/test/Tests/test_dualize_quadratic.jl b/test/Tests/test_dualize_quadratic.jl index a65eaaf0..7228f451 100644 --- a/test/Tests/test_dualize_quadratic.jl +++ b/test/Tests/test_dualize_quadratic.jl @@ -124,46 +124,46 @@ @test MOI.constant.(eq_con3_fun) == 0.0 @test MOI.constant(eq_con3_set) == 0.0 - primal_con_dual_var = primal_dual_map.primal_con_dual_var - @test primal_con_dual_var[MOI.ConstraintIndex{ + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}, }( 1, )] == [MOI.VariableIndex(1)] - @test primal_con_dual_var[MOI.ConstraintIndex{ + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}, }( 2, )] == [MOI.VariableIndex(2)] - primal_var_dual_con = primal_dual_map.primal_var_dual_con - @test primal_var_dual_con[MOI.VariableIndex(1)] == MOI.ConstraintIndex{ + primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con + @test primal_var_to_dual_con[MOI.VariableIndex(1)] == MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( 1, ) - @test primal_var_dual_con[MOI.VariableIndex(2)] == MOI.ConstraintIndex{ + @test primal_var_to_dual_con[MOI.VariableIndex(2)] == MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( 2, ) - @test primal_var_dual_con[MOI.VariableIndex(3)] == MOI.ConstraintIndex{ + @test primal_var_to_dual_con[MOI.VariableIndex(3)] == MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( 3, ) - primal_var_dual_quad_slack = primal_dual_map.primal_var_dual_quad_slack - @test primal_var_dual_quad_slack[MOI.VariableIndex(1)] == + 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)] == MOI.VariableIndex(2 + 1) - @test primal_var_dual_quad_slack[MOI.VariableIndex(2)] == + @test primal_var_in_quad_obj_to_dual_slack_var[MOI.VariableIndex(2)] == MOI.VariableIndex(2 + 2) - @test primal_var_dual_quad_slack[MOI.VariableIndex(3)] == + @test primal_var_in_quad_obj_to_dual_slack_var[MOI.VariableIndex(3)] == MOI.VariableIndex(2 + 3) end @testset "qp2_test" begin diff --git a/test/Tests/test_dualize_rsoc.jl b/test/Tests/test_dualize_rsoc.jl index d8a16d5a..8f11a196 100644 --- a/test/Tests/test_dualize_rsoc.jl +++ b/test/Tests/test_dualize_rsoc.jl @@ -125,16 +125,16 @@ ) @test rsoc_con.variables == MOI.VariableIndex.(1:4) - primal_con_dual_var = primal_dual_map.primal_con_dual_var - @test primal_con_dual_var[MOI.ConstraintIndex{ + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone, }( 1, )] == MOI.VariableIndex.(1:4) - primal_var_dual_con = primal_dual_map.primal_var_dual_con - @test primal_var_dual_con[MOI.VariableIndex(1)] == eq_con1 - @test primal_var_dual_con[MOI.VariableIndex(2)] == eq_con2 + primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con + @test primal_var_to_dual_con[MOI.VariableIndex(1)] == eq_con1 + @test primal_var_to_dual_con[MOI.VariableIndex(2)] == eq_con2 end end diff --git a/test/Tests/test_dualize_sdp.jl b/test/Tests/test_dualize_sdp.jl index 9bec7416..0afb2f75 100644 --- a/test/Tests/test_dualize_sdp.jl +++ b/test/Tests/test_dualize_sdp.jl @@ -125,18 +125,18 @@ sdp_con = MOI.get(dual_model, MOI.ConstraintFunction(), spd_con) - primal_con_dual_var = primal_dual_map.primal_con_dual_var - @test primal_con_dual_var[eq_con1] == [MOI.VariableIndex(1)] - @test primal_con_dual_var[MOI.ConstraintIndex{ + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec + @test primal_con_to_dual_var_vec[eq_con1] == [MOI.VariableIndex(1)] + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, }( 1, )] == MOI.VariableIndex.(2:4) - primal_var_dual_con = primal_dual_map.primal_var_dual_con - @test primal_var_dual_con[MOI.VariableIndex(1)] == eq_con1 - @test primal_var_dual_con[MOI.VariableIndex(2)] == eq_con2 - @test primal_var_dual_con[MOI.VariableIndex(3)] == eq_con3 + primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con + @test primal_var_to_dual_con[MOI.VariableIndex(1)] == eq_con1 + @test primal_var_to_dual_con[MOI.VariableIndex(2)] == eq_con2 + @test primal_var_to_dual_con[MOI.VariableIndex(3)] == eq_con3 end end diff --git a/test/Tests/test_dualize_soc.jl b/test/Tests/test_dualize_soc.jl index 130a7d32..91b0129b 100644 --- a/test/Tests/test_dualize_soc.jl +++ b/test/Tests/test_dualize_soc.jl @@ -114,8 +114,8 @@ ) @test soc_con.variables == MOI.VariableIndex.(2:4) - primal_con_dual_var = primal_dual_map.primal_con_dual_var - @test primal_con_dual_var[MOI.ConstraintIndex{ + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.VectorAffineFunction{Float64}, MOI.Zeros, }( @@ -130,12 +130,12 @@ }(), ), ) - @test primal_con_dual_var[primal_soc_con] == + @test primal_con_to_dual_var_vec[primal_soc_con] == [MOI.VariableIndex(2); MOI.VariableIndex(3); MOI.VariableIndex(4)] - primal_var_dual_con = primal_dual_map.primal_var_dual_con - @test primal_var_dual_con[MOI.VariableIndex(1)] == eq_con1 - @test primal_var_dual_con[MOI.VariableIndex(2)] == eq_con2 - @test primal_var_dual_con[MOI.VariableIndex(3)] == eq_con3 + primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con + @test primal_var_to_dual_con[MOI.VariableIndex(1)] == eq_con1 + @test primal_var_to_dual_con[MOI.VariableIndex(2)] == eq_con2 + @test primal_var_to_dual_con[MOI.VariableIndex(3)] == eq_con3 end end diff --git a/test/Tests/test_partial_dual_linear.jl b/test/Tests/test_partial_dual_linear.jl index 6e4bb0a6..4451b759 100644 --- a/test/Tests/test_partial_dual_linear.jl +++ b/test/Tests/test_partial_dual_linear.jl @@ -81,16 +81,16 @@ @test MOI.constant.(eq_con1_fun) == 0.0 @test MOI.constant(eq_con1_set) == 0.0 - primal_con_dual_var = primal_dual_map.primal_con_dual_var - @test primal_con_dual_var[MOI.ConstraintIndex{ + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}, }( 1, )] == [MOI.VariableIndex(1)] - primal_var_dual_con = primal_dual_map.primal_var_dual_con - @test primal_var_dual_con[MOI.VariableIndex(1)] == MOI.ConstraintIndex{ + primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con + @test primal_var_to_dual_con[MOI.VariableIndex(1)] == MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( @@ -167,7 +167,7 @@ @test MOI.constant.(eq_con2_fun) == 0.0 @test MOI.constant(eq_con2_set) == 3.0 - primal_con_dual_var = primal_dual_map.primal_con_dual_var + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec vaf_npos, = MOI.get( primal_model, MOI.ListOfConstraintIndices{ @@ -175,7 +175,7 @@ MOI.Nonpositives, }(), ) - @test primal_con_dual_var[vaf_npos] == + @test primal_con_to_dual_var_vec[vaf_npos] == [MOI.VariableIndex(1); MOI.VariableIndex(2)] vgt, = MOI.get( primal_model, @@ -184,10 +184,10 @@ MOI.GreaterThan{Float64}, }(), ) - @test primal_con_dual_var[vgt] == [MOI.VariableIndex(3)] + @test primal_con_to_dual_var_vec[vgt] == [MOI.VariableIndex(3)] - primal_var_dual_con = primal_dual_map.primal_var_dual_con - @test isempty(primal_var_dual_con) + primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con + @test isempty(primal_var_to_dual_con) end @testset "lp12_test - x_1 and x_3 ignored" begin @@ -265,28 +265,28 @@ @test MOI.constant.(eq_con2_fun) == 0.0 @test MOI.constant(eq_con2_set) == 0.0 - primal_con_dual_var = primal_dual_map.primal_con_dual_var - @test primal_con_dual_var[MOI.ConstraintIndex{ + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.VariableIndex, MOI.LessThan{Float64}, }( 2, )] == [MOI.VariableIndex(3)] - @test primal_con_dual_var[MOI.ConstraintIndex{ + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.VariableIndex, MOI.LessThan{Float64}, }( 1, )] == [MOI.VariableIndex(2)] - @test primal_con_dual_var[MOI.ConstraintIndex{ + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}, }( 1, )] == [MOI.VariableIndex(1)] - primal_var_dual_con = primal_dual_map.primal_var_dual_con - @test primal_var_dual_con[MOI.VariableIndex(2)] == MOI.ConstraintIndex{ + primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con + @test primal_var_to_dual_con[MOI.VariableIndex(2)] == MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( diff --git a/test/Tests/test_partial_dual_quadratic.jl b/test/Tests/test_partial_dual_quadratic.jl index ed52270c..60a27c26 100644 --- a/test/Tests/test_partial_dual_quadratic.jl +++ b/test/Tests/test_partial_dual_quadratic.jl @@ -105,41 +105,41 @@ @test MOI.constant.(eq_con2_fun) == 0.0 @test MOI.constant(eq_con2_set) == 0.0 - primal_con_dual_var = primal_dual_map.primal_con_dual_var - @test primal_con_dual_var[MOI.ConstraintIndex{ + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}, }( 1, )] == [MOI.VariableIndex(1)] - @test primal_con_dual_var[MOI.ConstraintIndex{ + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}, }( 2, )] == [MOI.VariableIndex(2)] - primal_var_dual_con = primal_dual_map.primal_var_dual_con - @test primal_var_dual_con[MOI.VariableIndex(1)] == MOI.ConstraintIndex{ + primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con + @test primal_var_to_dual_con[MOI.VariableIndex(1)] == MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( 1, ) - @test primal_var_dual_con[MOI.VariableIndex(2)] == MOI.ConstraintIndex{ + @test primal_var_to_dual_con[MOI.VariableIndex(2)] == MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( 2, ) - primal_parameter = primal_dual_map.primal_parameter - @test primal_parameter[MOI.VariableIndex(3)] == MOI.VariableIndex(2 + 1) + primal_parameter_to_dual_parameter = primal_dual_map.primal_parameter_to_dual_parameter + @test primal_parameter_to_dual_parameter[MOI.VariableIndex(3)] == MOI.VariableIndex(2 + 1) - primal_var_dual_quad_slack = primal_dual_map.primal_var_dual_quad_slack - @test primal_var_dual_quad_slack[MOI.VariableIndex(1)] == + 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)] == MOI.VariableIndex(2 + 1 + 1) - @test primal_var_dual_quad_slack[MOI.VariableIndex(2)] == + @test primal_var_in_quad_obj_to_dual_slack_var[MOI.VariableIndex(2)] == MOI.VariableIndex(2 + 1 + 2) end @testset "qp2_test - ignore y" begin @@ -218,32 +218,32 @@ @test MOI.constant.(eq_con1_fun) == 0.0 @test MOI.constant(eq_con1_set) == -1.0 - primal_con_dual_var = primal_dual_map.primal_con_dual_var - @test primal_con_dual_var[MOI.ConstraintIndex{ + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( 1, )] == [MOI.VariableIndex(1)] @test !haskey( - primal_con_dual_var, + primal_con_to_dual_var_vec, MOI.ConstraintIndex{MOI.VariableIndex,MOI.GreaterThan{Float64}}(1), ) - @test primal_con_dual_var[MOI.ConstraintIndex{ + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.VariableIndex, MOI.GreaterThan{Float64}, }( 2, )] == [MOI.VariableIndex(2)] - primal_var_dual_con = primal_dual_map.primal_var_dual_con - @test isempty(primal_var_dual_con) + primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con + @test isempty(primal_var_to_dual_con) - primal_parameter = primal_dual_map.primal_parameter - @test primal_parameter[MOI.VariableIndex(2)] == MOI.VariableIndex(3) + primal_parameter_to_dual_parameter = primal_dual_map.primal_parameter_to_dual_parameter + @test primal_parameter_to_dual_parameter[MOI.VariableIndex(2)] == MOI.VariableIndex(3) - primal_var_dual_quad_slack = primal_dual_map.primal_var_dual_quad_slack - @test primal_var_dual_quad_slack[MOI.VariableIndex(1)] == + 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)] == MOI.VariableIndex(4) end @testset "qp2_test - ignore y - no obj" begin @@ -322,31 +322,31 @@ @test MOI.constant.(eq_con1_fun) == 0.0 @test MOI.constant(eq_con1_set) == -1.0 - primal_con_dual_var = primal_dual_map.primal_con_dual_var - @test primal_con_dual_var[MOI.ConstraintIndex{ + primal_con_to_dual_var_vec = primal_dual_map.primal_con_to_dual_var_vec + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( 1, )] == [MOI.VariableIndex(1)] @test !(haskey( - primal_con_dual_var, + primal_con_to_dual_var_vec, MOI.ConstraintIndex{MOI.VariableIndex,MOI.GreaterThan{Float64}}(1), )) - @test primal_con_dual_var[MOI.ConstraintIndex{ + @test primal_con_to_dual_var_vec[MOI.ConstraintIndex{ MOI.VariableIndex, MOI.GreaterThan{Float64}, }( 2, )] == [MOI.VariableIndex(2)] - @test isempty(primal_dual_map.primal_var_dual_con) + @test isempty(primal_dual_map.primal_var_to_dual_con) - primal_parameter = primal_dual_map.primal_parameter - @test primal_parameter[MOI.VariableIndex(2)] == MOI.VariableIndex(3) + primal_parameter_to_dual_parameter = primal_dual_map.primal_parameter_to_dual_parameter + @test primal_parameter_to_dual_parameter[MOI.VariableIndex(2)] == MOI.VariableIndex(3) - primal_var_dual_quad_slack = primal_dual_map.primal_var_dual_quad_slack - @test primal_var_dual_quad_slack[MOI.VariableIndex(1)] == + 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)] == MOI.VariableIndex(4) end end diff --git a/test/Tests/test_structures.jl b/test/Tests/test_structures.jl index 13e07101..be1a244d 100644 --- a/test/Tests/test_structures.jl +++ b/test/Tests/test_structures.jl @@ -7,7 +7,7 @@ primal_dual_map = Dualization.PrimalDualMap{Float64}() @test Dualization.is_empty(primal_dual_map) push!( - primal_dual_map.primal_var_dual_con, + primal_dual_map.primal_var_to_dual_con, MOI.VariableIndex(1) => MOI.ConstraintIndex{MOI.VariableIndex,MOI.EqualTo}(1), ) diff --git a/test/optimize_abstract_models.jl b/test/optimize_abstract_models.jl index 2b7776ac..1c4b5e9b 100644 --- a/test/optimize_abstract_models.jl +++ b/test/optimize_abstract_models.jl @@ -10,7 +10,7 @@ solve it and retrieve the termination status and objective value function solve_abstract_model( model::MOI.ModelLike, optimizer_constructor, -) where {T} +) JuMP_model = JuMP.Model() MOI.copy_to(JuMP.backend(JuMP_model), model) set_optimizer(JuMP_model, optimizer_constructor) From 201121a6da33a91f944f4427e1b1eccaad8a9820 Mon Sep 17 00:00:00 2001 From: joaquimg Date: Mon, 14 Apr 2025 17:39:03 -0700 Subject: [PATCH 4/6] format --- src/MOI_wrapper.jl | 6 ++- src/constrained_variables.jl | 7 +++- src/dual_equality_constraints.jl | 49 ++++++++++++++++++----- src/dual_model_variables.jl | 15 +++++-- src/structures.jl | 24 ++++++++--- test/Tests/test_dualize_conic_linear.jl | 18 +++++---- test/Tests/test_dualize_quadratic.jl | 12 ++++-- test/Tests/test_partial_dual_linear.jl | 6 ++- test/Tests/test_partial_dual_quadratic.jl | 33 ++++++++++----- test/optimize_abstract_models.jl | 5 +-- 10 files changed, 124 insertions(+), 51 deletions(-) diff --git a/src/MOI_wrapper.jl b/src/MOI_wrapper.jl index 0586158c..870751c3 100644 --- a/src/MOI_wrapper.jl +++ b/src/MOI_wrapper.jl @@ -160,7 +160,8 @@ function MOI.modify( end vi = obj_change.variable if vi in keys(primal_dual_map.primal_convar_to_primal_convarcon_and_index) - ci_primal, index = primal_dual_map.primal_convar_to_primal_convarcon_and_index[vi] + ci_primal, index = + primal_dual_map.primal_convar_to_primal_convarcon_and_index[vi] ci_dual = primal_dual_map.primal_convarcon_to_dual_con[ci_primal] if ci_dual === NO_CONSTRAINT return @@ -329,7 +330,8 @@ function MOI.get( ) primal_dual_map = optimizer.dual_problem.primal_dual_map if vi in keys(primal_dual_map.primal_convar_to_primal_convarcon_and_index) - ci_primal, idx = primal_dual_map.primal_convar_to_primal_convarcon_and_index[vi] + ci_primal, idx = + primal_dual_map.primal_convar_to_primal_convarcon_and_index[vi] ci_dual = primal_dual_map.primal_convarcon_to_dual_con[ci_primal] return _get_at_index( optimizer, diff --git a/src/constrained_variables.jl b/src/constrained_variables.jl index e4517d83..e2aeb336 100644 --- a/src/constrained_variables.jl +++ b/src/constrained_variables.jl @@ -52,7 +52,9 @@ function _add_constrained_variables( if all( # no element of the VectorOfVariables is a constrained variable # and not a parameter - vi -> !haskey(m.primal_convar_to_primal_convarcon_and_index, vi) && !(vi in params), + vi -> + !haskey(m.primal_convar_to_primal_convarcon_and_index, vi) && + !(vi in params), f.variables, ) for (i, vi) in enumerate(f.variables) @@ -80,7 +82,8 @@ function _add_constrained_variable( f = MOI.get(primal_model, MOI.ConstraintFunction(), ci) # no element of the VectorOfVariables is a constrained variable # and not a parameter - if !haskey(m.primal_convar_to_primal_convarcon_and_index, f) && !(f in params) + if !haskey(m.primal_convar_to_primal_convarcon_and_index, f) && + !(f in params) set = MOI.get(primal_model, MOI.ConstraintSet(), ci) if !iszero(MOI.constant(set)) continue diff --git a/src/dual_equality_constraints.jl b/src/dual_equality_constraints.jl index 29d13a51..2718db38 100644 --- a/src/dual_equality_constraints.jl +++ b/src/dual_equality_constraints.jl @@ -80,7 +80,8 @@ function add_dual_equality_constraints( # Free variables for primal_vi in non_parameter_variables - if primal_vi in keys(primal_dual_map.primal_convar_to_primal_convarcon_and_index) + if primal_vi in + keys(primal_dual_map.primal_convar_to_primal_convarcon_and_index) continue # constrained variable end # Add equality constraint @@ -240,7 +241,10 @@ function add_scalar_affine_terms_from_quad_obj( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_var_in_quad_obj_to_dual_slack_var::Dict{MOI.VariableIndex,MOI.VariableIndex}, + primal_var_in_quad_obj_to_dual_slack_var::Dict{ + MOI.VariableIndex, + MOI.VariableIndex, + }, primal_objective::PrimalObjective{T}, sense_change::T, ) where {T} @@ -253,13 +257,15 @@ function add_scalar_affine_terms_from_quad_obj( dual_vi, ) else - dual_vi_1 = primal_var_in_quad_obj_to_dual_slack_var[term.variable_1] + dual_vi_1 = + primal_var_in_quad_obj_to_dual_slack_var[term.variable_1] push_to_scalar_affine_terms!( scalar_affine_terms[term.variable_2], -sense_change * MOI.coefficient(term), dual_vi_1, ) - dual_vi_2 = primal_var_in_quad_obj_to_dual_slack_var[term.variable_2] + dual_vi_2 = + primal_var_in_quad_obj_to_dual_slack_var[term.variable_2] push_to_scalar_affine_terms!( scalar_affine_terms[term.variable_1], -sense_change * MOI.coefficient(term), @@ -275,7 +281,10 @@ function add_scalar_affine_terms_from_quad_params( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_parameter_to_dual_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex}, + primal_parameter_to_dual_parameter::Dict{ + MOI.VariableIndex, + MOI.VariableIndex, + }, primal_objective::PrimalObjective{T}, sense_change::T, ) where {T} @@ -324,7 +333,10 @@ function fill_scalar_affine_terms!( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{ + MOI.ConstraintIndex, + Vector{MOI.VariableIndex}, + }, primal_model::MOI.ModelLike, ::Type{F}, ::Type{S}, @@ -342,7 +354,10 @@ end function get_scalar_affine_terms( primal_model::MOI.ModelLike, - primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{ + MOI.ConstraintIndex, + Vector{MOI.VariableIndex}, + }, variables::Vector{MOI.VariableIndex}, con_types::Vector{Tuple{Type,Type}}, ::Type{T}, @@ -379,7 +394,10 @@ function fill_scalar_affine_terms!( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{ + MOI.ConstraintIndex, + Vector{MOI.VariableIndex}, + }, primal_model::MOI.ModelLike, ci::MOI.ConstraintIndex{MOI.ScalarAffineFunction{T},S}, ) where {T,S<:Union{MOI.GreaterThan{T},MOI.LessThan{T},MOI.EqualTo{T}}} @@ -400,7 +418,10 @@ function fill_scalar_affine_terms!( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{ + MOI.ConstraintIndex, + Vector{MOI.VariableIndex}, + }, primal_model::MOI.ModelLike, ci::MOI.ConstraintIndex{MOI.VariableIndex,S}, ) where {T,S<:Union{MOI.GreaterThan{T},MOI.LessThan{T},MOI.EqualTo{T}}} @@ -426,7 +447,10 @@ function fill_scalar_affine_terms!( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{ + MOI.ConstraintIndex, + Vector{MOI.VariableIndex}, + }, primal_model::MOI.ModelLike, ci::MOI.ConstraintIndex{MOI.VectorAffineFunction{T},S}, ) where {T,S<:MOI.AbstractVectorSet} @@ -450,7 +474,10 @@ function fill_scalar_affine_terms!( MOI.VariableIndex, Vector{MOI.ScalarAffineTerm{T}}, }, - primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{ + MOI.ConstraintIndex, + Vector{MOI.VariableIndex}, + }, primal_model::MOI.ModelLike, ci::MOI.ConstraintIndex{MOI.VectorOfVariables,S}, ) where {T,S<:MOI.AbstractVectorSet} diff --git a/src/dual_model_variables.jl b/src/dual_model_variables.jl index 2437b3e5..01c54933 100644 --- a/src/dual_model_variables.jl +++ b/src/dual_model_variables.jl @@ -71,7 +71,10 @@ function push_to_primal_con_to_primal_constants_vec!( primal_con_to_primal_constants_vec::Dict{MOI.ConstraintIndex,Vector{T}}, ci::MOI.ConstraintIndex{F,S}, ) where {T,F<:MOI.AbstractScalarFunction,S<:MOI.AbstractScalarSet} - push!(primal_con_to_primal_constants_vec, ci => get_scalar_term(primal_model, ci)) + push!( + primal_con_to_primal_constants_vec, + ci => get_scalar_term(primal_model, ci), + ) return end @@ -136,7 +139,10 @@ function add_dual_variable( dual_model::MOI.ModelLike, primal_model::MOI.ModelLike, dual_names::DualNames, - primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}, + primal_con_to_dual_var_vec::Dict{ + MOI.ConstraintIndex, + Vector{MOI.VariableIndex}, + }, dual_obj_affine_terms::Dict{MOI.VariableIndex,T}, ci::MOI.ConstraintIndex{F,S}, ) where {T,F<:MOI.AbstractFunction,S<:MOI.AbstractSet} @@ -251,7 +257,10 @@ end # Save mapping between primal parameter and dual parameter function push_to_primal_parameter_to_dual_parameter!( - primal_parameter_to_dual_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex}, + primal_parameter_to_dual_parameter::Dict{ + MOI.VariableIndex, + MOI.VariableIndex, + }, vi::MOI.VariableIndex, vi_dual::MOI.VariableIndex, ) diff --git a/src/structures.jl b/src/structures.jl index 4390295d..75444158 100644 --- a/src/structures.jl +++ b/src/structures.jl @@ -113,19 +113,31 @@ Main maps: Future name: primal_var_in_quad_obj_to_dual_slack_var """ mutable struct PrimalDualMap{T} - primal_convar_to_primal_convarcon_and_index::Dict{MOI.VariableIndex,Tuple{MOI.ConstraintIndex,Int}} + primal_convar_to_primal_convarcon_and_index::Dict{ + MOI.VariableIndex, + Tuple{MOI.ConstraintIndex,Int}, + } primal_convarcon_to_dual_con::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex} primal_var_to_dual_con::Dict{MOI.VariableIndex,MOI.ConstraintIndex} - primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}} + primal_con_to_dual_var_vec::Dict{ + MOI.ConstraintIndex, + Vector{MOI.VariableIndex}, + } primal_con_to_dual_convarcon::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex} primal_con_to_primal_constants_vec::Dict{MOI.ConstraintIndex,Vector{T}} - primal_parameter_to_dual_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex} + primal_parameter_to_dual_parameter::Dict{ + MOI.VariableIndex, + MOI.VariableIndex, + } primal_convarcon_to_dual_function::Dict{ MOI.ConstraintIndex, Union{MOI.VectorAffineFunction{T},MOI.ScalarAffineFunction{T}}, } - primal_var_in_quad_obj_to_dual_slack_var::Dict{MOI.VariableIndex,MOI.VariableIndex} + primal_var_in_quad_obj_to_dual_slack_var::Dict{ + MOI.VariableIndex, + MOI.VariableIndex, + } function PrimalDualMap{T}() where {T} return new( @@ -179,7 +191,9 @@ function Base.getproperty(m::PrimalDualMap{T}, name::Symbol) where {T} end function is_empty(primal_dual_map::PrimalDualMap{T}) where {T} - return isempty(primal_dual_map.primal_convar_to_primal_convarcon_and_index) && + return isempty( + primal_dual_map.primal_convar_to_primal_convarcon_and_index, + ) && isempty(primal_dual_map.primal_convarcon_to_dual_con) && isempty(primal_dual_map.primal_convarcon_to_dual_function) && isempty(primal_dual_map.primal_var_to_dual_con) && diff --git a/test/Tests/test_dualize_conic_linear.jl b/test/Tests/test_dualize_conic_linear.jl index 141e3edd..e480e686 100644 --- a/test/Tests/test_dualize_conic_linear.jl +++ b/test/Tests/test_dualize_conic_linear.jl @@ -81,7 +81,8 @@ for i in 1:3 vi = MOI.VariableIndex(i) @test !haskey(primal_dual_map.primal_var_to_dual_con, vi) - @test primal_dual_map.primal_convar_to_primal_convarcon_and_index[vi] == (ci_nneg, i) + @test primal_dual_map.primal_convar_to_primal_convarcon_and_index[vi] == + (ci_nneg, i) end end @@ -234,11 +235,14 @@ vi = MOI.VariableIndex(i) @test !haskey(primal_var_to_dual_con, vi) end - @test primal_dual_map.primal_convar_to_primal_convarcon_and_index[MOI.VariableIndex(2)] == - (ci_npos, 1) - @test primal_dual_map.primal_convar_to_primal_convarcon_and_index[MOI.VariableIndex(3)] == - (ci_nneg, 1) - @test primal_dual_map.primal_convar_to_primal_convarcon_and_index[MOI.VariableIndex(4)] == - (ci_zero, 1) + @test primal_dual_map.primal_convar_to_primal_convarcon_and_index[MOI.VariableIndex( + 2, + )] == (ci_npos, 1) + @test primal_dual_map.primal_convar_to_primal_convarcon_and_index[MOI.VariableIndex( + 3, + )] == (ci_nneg, 1) + @test primal_dual_map.primal_convar_to_primal_convarcon_and_index[MOI.VariableIndex( + 4, + )] == (ci_zero, 1) end end diff --git a/test/Tests/test_dualize_quadratic.jl b/test/Tests/test_dualize_quadratic.jl index 7228f451..ee6187ef 100644 --- a/test/Tests/test_dualize_quadratic.jl +++ b/test/Tests/test_dualize_quadratic.jl @@ -139,26 +139,30 @@ )] == [MOI.VariableIndex(2)] primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con - @test primal_var_to_dual_con[MOI.VariableIndex(1)] == MOI.ConstraintIndex{ + @test primal_var_to_dual_con[MOI.VariableIndex(1)] == + MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( 1, ) - @test primal_var_to_dual_con[MOI.VariableIndex(2)] == MOI.ConstraintIndex{ + @test primal_var_to_dual_con[MOI.VariableIndex(2)] == + MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( 2, ) - @test primal_var_to_dual_con[MOI.VariableIndex(3)] == MOI.ConstraintIndex{ + @test primal_var_to_dual_con[MOI.VariableIndex(3)] == + MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( 3, ) - primal_var_in_quad_obj_to_dual_slack_var = primal_dual_map.primal_var_in_quad_obj_to_dual_slack_var + 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)] == MOI.VariableIndex(2 + 1) @test primal_var_in_quad_obj_to_dual_slack_var[MOI.VariableIndex(2)] == diff --git a/test/Tests/test_partial_dual_linear.jl b/test/Tests/test_partial_dual_linear.jl index 4451b759..b5302b13 100644 --- a/test/Tests/test_partial_dual_linear.jl +++ b/test/Tests/test_partial_dual_linear.jl @@ -90,7 +90,8 @@ )] == [MOI.VariableIndex(1)] primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con - @test primal_var_to_dual_con[MOI.VariableIndex(1)] == MOI.ConstraintIndex{ + @test primal_var_to_dual_con[MOI.VariableIndex(1)] == + MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( @@ -286,7 +287,8 @@ )] == [MOI.VariableIndex(1)] primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con - @test primal_var_to_dual_con[MOI.VariableIndex(2)] == MOI.ConstraintIndex{ + @test primal_var_to_dual_con[MOI.VariableIndex(2)] == + MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( diff --git a/test/Tests/test_partial_dual_quadratic.jl b/test/Tests/test_partial_dual_quadratic.jl index 60a27c26..6c47482c 100644 --- a/test/Tests/test_partial_dual_quadratic.jl +++ b/test/Tests/test_partial_dual_quadratic.jl @@ -120,23 +120,28 @@ )] == [MOI.VariableIndex(2)] primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con - @test primal_var_to_dual_con[MOI.VariableIndex(1)] == MOI.ConstraintIndex{ + @test primal_var_to_dual_con[MOI.VariableIndex(1)] == + MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( 1, ) - @test primal_var_to_dual_con[MOI.VariableIndex(2)] == MOI.ConstraintIndex{ + @test primal_var_to_dual_con[MOI.VariableIndex(2)] == + MOI.ConstraintIndex{ MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, }( 2, ) - primal_parameter_to_dual_parameter = primal_dual_map.primal_parameter_to_dual_parameter - @test primal_parameter_to_dual_parameter[MOI.VariableIndex(3)] == MOI.VariableIndex(2 + 1) + primal_parameter_to_dual_parameter = + primal_dual_map.primal_parameter_to_dual_parameter + @test primal_parameter_to_dual_parameter[MOI.VariableIndex(3)] == + MOI.VariableIndex(2 + 1) - primal_var_in_quad_obj_to_dual_slack_var = primal_dual_map.primal_var_in_quad_obj_to_dual_slack_var + 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)] == MOI.VariableIndex(2 + 1 + 1) @test primal_var_in_quad_obj_to_dual_slack_var[MOI.VariableIndex(2)] == @@ -239,10 +244,13 @@ primal_var_to_dual_con = primal_dual_map.primal_var_to_dual_con @test isempty(primal_var_to_dual_con) - primal_parameter_to_dual_parameter = primal_dual_map.primal_parameter_to_dual_parameter - @test primal_parameter_to_dual_parameter[MOI.VariableIndex(2)] == MOI.VariableIndex(3) + primal_parameter_to_dual_parameter = + primal_dual_map.primal_parameter_to_dual_parameter + @test primal_parameter_to_dual_parameter[MOI.VariableIndex(2)] == + MOI.VariableIndex(3) - primal_var_in_quad_obj_to_dual_slack_var = primal_dual_map.primal_var_in_quad_obj_to_dual_slack_var + 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)] == MOI.VariableIndex(4) end @@ -342,10 +350,13 @@ @test isempty(primal_dual_map.primal_var_to_dual_con) - primal_parameter_to_dual_parameter = primal_dual_map.primal_parameter_to_dual_parameter - @test primal_parameter_to_dual_parameter[MOI.VariableIndex(2)] == MOI.VariableIndex(3) + primal_parameter_to_dual_parameter = + primal_dual_map.primal_parameter_to_dual_parameter + @test primal_parameter_to_dual_parameter[MOI.VariableIndex(2)] == + MOI.VariableIndex(3) - primal_var_in_quad_obj_to_dual_slack_var = primal_dual_map.primal_var_in_quad_obj_to_dual_slack_var + 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)] == MOI.VariableIndex(4) end diff --git a/test/optimize_abstract_models.jl b/test/optimize_abstract_models.jl index 1c4b5e9b..04823c6b 100644 --- a/test/optimize_abstract_models.jl +++ b/test/optimize_abstract_models.jl @@ -7,10 +7,7 @@ Attach an MOI.ModelLike to an optimizer, solve it and retrieve the termination status and objective value """ -function solve_abstract_model( - model::MOI.ModelLike, - optimizer_constructor, -) +function solve_abstract_model(model::MOI.ModelLike, optimizer_constructor) JuMP_model = JuMP.Model() MOI.copy_to(JuMP.backend(JuMP_model), model) set_optimizer(JuMP_model, optimizer_constructor) From 91c35fc0888a09b57cd79451501f35dc51f62c85 Mon Sep 17 00:00:00 2001 From: joaquimg Date: Mon, 14 Apr 2025 17:47:14 -0700 Subject: [PATCH 5/6] format --- src/dual_equality_constraints.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dual_equality_constraints.jl b/src/dual_equality_constraints.jl index e396601e..76b13a0b 100644 --- a/src/dual_equality_constraints.jl +++ b/src/dual_equality_constraints.jl @@ -80,7 +80,10 @@ function add_dual_equality_constraints( # Free variables for primal_vi in non_parameter_variables - if haskey(primal_dual_map.primal_convar_to_primal_convarcon_and_index, primal_vi) + if haskey( + primal_dual_map.primal_convar_to_primal_convarcon_and_index, + primal_vi, + ) continue # constrained variable end # Add equality constraint From 3b7b910a037aa9a28c282a082ed261fd4f8607cb Mon Sep 17 00:00:00 2001 From: joaquimg Date: Mon, 14 Apr 2025 19:18:34 -0700 Subject: [PATCH 6/6] more info --- src/dual_model_variables.jl | 2 +- src/structures.jl | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/dual_model_variables.jl b/src/dual_model_variables.jl index 01c54933..9fbc6c8c 100644 --- a/src/dual_model_variables.jl +++ b/src/dual_model_variables.jl @@ -13,7 +13,7 @@ function _add_dual_vars_in_dual_cones( ::Type{S}, ) where {T,F,S} for ci in MOI.get(primal_model, MOI.ListOfConstraintIndices{F,S}()) - # If `F` not one of these two, we can skip the `in` check. + # If `F` not one of these two, we can skip the `haskey` check. if (F === MOI.VectorOfVariables || F === MOI.VariableIndex) && haskey(primal_dual_map.primal_convarcon_to_dual_con, ci) continue diff --git a/src/structures.jl b/src/structures.jl index 75444158..5b5c7710 100644 --- a/src/structures.jl +++ b/src/structures.jl @@ -75,27 +75,32 @@ Main maps: * `primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}`: maps primal constraint indices to vectors of dual variable indices. For scalar constraints those vectors will be single element vectors. - Primal Constrained variables constraints (the main ones) are not in this - map. + Primal constrained variables constraints (the main ones) are not in this + map. However, `VariableIndex`-in-set and `VectorOfVariables`-in-set might + appear in this map if they were not chosen as the main ones. - note: possibly change this to + note: possibly change this to: + primal_con_to_dual_var_vec_and_convarcon - * `primal_con_to_dual_convarcon::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}`: maps - primal constraints to dual constrained variable. If the primal + * `primal_con_to_dual_convarcon::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}`: + maps regular primal constraints to dual constrained variable. If the primal constraint's set is EqualTo or Zeros, no constraint is added in the dual variable (the dual variable is said to be free). + Primal constrained variables constraints (the main ones) are not in this + map. However, `VariableIndex`-in-set and `VectorOfVariables`-in-set might + appear in this map if they were not chosen as the main ones. The keys are similar to the (# primal_con_to_dual_var_vec) map, except that `VariableIndex`-in-`EqualTo(zero(T))` and `VectorOfVariables`-in-`Zeros` - are not in this map. + are not in this map, as the dual constraint would belong to the `Reals` set, + and would be innocuous (hence, not added). Additional helper maps: * `primal_con_to_primal_constants_vec::Dict{MOI.ConstraintIndex,Vector{T}}`: maps primal constraints to their respective constants, which might be inside the set. This map is used in `MOI.get(::DualOptimizer,::MOI.ConstraintPrimal,ci)` - that requires extra information in the case that the scalar set constrains + that requires extra information in the case that the scalar set constains a constant (`EqualtTo`, `GreaterThan`, `LessThan`). - # TODO is the vec ever really used??? * `primal_parameter_to_dual_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex}`: maps parameters in the primal to parameters in the dual model.