Dualization.jl icon indicating copy to clipboard operation
Dualization.jl copied to clipboard

Support `Parameter`

Open klamike opened this issue 11 months ago • 0 comments

Currently dualize is not compatible with Parameter, but there is a variable_parameters kwarg which does the job:

m = Model()
@variable m p ∈ Parameter(1.0)
@variable m x
@constraint m x ≥ p
@objective m Min x
dualize(m)
# ERROR: Constraints of the Function MathOptInterface.VariableIndex in the set MathOptInterface.Parameter{Float64} are not yet implemented.

m = Model()
@variable m p
@variable m x
@constraint m x ≥ p
@objective m Min x
print(dualize(m, variable_parameters=[index(p)], dual_names=DualNames("λ_", "ν_", "θ_", "q_")))
# Max θ_p*_[1]
# Subject to
#  ν_x : _[1] = 1
#  _[1] ≥ 0

I think dualize should support Parameter and rely on it to create variable_parameters internally. Getting the example to work is easy, just update the beginning of dualize! like below. Obviously this is a breaking change.

dualize.jl diff

Note the patch works but it skips putting θ_p ∈ Parameter(1.0) in the dual model, which I think would make sense to do.

function dualize(
    primal_model::MOI.ModelLike,
    dual_problem::DualProblem = DualProblem{Float64}();
    dual_names::DualNames = EMPTY_DUAL_NAMES,
-   variable_parameters::Vector{MOI.VariableIndex} = MOI.VariableIndex[],
    ignore_objective::Bool = false,
    consider_constrained_variables::Bool = true,
)
    return dualize(
        primal_model,
        dual_problem,
        dual_names,
-       variable_parameters,
        ignore_objective,
        consider_constrained_variables,
    )
end

function dualize(
    primal_model::MOI.ModelLike,
    dual_problem::DualProblem{T},
    dual_names::DualNames,
    ignore_objective::Bool,
-   variable_parameters::Vector{MOI.VariableIndex},
    consider_constrained_variables::Bool,
) where {T}
    # Throws an error if objective function cannot be dualized
    supported_objective(primal_model)

    # Query all constraint types of the model
-   con_types = MOI.get(primal_model, MOI.ListOfConstraintTypesPresent()
+   con_types = filter(
+        FS -> !(FS[2]<:MOI.Parameter),
+        MOI.get(primal_model, MOI.ListOfConstraintTypesPresent())
+    )

    supported_constraints(con_types) # Errors if constraint cant be dualized

+   # Get parameters
+   parameter_cis = MOI.get(primal_model, MOI.ListOfConstraintIndices{MOI.VariableIndex, MOI.Parameter{T}}())
+   variable_parameters = MOI.get.(primal_model, MOI.ConstraintFunction(), parameter_cis)

klamike avatar Feb 07 '25 12:02 klamike