jump-dev / MosekTools.jl

A MathOptInterface.jl interface to the MOSEK solver
https://github.com/MOSEK/Mosek.jl
MIT License
29 stars 8 forks source link

VectorOfVariables constraints #11

Closed blegat closed 5 years ago

blegat commented 5 years ago

Because the PositiveSemidefiniteConeTriangle does not directly match the PSD cone used by Mosek, when doing

@variable(model, x[1:2, 1:2], PSD)

3 scalar variables are created by JuMP (say x1, x2, x3) and then a matrix variable of 3 variables (y[1:3]) is created by MosekTools, the matrix variables y are in the Mosek PSD cone and their correspondance with the 3 variables added by JuMP is encoded by 3 equalities: y[1] = x1, y[2] = √2*x2 and y[3] = x3. As we can see below, it creates 3 constraints, 3 scalar constraints and a matrix variable.

julia> using MosekTools

julia> optimizer = Mosek.Optimizer();

julia> using JuMP

julia> x = MOI.add_variables(optimizer, 3)
3-element Array{MathOptInterface.VariableIndex,1}:
 MathOptInterface.VariableIndex(1)
 MathOptInterface.VariableIndex(2)
 MathOptInterface.VariableIndex(3)

julia> c = MOI.add_constraint(optimizer, MOI.VectorOfVariables(x), MOI.PositiveSemidefiniteConeTriangle(2))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables,MathOptInterface.PositiveSemidefiniteConeTriangle}(3)

julia> MOI.optimize!(optimizer)
Problem
  Name                   :                 
  Objective sense        : min             
  Type                   : CONIC (conic optimization problem)
  Constraints            : 3               
  Cones                  : 0               
  Scalar variables       : 3               
  Matrix variables       : 1               
  Integer variables      : 0               

Optimizer started.
Optimizer terminated. Time: 0.00    

2-element Array{MosekTools.MosekSolution,1}:
 MosekTools.MosekSolution(Mosek.MSK_SOL_BAS, Mosek.MSK_SOL_STA_DUAL_FEAS, Mosek.MSK_PRO_STA_DUAL_FEAS, Mosek.Stakey[Mosek.MSK_SK_SUPBAS, Mosek.MSK_SK_SUPBAS, Mosek.MSK_SK_SUPBAS], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Float64[], Mosek.Stakey[Mosek.MSK_SK_BAS, Mosek.MSK_SK_BAS, Mosek.MSK_SK_BAS], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0])                                                           
 MosekTools.MosekSolution(Mosek.MSK_SOL_ITR, Mosek.MSK_SOL_STA_OPTIMAL, Mosek.MSK_PRO_STA_PRIM_AND_DUAL_FEAS, Mosek.Stakey[Mosek.MSK_SK_SUPBAS, Mosek.MSK_SK_SUPBAS, Mosek.MSK_SK_SUPBAS], [0.679405, 0.0, 0.679405], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], Mosek.Stakey[Mosek.MSK_SK_FIX, Mosek.MSK_SK_FIX, Mosek.MSK_SK_FIX], [-0.0, -0.0, -0.0], [1.51119e-10, 0.0, 1.51119e-10], [0.0, -0.0, 0.0], [1.51119e-10, 0.0, 1.51119e-10])

@ulfworsoe Does Mosek always eliminates the variables x1, x2 and x3 or would it be more efficient to avoid create the x1, x2 and x3 variables directly use y[1], y2/√2 and y[3] in the model ?

blegat commented 5 years ago

It seems to be causing a significant slowdown of Mosek performance, see https://nbviewer.jupyter.org/github/mforets/escritoire/blob/master/reachability/XFZ18under.ipynb#Comparison-with-a-MATLAB/YALMIP-implementation cc @mforets

mforets commented 5 years ago

Awesome! I confirm that the slowdown is fixed for the problem in the previous comment, and I've uploaded a new version of that notebook including the results using JuMP v0.19.0.