Reformulate quadratic constraints
It would be nice if dualize could optionally add a bridge layer before dualizing so that it can for instance reformulate quadratic constraints to SOC
This would also solve https://github.com/jump-dev/Dualization.jl/issues/73
Leaving the SingleBridgeOptimizer workaround here for future readers...
Replace
model = JuMP.Model()
...
dual_model = Dualization.dualize(model)
with
model = JuMP.Model()
...
dualizable_model = MOI.Utilities.Model{Float64}()
bridged_model = MOI.Bridges.Constraint.QuadtoSOC{Float64}(dualizable_model)
MOI.copy_to(bridged_model, JuMP.backend(model))
dual_problem = Dualization.dualize(dualizable_model)
dual_model = JuMP.Model()
MOI.copy_to(dual_model, dual_problem.dual_model)
Based on https://github.com/jump-dev/Dualization.jl/issues/73#issuecomment-581988209
Here is the issue:
1 - We start with a primal_model that has constraints that Dualization.jl does not know how to handle: for instance, quadratic constraints.
2 - So we need to obtain a new primal model that can be dualized.
Dualization could provide a cache DualizationCache (that is a full_bridge_optimizer(+ a CachingOptimizer) on top of the Dualization.DualizableModel).
We would need to copy_to the primal_model to the DualizationCache.
3 - Then, we grab the inner thing, Dualization.DualizableModel, and apply dualize on it.
For this to be fully functional, we would need a map from the original primal_model to the final dual model.
But constraints won't match because things were bridged, so we can't write a PrimalDualMap from the original primal_model to the final dual model.
This makes sense a docs improvement. But I am not seeing how this would be clean and useful inside dualize.
Yeah propagating the map would get nasty and probably cause more confusion... I do think a better error would be nice here, e.g. (very rough)
Dualization.jl only supports models with linear or convex quadratic objective and constraints in conic form, but a <nonlinear constraint/objective> was found in your model. For more details and an example of how to reformulate a model into such a form, see <docs page>.
We could give a partial map that errors for constraints that are bridged with a nice error message