Skip to content

Commit ff44c11

Browse files
committed
Complete restructure of PrimalDualMap
1 parent c2a4f45 commit ff44c11

17 files changed

+376
-408
lines changed

src/MOI_wrapper.jl

Lines changed: 59 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -159,23 +159,13 @@ function MOI.modify(
159159
constant = -constant
160160
end
161161
vi = obj_change.variable
162-
# if haskey(primal_dual_map.primal_convar_to_primal_convarcon_and_index, vi)
163-
# ci_primal, index =
164-
# primal_dual_map.primal_convar_to_primal_convarcon_and_index[vi]
165-
# ci_dual = primal_dual_map.primal_convarcon_to_dual_con[ci_primal]
166-
# if ci_dual === NO_CONSTRAINT
167-
# return
168-
# end
169-
# constant = -constant
170-
# else
171-
# ci_dual = primal_dual_map.primal_var_to_dual_con[vi]
172-
# index = 1
173-
# end
174162
data = get(primal_dual_map.primal_variable_data, vi, nothing)
175163
if data === nothing
176164
# error
177-
elseif data.dual_constraint == NO_CONSTRAINT
165+
elseif data.dual_constraint === nothing
178166
return
167+
elseif data.primal_constrained_variable_constraint !== nothing
168+
constant = -constant
179169
end
180170
_change_constant(
181171
optimizer.dual_problem.dual_model,
@@ -257,53 +247,28 @@ function MOI.get(
257247
data = get(primal_dual_map.primal_variable_data, vi, nothing)
258248
if data === nothing
259249
# error
260-
elseif data.dual_constraint == NO_CONSTRAINT
250+
elseif data.dual_constraint === nothing
261251
return zero(T)
262252
elseif data.primal_constrained_variable_constraint === nothing
263253
return -MOI.get(
264254
optimizer.dual_problem.dual_model,
265255
MOI.ConstraintDual(),
266-
primal_dual_map.primal_var_to_dual_con[vi],
256+
data.dual_constraint,
267257
)
268-
elseif data.dual_constraint isa MOI.ConstraintIndex{<:MOI.AbstractVectorFunction}
258+
elseif data.dual_constraint isa
259+
MOI.ConstraintIndex{<:MOI.AbstractVectorFunction}
269260
return MOI.get(
270-
optimizer.dual_problem.dual_model,
271-
MOI.ConstraintDual(),
272-
data.dual_constraint,
273-
)[data.primal_constrained_variable_index]
261+
optimizer.dual_problem.dual_model,
262+
MOI.ConstraintDual(),
263+
data.dual_constraint,
264+
)[data.primal_constrained_variable_index]
274265
else
275266
return MOI.get(
276-
optimizer.dual_problem.dual_model,
277-
MOI.ConstraintDual(),
278-
ci_dual,
279-
)
267+
optimizer.dual_problem.dual_model,
268+
MOI.ConstraintDual(),
269+
data.dual_constraint,
270+
)
280271
end
281-
# if haskey(primal_dual_map.primal_convar_to_primal_convarcon_and_index, vi)
282-
# ci_primal, idx =
283-
# primal_dual_map.primal_convar_to_primal_convarcon_and_index[vi]
284-
# ci_dual = primal_dual_map.primal_convarcon_to_dual_con[ci_primal]
285-
# if ci_dual === NO_CONSTRAINT
286-
# return zero(T)
287-
# elseif ci_dual isa MOI.ConstraintIndex{<:MOI.AbstractVectorFunction}
288-
# return MOI.get(
289-
# optimizer.dual_problem.dual_model,
290-
# MOI.ConstraintDual(),
291-
# ci_dual,
292-
# )[idx]
293-
# else
294-
# return MOI.get(
295-
# optimizer.dual_problem.dual_model,
296-
# MOI.ConstraintDual(),
297-
# ci_dual,
298-
# )
299-
# end
300-
# else
301-
# return -MOI.get(
302-
# optimizer.dual_problem.dual_model,
303-
# MOI.ConstraintDual(),
304-
# primal_dual_map.primal_var_to_dual_con[vi],
305-
# )
306-
# end
307272
end
308273

309274
function MOI.get(
@@ -312,16 +277,17 @@ function MOI.get(
312277
ci::MOI.ConstraintIndex{F,S},
313278
) where {F<:MOI.AbstractScalarFunction,S<:MOI.AbstractScalarSet}
314279
primal_dual_map = optimizer.dual_problem.primal_dual_map
315-
if haskey(primal_dual_map.primal_convarcon_to_dual_con, ci)
316-
ci_dual = primal_dual_map.primal_convarcon_to_dual_con[ci]
317-
if ci_dual === NO_CONSTRAINT
280+
if haskey(primal_dual_map.primal_constrained_variables, ci)
281+
vi = primal_dual_map.primal_constrained_variables[ci][]
282+
ci_dual = primal_dual_map.primal_variable_data[vi].dual_constraint
283+
if ci_dual === nothing
318284
return MOI.Utilities.eval_variables(
319-
primal_dual_map.primal_convarcon_to_dual_function[ci],
320-
) do vi
285+
primal_dual_map.primal_variable_data[vi].primal_function,
286+
) do inner_vi
321287
return MOI.get(
322288
optimizer.dual_problem.dual_model,
323289
MOI.VariablePrimal(),
324-
vi,
290+
inner_vi,
325291
)
326292
end
327293
end
@@ -339,7 +305,7 @@ function MOI.get(
339305
return MOI.get(
340306
optimizer.dual_problem.dual_model,
341307
MOI.VariablePrimal(),
342-
primal_dual_map.primal_con_to_dual_var_vec[ci][],
308+
primal_dual_map.primal_constraint_data[ci].dual_variables[],
343309
)
344310
end
345311
end
@@ -350,29 +316,32 @@ function MOI.get(
350316
ci::MOI.ConstraintIndex{F,S},
351317
) where {F<:MOI.AbstractVectorFunction,S<:MOI.AbstractVectorSet}
352318
primal_dual_map = optimizer.dual_problem.primal_dual_map
353-
if haskey(primal_dual_map.primal_convarcon_to_dual_con, ci)
354-
ci_dual = primal_dual_map.primal_convarcon_to_dual_con[ci]
355-
if ci_dual === NO_CONSTRAINT
356-
return MOI.Utilities.eval_variables(
357-
primal_dual_map.primal_convarcon_to_dual_function[ci],
358-
) do vi
359-
return MOI.get(
360-
optimizer.dual_problem.dual_model,
361-
MOI.VariablePrimal(),
362-
vi,
363-
)
364-
end
319+
if !haskey(primal_dual_map.primal_constraint_data, ci)
320+
vis = primal_dual_map.primal_constrained_variables[ci]
321+
ci_dual = primal_dual_map.primal_variable_data[vis[1]].dual_constraint
322+
if ci_dual === nothing
323+
return [
324+
MOI.Utilities.eval_variables(
325+
primal_dual_map.primal_variable_data[vi].primal_function,
326+
) do inner_vi
327+
return MOI.get(
328+
optimizer.dual_problem.dual_model,
329+
MOI.VariablePrimal(),
330+
inner_vi,
331+
)
332+
end for vi in vis
333+
]
365334
end
366335
return MOI.get(
367336
optimizer.dual_problem.dual_model,
368337
MOI.ConstraintPrimal(),
369-
primal_dual_map.primal_convarcon_to_dual_con[ci],
338+
ci_dual,
370339
)
371340
else
372341
return MOI.get.(
373342
optimizer.dual_problem.dual_model,
374343
MOI.VariablePrimal(),
375-
primal_dual_map.primal_con_to_dual_var_vec[ci],
344+
primal_dual_map.primal_constraint_data[ci].dual_variables,
376345
)
377346
end
378347
end
@@ -383,9 +352,11 @@ function MOI.get(
383352
ci::MOI.ConstraintIndex{F,S},
384353
) where {T,F<:MOI.AbstractScalarFunction,S<:MOI.AbstractScalarSet}
385354
primal_dual_map = optimizer.dual_problem.primal_dual_map
386-
if haskey(primal_dual_map.primal_convarcon_to_dual_con, ci)
387-
ci_dual = primal_dual_map.primal_convarcon_to_dual_con[ci]
388-
if ci_dual === NO_CONSTRAINT
355+
data = get(primal_dual_map.primal_constraint_data, ci, nothing)
356+
if data === nothing
357+
first_vi = primal_dual_map.primal_constrained_variables[ci][1]
358+
ci_dual = primal_dual_map.primal_variable_data[first_vi].dual_constraint
359+
if ci_dual === nothing
389360
return zero(T)
390361
else
391362
return MOI.get(
@@ -395,17 +366,16 @@ function MOI.get(
395366
)
396367
end
397368
else
398-
primal_ci_constant =
399-
primal_dual_map.primal_con_to_primal_constants_vec[ci][1]
369+
primal_ci_constant = data.primal_set_constants[1]
400370
# If it has no key then there is no dual constraint
401-
if !haskey(primal_dual_map.primal_con_to_dual_convarcon, ci)
371+
ci_dual = data.dual_constrained_variable_constraint
372+
if ci_dual === nothing
402373
return -primal_ci_constant
403374
end
404-
ci_dual_problem = primal_dual_map.primal_con_to_dual_convarcon[ci]
405375
return MOI.get(
406376
optimizer.dual_problem.dual_model,
407377
MOI.ConstraintDual(),
408-
ci_dual_problem,
378+
ci_dual,
409379
) - primal_ci_constant
410380
end
411381
end
@@ -416,13 +386,12 @@ function MOI.get(
416386
ci::MOI.ConstraintIndex{F,S},
417387
) where {T,F<:MOI.AbstractVectorFunction,S<:MOI.AbstractVectorSet}
418388
primal_dual_map = optimizer.dual_problem.primal_dual_map
419-
if haskey(primal_dual_map.primal_convarcon_to_dual_con, ci)
420-
ci_dual = primal_dual_map.primal_convarcon_to_dual_con[ci]
421-
if ci_dual === NO_CONSTRAINT
422-
n = MOI.output_dimension(
423-
primal_dual_map.primal_convarcon_to_dual_function[ci],
424-
)
425-
return zeros(T, n)
389+
data = get(primal_dual_map.primal_constraint_data, ci, nothing)
390+
if data === nothing
391+
vis = primal_dual_map.primal_constrained_variables[ci]
392+
ci_dual = primal_dual_map.primal_variable_data[vis[1]].dual_constraint
393+
if ci_dual === nothing
394+
return zeros(T, length(vis))
426395
else
427396
return MOI.get(
428397
optimizer.dual_problem.dual_model,
@@ -431,18 +400,17 @@ function MOI.get(
431400
)
432401
end
433402
else
403+
ci_dual = data.dual_constrained_variable_constraint
434404
# If it has no key then there is no dual constraint
435-
if !haskey(primal_dual_map.primal_con_to_dual_convarcon, ci)
405+
if ci_dual === nothing
436406
# The number of dual variable associated with the primal constraint is the ci dimension
437-
ci_dimension =
438-
length(primal_dual_map.primal_con_to_dual_var_vec[ci])
407+
ci_dimension = length(data.dual_variables)
439408
return zeros(T, ci_dimension)
440409
end
441-
ci_dual_problem = primal_dual_map.primal_con_to_dual_convarcon[ci]
442410
return MOI.get(
443411
optimizer.dual_problem.dual_model,
444412
MOI.ConstraintDual(),
445-
ci_dual_problem,
413+
ci_dual,
446414
)
447415
end
448416
end

src/constrained_variables.jl

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,27 @@ function _select_constrained_variables(
1414
primal_model,
1515
)
1616
params = Set(variable_parameters)
17+
selected_variables = Set{MOI.VariableIndex}()
1718
for S in single_or_vector_variables_types
1819
_select_constrained_variables(
1920
dual_problem.primal_dual_map,
2021
primal_model,
2122
S,
2223
params,
24+
selected_variables,
2325
)
2426
end
2527
return
2628
end
2729

28-
const NO_CONSTRAINT = MOI.ConstraintIndex{Nothing,Nothing}(0)
29-
3030
# Function barrier for the type instability of `F` and `S`.
3131
function _select_constrained_variables(
32-
m::PrimalDualMap,
32+
m::PrimalDualMap{T},
3333
primal_model,
3434
::Type{S},
3535
params,
36-
) where {S<:MOI.AbstractVectorSet}
36+
selected_variables,
37+
) where {T,S<:MOI.AbstractVectorSet}
3738
cis = MOI.get(
3839
primal_model,
3940
MOI.ListOfConstraintIndices{MOI.VectorOfVariables,S}(),
@@ -44,53 +45,40 @@ function _select_constrained_variables(
4445
if all(
4546
# no element of the VectorOfVariables is a constrained variable
4647
# and not a parameter
47-
vi ->
48-
# !haskey(m.primal_convar_to_primal_convarcon_and_index, vi) &&
49-
!is_constrained(m, vi) && !(vi in params),
48+
vi -> !(vi in selected_variables) && !(vi in params),
5049
f.variables,
5150
)
52-
# for (i, vi) in enumerate(f.variables)
53-
# m.primal_convar_to_primal_convarcon_and_index[vi] = (ci, i)
54-
# end
55-
# # Placeholder to indicate this constraint is part of constrained variables,
56-
# # it will be replaced later with a dual constraints
57-
# m.primal_convarcon_to_dual_con[ci] = NO_CONSTRAINT
58-
#
59-
for (i, vi) in enumerate(f.variables)
60-
m.primal_variable_data[vi] = VariableData(ci, i, NO_CONSTRAINT)
51+
m.primal_constrained_variables[ci] = f.variables
52+
for vi in f.variables
53+
push!(selected_variables, vi)
6154
end
62-
6355
end
6456
end
6557
return
6658
end
6759

6860
function _select_constrained_variables(
69-
m::PrimalDualMap,
61+
m::PrimalDualMap{T},
7062
primal_model,
7163
::Type{S},
7264
params,
73-
) where {S<:MOI.AbstractScalarSet}
65+
selected_variables,
66+
) where {T,S<:MOI.AbstractScalarSet}
7467
cis = MOI.get(
7568
primal_model,
7669
MOI.ListOfConstraintIndices{MOI.VariableIndex,S}(),
7770
)
7871
for ci in cis
79-
f = MOI.get(primal_model, MOI.ConstraintFunction(), ci)
72+
vi = MOI.get(primal_model, MOI.ConstraintFunction(), ci)
8073
# no element of the VectorOfVariables is a constrained variable
8174
# and not a parameter
82-
if is_constrained(m, vi)
83-
#!haskey(m.primal_convar_to_primal_convarcon_and_index, f) &&
84-
!(f in params)
75+
if !(vi in selected_variables) && !(vi in params)
8576
set = MOI.get(primal_model, MOI.ConstraintSet(), ci)
8677
if !iszero(MOI.constant(set))
8778
continue
8879
end
89-
# m.primal_convar_to_primal_convarcon_and_index[f] = (ci, 1)
90-
# # Placeholder to indicate this constraint is part of constrained variables,
91-
# # it will be replaced later with a dual constraints
92-
# m.primal_convarcon_to_dual_con[ci] = NO_CONSTRAINT
93-
m.primal_variable_data = VariableData(ci, 0, NO_CONSTRAINT)
80+
m.primal_constrained_variables[ci] = [vi]
81+
push!(selected_variables, vi)
9482
end
9583
end
9684
return

0 commit comments

Comments
 (0)