207207
208208function MOI. supports_add_constrained_variables (
209209 optimizer:: DualOptimizer{T} ,
210- S :: Type{MOI.Reals} ,
210+ :: Type{MOI.Reals} ,
211211) where {T}
212212 return MOI. supports_constraint (
213213 optimizer. dual_problem. dual_model,
@@ -234,21 +234,29 @@ function MOI.supports_add_constrained_variables(
234234end
235235
236236function MOI. copy_to (dest:: DualOptimizer , src:: MOI.ModelLike )
237+ MOI. empty! (dest)
237238 dualize (
238239 src,
239240 dest. dual_problem,
240241 assume_min_if_feasibility = dest. assume_min_if_feasibility,
241242 )
242- idx_map = MOI . Utilities . IndexMap ()
243- for vi in MOI. get (src, MOI . ListOfVariableIndices ())
244- setindex! (idx_map, vi, vi )
243+ # Copy attributes except names which have already been passed in `dualize`
244+ primal_without_names = MOI. Utilities . ModelFilter (src) do attr
245+ return ! (attr isa Union{MOI . VariableName,MOI . ConstraintName} )
245246 end
247+ index_map = MOI. Utilities. identity_index_map (src)
248+ vis = MOI. get (src, MOI. ListOfVariableIndices ())
249+ MOI. Utilities. pass_attributes (dest, primal_without_names, index_map, vis)
246250 for (F, S) in MOI. get (src, MOI. ListOfConstraintTypesPresent ())
247- for con in MOI. get (src, MOI. ListOfConstraintIndices {F,S} ())
248- setindex! (idx_map, con, con)
249- end
251+ cis = MOI. get (src, MOI. ListOfConstraintIndices {F,S} ())
252+ MOI. Utilities. pass_attributes (
253+ dest,
254+ primal_without_names,
255+ index_map,
256+ cis,
257+ )
250258 end
251- return idx_map
259+ return index_map
252260end
253261
254262function MOI. optimize! (optimizer:: DualOptimizer )
@@ -270,226 +278,3 @@ function MOI.get(optimizer::DualOptimizer, ::MOI.SolverName)
270278 name = MOI. get (optimizer. dual_problem. dual_model, MOI. SolverName ())
271279 return " Dual model with $name attached"
272280end
273-
274- function MOI. get (
275- optimizer:: DualOptimizer{T} ,
276- :: MOI.VariablePrimal ,
277- vi:: MOI.VariableIndex ,
278- ):: T where {T}
279- primal_dual_map = optimizer. dual_problem. primal_dual_map
280- data = get (primal_dual_map. primal_variable_data, vi, nothing )
281- if data === nothing
282- # error
283- elseif data. dual_constraint === nothing
284- return zero (T)
285- elseif data. primal_constrained_variable_constraint === nothing
286- return - MOI. get (
287- optimizer. dual_problem. dual_model,
288- MOI. ConstraintDual (),
289- data. dual_constraint,
290- )
291- elseif data. dual_constraint isa
292- MOI. ConstraintIndex{<: MOI.AbstractVectorFunction }
293- return MOI. get (
294- optimizer. dual_problem. dual_model,
295- MOI. ConstraintDual (),
296- data. dual_constraint,
297- )[data. primal_constrained_variable_index]
298- else
299- return MOI. get (
300- optimizer. dual_problem. dual_model,
301- MOI. ConstraintDual (),
302- data. dual_constraint,
303- )
304- end
305- end
306-
307- function MOI. get (
308- optimizer:: DualOptimizer ,
309- :: MOI.ConstraintDual ,
310- ci:: MOI.ConstraintIndex{F,S} ,
311- ) where {F<: MOI.AbstractScalarFunction ,S<: MOI.AbstractScalarSet }
312- primal_dual_map = optimizer. dual_problem. primal_dual_map
313- if haskey (primal_dual_map. primal_constrained_variables, ci)
314- vi = primal_dual_map. primal_constrained_variables[ci][]
315- ci_dual = primal_dual_map. primal_variable_data[vi]. dual_constraint
316- if ci_dual === nothing
317- return MOI. Utilities. eval_variables (
318- primal_dual_map. primal_variable_data[vi]. dual_function,
319- ) do inner_vi
320- return MOI. get (
321- optimizer. dual_problem. dual_model,
322- MOI. VariablePrimal (),
323- inner_vi,
324- )
325- end
326- end
327- set = MOI. get (
328- optimizer. dual_problem. dual_model,
329- MOI. ConstraintSet (),
330- ci_dual,
331- )
332- return MOI. get (
333- optimizer. dual_problem. dual_model,
334- MOI. ConstraintPrimal (),
335- ci_dual,
336- ) - MOI. constant (set)
337- else
338- return MOI. get (
339- optimizer. dual_problem. dual_model,
340- MOI. VariablePrimal (),
341- primal_dual_map. primal_constraint_data[ci]. dual_variables[],
342- )
343- end
344- end
345-
346- function MOI. get (
347- optimizer:: DualOptimizer ,
348- :: MOI.ConstraintDual ,
349- ci:: MOI.ConstraintIndex{F,S} ,
350- ) where {F<: MOI.AbstractVectorFunction ,S<: MOI.AbstractVectorSet }
351- primal_dual_map = optimizer. dual_problem. primal_dual_map
352- if ! haskey (primal_dual_map. primal_constraint_data, ci)
353- vis = primal_dual_map. primal_constrained_variables[ci]
354- ci_dual = primal_dual_map. primal_variable_data[vis[1 ]]. dual_constraint
355- if ci_dual === nothing
356- return [
357- MOI. Utilities. eval_variables (
358- primal_dual_map. primal_variable_data[vi]. dual_function,
359- ) do inner_vi
360- return MOI. get (
361- optimizer. dual_problem. dual_model,
362- MOI. VariablePrimal (),
363- inner_vi,
364- )
365- end for vi in vis
366- ]
367- end
368- return MOI. get (
369- optimizer. dual_problem. dual_model,
370- MOI. ConstraintPrimal (),
371- ci_dual,
372- )
373- else
374- return MOI. get .(
375- optimizer. dual_problem. dual_model,
376- MOI. VariablePrimal (),
377- primal_dual_map. primal_constraint_data[ci]. dual_variables,
378- )
379- end
380- end
381-
382- function MOI. get (
383- optimizer:: DualOptimizer{T} ,
384- :: MOI.ConstraintPrimal ,
385- ci:: MOI.ConstraintIndex{F,S} ,
386- ) where {T,F<: MOI.AbstractScalarFunction ,S<: MOI.AbstractScalarSet }
387- primal_dual_map = optimizer. dual_problem. primal_dual_map
388- data = get (primal_dual_map. primal_constraint_data, ci, nothing )
389- if data === nothing
390- first_vi = primal_dual_map. primal_constrained_variables[ci][1 ]
391- ci_dual = primal_dual_map. primal_variable_data[first_vi]. dual_constraint
392- if ci_dual === nothing
393- return zero (T)
394- else
395- return MOI. get (
396- optimizer. dual_problem. dual_model,
397- MOI. ConstraintDual (),
398- ci_dual,
399- )
400- end
401- else
402- primal_ci_constant = data. primal_set_constants[1 ]
403- # If it has no key then there is no dual constraint
404- ci_dual = data. dual_constrained_variable_constraint
405- if ci_dual === nothing
406- return - primal_ci_constant
407- end
408- return MOI. get (
409- optimizer. dual_problem. dual_model,
410- MOI. ConstraintDual (),
411- ci_dual,
412- ) - primal_ci_constant
413- end
414- end
415-
416- function MOI. get (
417- optimizer:: DualOptimizer{T} ,
418- :: MOI.ConstraintPrimal ,
419- ci:: MOI.ConstraintIndex{F,S} ,
420- ) where {T,F<: MOI.AbstractVectorFunction ,S<: MOI.AbstractVectorSet }
421- primal_dual_map = optimizer. dual_problem. primal_dual_map
422- data = get (primal_dual_map. primal_constraint_data, ci, nothing )
423- if data === nothing
424- vis = primal_dual_map. primal_constrained_variables[ci]
425- ci_dual = primal_dual_map. primal_variable_data[vis[1 ]]. dual_constraint
426- if ci_dual === nothing
427- return zeros (T, length (vis))
428- else
429- return MOI. get (
430- optimizer. dual_problem. dual_model,
431- MOI. ConstraintDual (),
432- ci_dual,
433- )
434- end
435- else
436- ci_dual = data. dual_constrained_variable_constraint
437- # If it has no key then there is no dual constraint
438- if ci_dual === nothing
439- # The number of dual variable associated with the primal constraint is the ci dimension
440- ci_dimension = length (data. dual_variables)
441- return zeros (T, ci_dimension)
442- end
443- return MOI. get (
444- optimizer. dual_problem. dual_model,
445- MOI. ConstraintDual (),
446- ci_dual,
447- )
448- end
449- end
450-
451- function MOI. get (optimizer:: DualOptimizer , :: MOI.TerminationStatus )
452- return _dual_status (
453- MOI. get (optimizer. dual_problem. dual_model, MOI. TerminationStatus ()),
454- )
455- end
456-
457- function _dual_status (term:: MOI.TerminationStatusCode )
458- if term == MOI. INFEASIBLE
459- return MOI. DUAL_INFEASIBLE
460- elseif term == MOI. DUAL_INFEASIBLE
461- return MOI. INFEASIBLE
462- elseif term == MOI. ALMOST_INFEASIBLE
463- return MOI. ALMOST_DUAL_INFEASIBLE
464- elseif term == MOI. ALMOST_DUAL_INFEASIBLE
465- return MOI. ALMOST_INFEASIBLE
466- end
467- return term
468- end
469-
470- function MOI. supports (
471- optimizer:: DualOptimizer ,
472- attr:: MOI.AbstractOptimizerAttribute ,
473- )
474- return MOI. supports (optimizer. dual_problem. dual_model, attr)
475- end
476-
477- function MOI. set (
478- optimizer:: DualOptimizer ,
479- attr:: MOI.AbstractOptimizerAttribute ,
480- value,
481- )
482- return MOI. set (optimizer. dual_problem. dual_model, attr, value)
483- end
484-
485- function MOI. get (optimizer:: DualOptimizer , attr:: MOI.AbstractOptimizerAttribute )
486- return MOI. get (optimizer. dual_problem. dual_model, attr)
487- end
488-
489- # For now we don't support setting arbitrary AbstractModelAttribute because
490- # we don't know if they need to be modified via the dualization. One example
491- # would be `MOI.set(model, MOI.ObjectiveFunction{F}(), f)`. We currently
492- # don't support the incremental interface.
493- function MOI. get (optimizer:: DualOptimizer , attr:: MOI.AbstractModelAttribute )
494- return MOI. get (optimizer. dual_problem. dual_model, attr)
495- end
0 commit comments