Skip to content

Commit 90f26cf

Browse files
committed
add docs, fix names and add errors
1 parent ff44c11 commit 90f26cf

File tree

7 files changed

+145
-130
lines changed

7 files changed

+145
-130
lines changed

docs/src/reference.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@
44
Dualization.supported_constraints
55
Dualization.supported_objective
66
Dualization.DualNames
7+
Dualization.VariableData
8+
Dualization.ConstraintData
9+
Dualization.PrimalDualMap
710
```

src/MOI_wrapper.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ function MOI.get(
282282
ci_dual = primal_dual_map.primal_variable_data[vi].dual_constraint
283283
if ci_dual === nothing
284284
return MOI.Utilities.eval_variables(
285-
primal_dual_map.primal_variable_data[vi].primal_function,
285+
primal_dual_map.primal_variable_data[vi].dual_function,
286286
) do inner_vi
287287
return MOI.get(
288288
optimizer.dual_problem.dual_model,
@@ -322,7 +322,7 @@ function MOI.get(
322322
if ci_dual === nothing
323323
return [
324324
MOI.Utilities.eval_variables(
325-
primal_dual_map.primal_variable_data[vi].primal_function,
325+
primal_dual_map.primal_variable_data[vi].dual_function,
326326
) do inner_vi
327327
return MOI.get(
328328
optimizer.dual_problem.dual_model,

src/dual_equality_constraints.jl

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,9 @@ function _add_dual_equality_constraints(
8181

8282
# Free variables
8383
for primal_vi in non_parameter_variables
84-
if is_constrained(primal_dual_map, primal_vi)
85-
# haskey(
86-
# primal_dual_map.primal_convar_to_primal_convarcon_and_index,
87-
# primal_vi,
88-
# )
84+
data = get(primal_dual_map.primal_variable_data, primal_vi, nothing)
85+
if data !== nothing &&
86+
data.primal_constrained_variable_constraint !== nothing
8987
continue # constrained variable
9088
end
9189
# Add equality constraint
@@ -136,12 +134,12 @@ function _add_constrained_variable_constraint(
136134
# to not adding any constraint.
137135
vis = primal_dual_map.primal_constrained_variables[ci]
138136
for (i, vi) in enumerate(vis)
139-
primal_function = MOI.ScalarAffineFunction(
137+
dual_function = MOI.ScalarAffineFunction(
140138
MOI.Utilities.operate_terms(-, scalar_affine_terms[vi]),
141139
sense_change * get(scalar_terms, vi, zero(T)),
142140
)
143141
primal_dual_map.primal_variable_data[vi] =
144-
VariableData{T}(ci, i, nothing, primal_function)
142+
VariableData{T}(ci, i, nothing, dual_function)
145143
end
146144
return
147145
end
@@ -196,12 +194,12 @@ function _add_constrained_variable_constraint(
196194
) where {T}
197195
vi = primal_dual_map.primal_constrained_variables[ci][]
198196
# Nothing to add as the set is `EqualTo`.
199-
primal_function = MOI.ScalarAffineFunction(
197+
dual_function = MOI.ScalarAffineFunction(
200198
MOI.Utilities.operate_terms(-, scalar_affine_terms[vi]),
201199
sense_change * get(scalar_terms, vi, zero(T)),
202200
)
203201
primal_dual_map.primal_variable_data[vi] =
204-
VariableData{T}(ci, 0, nothing, primal_function)
202+
VariableData{T}(ci, 0, nothing, dual_function)
205203
return
206204
end
207205

src/structures.jl

Lines changed: 129 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -26,48 +26,68 @@ MOI.Utilities.@model(
2626
)
2727

2828
"""
29+
VariableData{T}
30+
31+
Data structure used in `PrimalDualMap` to hold information about primal
32+
variables and their dual counterparts.
33+
34+
* `primal_constrained_variable_constraint::Union{Nothing,MOI.ConstraintIndex}`:
35+
if primal variable is chosen to be a constrained variable by
36+
Dualization.jl, then this value is different from nothing.
37+
38+
* `primal_constrained_variable_index::Int`: if variable is a scalar
39+
constrained variable then it is 0. If variable is not a constrained variable
40+
then it is -1. If variable is part of a vector constrained variable, then
41+
this is the position in that vector.
42+
43+
* `dual_constraint::Union{Nothing,MOI.ConstraintIndex}`: dual constraint
44+
associated with the variable. If the variable is not constrained then the
45+
set is EqualTo{T}(zero(T)). If the variable is a constrained variable then
46+
the set is the dual set of the constrained variable set. If the dual set is
47+
`Reals` then the field is kept as `nothing` as teh constraint is not added.
48+
49+
* `dual_function::Union{Nothing,MOI.ScalarAffineFunction{T}}`: if the
50+
constrained variable is `VectorOfVariables`-in-`Zeros` or
51+
`VariableIndex`-in-`EqualTo(zero(T))` then the dual is `func`-in-`Reals`,
52+
which is "irrelevant" to the model. But this information is cached for
53+
completeness of the `DualOptimizer` for `get`ting `ConstraintDuals`.
54+
55+
To got from the constrained variable constraint to the primal variable, use the
56+
`primal_constrained_variables` field of `PrimalDualMap`.
2957
58+
See also `PrimalDualMap` and `ConstraintData`.
3059
"""
3160
struct VariableData{T}
32-
# if primal variable is chosen to be a constrained variable by
33-
# Dualization.jl, then this value is different from nothing
3461
primal_constrained_variable_constraint::Union{Nothing,MOI.ConstraintIndex}
35-
# if variable is a scalar constrained variable then it is 0
36-
# if variable is not a constrained variable then it is -1
37-
# if variable is part of a vector constrained variable, the this is the
38-
# position in that vector
3962
primal_constrained_variable_index::Int
40-
# dual constraint associated with the variable
41-
# if the variable is not constrained then the set is EqualTo
42-
# if the variable is a constrained variable then the set is the dual set
43-
# of the constrained variable set
44-
# if the dual set is Reals then the field is kept as `nothing`
4563
dual_constraint::Union{Nothing,MOI.ConstraintIndex}
46-
# if the constrained variable is:
47-
# * `VectorOfVariables`-in-`Zeros`
48-
# * `VariableIndex`-in-`EqualTo(zero(T))`
49-
# then the dual is `func`-in-`Reals`, which is "irrelevant" to the model.
50-
# But this information is cached for completeness of the `DualOptimizer` for
51-
# `get`ting `ConstraintDuals`.
52-
primal_function::Union{
53-
Nothing,
54-
MOI.ScalarAffineFunction{T},
55-
# MOI.VectorAffineFunction{T},
56-
}
64+
dual_function::Union{Nothing,MOI.ScalarAffineFunction{T}}
5765
end
5866

5967
# constraints of primal constrained variables are not here
6068
"""
69+
ConstraintData{T}
70+
71+
Data structure used in `PrimalDualMap` to hold information about primal
72+
constraints and their dual counterparts.
73+
74+
Constraint indices for constrained variables are not in this structure. They are
75+
added in the `primal_constrained_variables` field of `PrimalDualMap`.
76+
77+
* `primal_set_constants::Vector{T}`: a vector of primal set constants that are
78+
used in MOI getters. This is used to get the primal constants of the primal
79+
constraints.
6180
81+
* `dual_variables::Vector{MOI.VariableIndex}`: vector of dual variables. If
82+
primal constraint is scalar then, the vector has length = 1.
83+
84+
* `dual_constrained_variable_constraint::Union{Nothing,MOI.ConstraintIndex}`:
85+
if primal set is `EqualTo` or `Zeros`, then the dual constraint is `Reals`
86+
then the dual variable is free (no constraint in the dual model).
6287
"""
6388
struct ConstraintData{T}
64-
# a vector of primal set constants that are used in MOI getters
6589
primal_set_constants::Vector{T}
66-
# vector of dual variables
67-
# if primal constraint is scalar then, the vector has length = 1
6890
dual_variables::Vector{MOI.VariableIndex}
69-
# if primal set is `EqualTo` or `Zeros`, then the dual constraint is `Reals`
70-
# then the dual variable is free (no constraint in the dual model)
7191
dual_constrained_variable_constraint::Union{Nothing,MOI.ConstraintIndex}
7292
end
7393

@@ -79,74 +99,26 @@ Maps information from all structures of the primal to the dual model.
7999
Main maps:
80100
81101
* `primal_variable_data::Dict{MOI.VariableIndex,Dualization.VariableData{T}}`:
82-
102+
maps primal variable indices to their data. The data is a structure that
103+
contains information about the primal variable and its dual counterpart.
104+
In particular, it contains the primal constrained variable constraint index,
105+
the primal constrained variable index, the dual constraint index and the
106+
primal function for the case of constraints that are not added in the dual.
83107
84-
The following abbreviations are used in the maps:
108+
* `primal_constraint_data::Dict{MOI.ConstraintIndex,Dualization.ConstraintData{T}}`:
109+
maps primal constraint indices to their data. The data is a structure that
110+
contains information about the primal constraint and its dual counterpart.
111+
In particular, it contains the primal set constants, the dual variables and
112+
the dual constrained variable constraint index.
85113
86-
* `var`: variable index
87-
* `con`: constraint index
88-
* `convar`: constrained variable, variable index
89-
* `convarcon`: constrained variable, constraint index
114+
* `primal_constrained_variables::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}`:
115+
maps primal constrained variable constraint indices to their primal
116+
constrained variables.
90117
91-
Main maps:
118+
Addtional maps
92119
93-
* `primal_convar_to_primal_convarcon_and_index::Dict{MOI.VariableIndex,Tuple{MOI.ConstraintIndex,Int}}`:
94-
maps primal constrained variables to their primal
95-
constraints (the special ones that makes them constrained variables) and
96-
their internal index from 1 to dimension(set) (if vector constraints:
97-
VectorOfVariables-in-Set), 1 otherwise (scalar: VariableIndex-in-Set).
98-
99-
INCOMPLE: needs primal_ci to primal_vi_vec
100-
* `primal_convarcon_to_dual_con::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}`: maps
101-
the primal constraint index of constrained variables to the dual
102-
model's constraint index of the associated dual constraint. This dual
103-
constraint is a regular constraint (not a constrained variable constraint).
104-
`VectorOfVariables`-in-`Zeros` and `VariableIndex`-in-`EqualTo(zero(T))`
105-
are not in this map, as they are not dualized (See
106-
primal_convarcon_to_dual_function).
107-
108-
* `primal_var_to_dual_con::Dict{MOI.VariableIndex,MOI.ConstraintIndex}`: maps
109-
"free" primal variables to their associated dual (equality) constraints.
110-
Free variables as opposed to constrained variables. Note that Dualization
111-
will select automatically which variables are free and which are
112-
constrained.
113-
114-
* `primal_con_to_dual_var_vec::Dict{MOI.ConstraintIndex,Vector{MOI.VariableIndex}}`:
115-
maps primal constraint indices to vectors of dual variable indices. For
116-
scalar constraints those vectors will be single element vectors.
117-
Primal constrained variables constraints (the main ones) are not in this
118-
map. However, `VariableIndex`-in-set and `VectorOfVariables`-in-set might
119-
appear in this map if they were not chosen as the main ones.
120-
121-
* `primal_con_to_dual_convarcon::Dict{MOI.ConstraintIndex,MOI.ConstraintIndex}`:
122-
maps regular primal constraints to dual constrained variable. If the primal
123-
constraint's set is EqualTo or Zeros, no constraint is added in the dual
124-
variable (the dual variable is said to be free).
125-
Primal constrained variables constraints (the main ones) are not in this
126-
map. However, `VariableIndex`-in-set and `VectorOfVariables`-in-set might
127-
appear in this map if they were not chosen as the main ones.
128-
The keys are similar to the (# primal_con_to_dual_var_vec) map, except
129-
that `VariableIndex`-in-`EqualTo(zero(T))` and `VectorOfVariables`-in-`Zeros`
130-
are not in this map, as the dual constraint would belong to the `Reals` set,
131-
and would be innocuous (hence, not added).
132-
133-
Additional helper maps:
134-
135-
* `primal_con_to_primal_constants_vec::Dict{MOI.ConstraintIndex,Vector{T}}`: maps primal
136-
constraints to their respective constants, which might be inside the set.
137-
This map is used in `MOI.get(::DualOptimizer,::MOI.ConstraintPrimal,ci)`
138-
that requires extra information in the case that the scalar set constains
139-
a constant (`EqualtTo`, `GreaterThan`, `LessThan`).
140-
141-
* `primal_parameter_to_dual_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex}`: maps
142-
parameters in the primal to parameters in the dual model.
143-
144-
* `primal_convarcon_to_dual_function::Dict{MOI.ConstraintIndex,Union{MOI.ScalarAffineFunction,MOI.VectorAffineFunction}}`:
145-
caches scalar affine functions or vector affine functions associated with
146-
constrained variables of type `VectorOfVariables`-in-`Zeros` or
147-
`VariableIndex`-in-`EqualTo(zero(T))` as their duals would be `func`-in-`Reals`,
148-
which are "irrelevant" to the model. This information is cached for
149-
completeness of the `DualOptimizer` for `get`ting `ConstraintDuals`.
120+
* `primal_parameter_to_dual_parameter::Dict{MOI.VariableIndex,MOI.VariableIndex}`:
121+
maps parameters in the primal model to parameters in the dual model.
150122
151123
* `primal_var_in_quad_obj_to_dual_slack_var::Dict{MOI.VariableIndex,MOI.VariableIndex}`:
152124
maps primal variables (that appear in quadratic objective terms) to dual
@@ -179,40 +151,82 @@ mutable struct PrimalDualMap{T}
179151
end
180152
end
181153

182-
function is_constrained(map::PrimalDualMap, vi::MOI.VariableIndex)
183-
data = get(map.primal_variable_data, vi, nothing)
184-
if data !== nothing &&
185-
data.primal_constrained_variable_constraint !== nothing
186-
return true
187-
end
188-
return false
189-
end
190-
191154
function Base.getproperty(m::PrimalDualMap{T}, name::Symbol) where {T}
192155
if name === :constrained_var_idx
193-
@warn "constrained_var_idx field is deprecated, use primal_convar_to_primal_convarcon_and_index instead"
194-
return getfield(m, :primal_convar_to_primal_convarcon_and_index)
156+
error(
157+
"""
158+
Field `constrained_var_idx` was removed.
159+
From a primal variable index, use the field `primal_variable_data`.
160+
In the data structures returned the constraint can be found at
161+
`primal_constrained_variable_constraint` and the index at
162+
`primal_constrained_variable_index`.
163+
"""
164+
)
195165
elseif name === :constrained_var_dual
196-
@warn "constrained_var_dual field is deprecated, use primal_convarcon_to_dual_con instead"
197-
return getfield(m, :primal_convarcon_to_dual_con)
166+
error(
167+
"""
168+
Field `constrained_var_dual` was removed.
169+
From a primal constrained variable constraint index, use the field
170+
`primal_constrained_variables` to obtain the primal varaibles.
171+
Then, from the primal variable index, use the field
172+
`primal_variable_data`.
173+
In the data structures returned, the constraint can be found at
174+
`dual_constraint`.
175+
"""
176+
)
198177
elseif name === :primal_var_dual_con
199-
@warn "primal_var_dual_con field is deprecated, use primal_var_to_dual_con instead"
200-
return getfield(m, :primal_var_to_dual_con)
178+
error(
179+
"""
180+
Field `primal_var_dual_con` was removed.
181+
From a primal variable index, use the field `primal_variable_data`.
182+
In the data structures returned, the constraint can be found at
183+
`dual_constraint`.
184+
"""
185+
)
201186
elseif name === :primal_con_dual_var
202-
@warn "primal_con_dual_var field is deprecated, use primal_con_to_dual_var_vec instead"
203-
return getfield(m, :primal_con_to_dual_var_vec)
187+
error(
188+
"""
189+
Field `primal_con_dual_var` was removed.
190+
From a primal constraint index, use the field
191+
`primal_constraint_data`.
192+
In the data structure returned, the dual variables can be found at
193+
`dual_varaibles`.
194+
"""
195+
)
204196
elseif name === :primal_con_dual_con
205-
@warn "primal_con_dual_con field is deprecated, use primal_con_to_dual_convarcon instead"
206-
return getfield(m, :primal_con_to_dual_convarcon)
197+
error(
198+
"""
199+
Field `primal_con_dual_con` was removed.
200+
From a primal constraint index, use the field
201+
`primal_constraint_data`.
202+
In the data structure returned, the dual constrained variable
203+
constraint can be found at `dual_constrained_variable_constraint`.
204+
"""
205+
)
207206
elseif name === :primal_con_constants
208-
@warn "primal_con_constants field is deprecated, use primal_con_to_primal_constants_vec instead"
209-
return getfield(m, :primal_con_to_primal_constants_vec)
207+
error(
208+
"""
209+
Field `primal_con_constants` was removed.
210+
From a primal constraint index, use the field `primal_constraint_data`.
211+
In the data structure returned, the primal set constants can be found
212+
at `primal_set_constants`.
213+
"""
214+
)
215+
elseif name === :constrained_var_zero
216+
error(
217+
"""
218+
Field `constrained_var_zero` was removed.
219+
From a primal constrained variable constraint index, use the field
220+
`primal_constrained_variables` to obtain the primal varaibles.
221+
Then, from the primal variable index, use the field
222+
`primal_variable_data`.
223+
In the data structure returned, the primal function can be found at
224+
`dual_function`.
225+
"""
226+
)
210227
elseif name === :primal_parameter
211228
@warn "primal_parameter field is deprecated, use primal_parameter_to_dual_parameter instead"
212229
return getfield(m, :primal_parameter_to_dual_parameter)
213-
elseif name === :constrained_var_zero
214-
@warn "constrained_var_zero field is deprecated, use primal_convarcon_to_dual_function instead"
215-
return getfield(m, :primal_convarcon_to_dual_function)
216230
elseif name === :primal_var_dual_quad_slack
217231
@warn "primal_var_dual_quad_slack field is deprecated, use primal_var_in_quad_obj_to_dual_slack_var instead"
218232
return getfield(m, :primal_var_in_quad_obj_to_dual_slack_var)

test/Tests/test_dualize_conic_linear.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
@test data.primal_constrained_variable_constraint == ci_nneg
8989
@test data.primal_constrained_variable_index == i
9090
@test data.dual_constraint == ci
91-
@test data.primal_function === nothing
91+
@test data.dual_function === nothing
9292
end
9393
end
9494

test/Tests/test_partial_dual_linear.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@
193193
@test data.primal_constrained_variable_constraint == vgt2
194194
@test data.primal_constrained_variable_index == 0
195195
@test data.dual_constraint !== nothing
196-
@test data.primal_function === nothing
196+
@test data.dual_function === nothing
197197
end
198198
end
199199

0 commit comments

Comments
 (0)