Examples
Here we discuss some useful examples of usage.
Dualize a JuMP model
Let us dualize the following Second Order Cone program
The corresponding code in JuMP is
using JuMP, Dualization
model = Model()
@variable(model, x)
@variable(model, y)
@variable(model, z)
@constraint(model, soccon, [x; y; z] in SecondOrderCone())
@constraint(model, eqcon, x == 1)
@objective(model, Min, y + z)
You can dualize the model by doing
dual_model = dualize(model)
And you should get the model
Note that if you declare the model with an optimizer attached you will lose the optimizer during the dualization. To dualize the model and attach the optimizer to the dual model you should do dualize(dual_model, SolverName.Optimizer)
using JuMP, Dualization, ECOS
model = Model(ECOS.Optimizer)
@variable(model, x)
@variable(model, y)
@variable(model, z)
@constraint(model, soccon, [x; y; z] in SecondOrderCone())
@constraint(model, eqcon, x == 1)
@objective(model, Min, y + z)
dual_model = dualize(model, ECOS.Optimizer)
Naming the dual variables and dual constraints
You can provide prefixes for the name of the variables and the name of the constraints using the a DualNames
variable. Every time you use the dualize function you can provide a DualNames
as keyword argument. Consider the following example.
You want to dualize this JuMP problem and add a prefix to the name of each constraint to be more clear on what the variables represent. For instance you want to put "dual"
before the name of the constraint.
using JuMP, Dualization
model = Model()
@variable(model, x)
@variable(model, y)
@variable(model, z)
@constraint(model, soccon, [x; y; z] in SecondOrderCone())
@constraint(model, eqcon, x == 1)
@objective(model, Min, y + z)
# The first field of DualNames is the prefix of the dual variables
# and the second field is the prefix of the dual constraint
dual_model = dualize(model; dual_names = DualNames("dual", ""))
The dual_model will be registered as
Solving a problem using its dual formulation
Depending on the solver and on the type of formulation, solving the dual problem could be faster than solving the primal. To solve the problem via its dual formulation can be done using the DualOptimizer
.
using JuMP, Dualization, ECOS
# Solving a problem the standard way
model = Model(ECOS.Optimizer)
@variable(model, x)
@variable(model, y)
@variable(model, z)
@constraint(model, soccon, [x; y; z] in SecondOrderCone())
@constraint(model, eqcon, x == 1)
@objective(model, Min, y + z)
# Solving a problem by providing its dual representation
model = Model(dual_optimizer(ECOS.Optimizer))
@variable(model, x)
@variable(model, y)
@variable(model, z)
@constraint(model, soccon, [x; y; z] in SecondOrderCone())
@constraint(model, eqcon, x == 1)
@objective(model, Min, y + z)
# You can pass arguments to the solver by attaching them to the solver constructor.
model = Model(dual_optimizer(optimizer_with_attributes(ECOS.Optimizer, "maxit" => 5)))
@variable(model, x)
@variable(model, y)
@variable(model, z)
@constraint(model, soccon, [x; y; z] in SecondOrderCone())
@constraint(model, eqcon, x == 1)
@objective(model, Min, y + z)