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..029198d3 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). + Future name: 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). + Future name: 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. + 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}}`: 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 - 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. + Future name: 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`). + 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. + 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 + 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}`: maps primal variables (that appear in quadratic objective terms) to dual - "slack" variables. + "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}}