Conic Optimization on Julia

Here I will describe a bit about conic programming on Julia based on Juan Pablo Vielma’s JuliaCon 2020 talk and JuMP devs Tutorials. We will begin by defining what is a cone and how to model them on JuMP together with some simple examples, by the end we will solve an mixed - integer conic problem of avoiding obstacles by following a polynomial trajectory.

Why Conic Optimizacion?

  • Linear- programming-like duality
  • Faster and more stable algorithms
    • Avoid non-differentiability issues, exploit primal-dual form, strong theory on barriers for interior point algorithms.
    • Industry change in 2018:
      1. Knitro version 11.0 adds support for SOCP constraints.
      2. Mosek version 9.0 deprecates expression/function-based formulations and focuses on pure conic (linear, SOCP, rotated SOCP, SDP, exp & power)

Table of Contents

  • What is a Cone?
  • Conic Programming.
  • Some type of Cones supported by JuMP and programming examples.
    • Second Order - Cone
    • Rotated Second Order - Cone
    • Exponential Cone
    • Positive Semidefinite Cone (PSD)
    • Other Cones and Functions.
  • Mixed Integer Conic example: Avoiding obstacles (Drone and Flappy bird)
  • Continuous Conic programming on Julia?

What is a Cone?

A subset C of a vector space V is a cone if xC and positive scalars α, the product αxC.

A cone C is a convex cone if αx+βyC, for any positive scalars α,β, and any x,yC."

Conic Programming

Conic programming problems are convex optimization problems in which a convex function is minimized over the intersection of an affine subspace and a convex cone. An example of a conic-form minimization problems, in the primal form is:

minxRna0x+b0

such that: Aix+biCifor i=1m

The corresponding dual problem is:

maxy1,,ymi=1mbiTyi+b0

such that: a0i=1mAiTyi=0 yiCi

Where each Ci is a closed convex cone and Ci is its dual cone.

Some of the Types of Cones supported by JuMP

Second - Order Cone

The Second - Order Cone (or Lorentz Cone) of dimension n is of the form:

Qn={(t,x)Rn:tx2}

A Second - Order Cone rotated by π/4 in the (x1,x2) plane is called a Rotated Second- Order Cone. It is of the form:

Qrn={(t,u,x)Rn:2tux2,t,u0}

These cones are represented in JuMP using MOI sets SecondOrderCone and RotatedSecondOrderCone

Example: Euclidean Projection on a hyperplane

For a given point u0 and a set K, we refer to any point uK which is closest to u0 as a projection of u0 on K. The projection of a point u0 on a hyperplane K={u:pu=q} is given by:

minxRnuu0s.t. pu=q

We can model the above problem as the following conic program:

mints.t. pu=q(t,uu0)Qn+1

If we transform this to the form we saw above,

x=(t,u)a0=e1b0=0A1=(0,p)b1=qC1=RA2=1b2=(0,u0)C2=Qn+1

Thus, we can obtain the dual problem as:

maxy1+(0,u0)y2s.t. e1(0,p)y1y2=0y1Ry2Qn+1

Let’s model this in Julia.

First we need to load some packages JuMP is the modeling package, ECOS is a solver, LinearAlgebra and Random are just to get some linear algebra operations and a fix seed for reproducibility respectively.

using JuMP
using ECOS
using LinearAlgebra
using Random
Random.seed!(2020);

Lets get some random values for the problem’s input: u0, p and q

u0 = rand(10)
p = rand(10)
q = rand();

Now we can write the model:

model = Model(optimizer_with_attributes(ECOS.Optimizer, "printlevel" => 0))
@variable(model, u[1:10])
@variable(model, t)
@objective(model, Min, t)
@constraint(model, [t, (u - u0)...] in SecondOrderCone())
@constraint(model, u' * p == q)
optimize!(model)
Optimization Result

Then we can see the objective function value and variable value at the optimum by doing:

@show objective_value(model);
@show value.(u);

We get an objective value of : 1.4149915748070703. We can also solve the dual problem:

e1 = [1.0, zeros(10)...]
dual_model = Model(optimizer_with_attributes(ECOS.Optimizer, "printlevel" => 0))
@variable(dual_model, y1 <= 0.0)
@variable(dual_model, y2[1:11])
@objective(dual_model, Max, q * y1 + dot(vcat(0.0, u0), y2))
@constraint(dual_model, e1 - [0.0, p...] .* y1 - y2 .== 0.0)
@constraint(dual_model, y2 in SecondOrderCone())
optimize!(dual_model)
Optimization Dual problem
@show objective_value(dual_model);

We get an objective value of : 1.4149916455792486. The difference between this value and the primal is 7.07×108, does this makes sense?

We can also have an equivalent formulation using a Rotated Second - Order cone:

mints.t. pu=q(t,1/2,uu0)Qrn+2

model = Model(optimizer_with_attributes(ECOS.Optimizer, "printlevel" => 0))
@variable(model, u[1:10])
@variable(model, t)
@objective(model, Min, t)
@constraint(model, [t, 0.5, (u - u0)...] in RotatedSecondOrderCone())
@constraint(model, u' * p == q)
optimize!(model)
Optimization Rotated formulation

We notice that the objective function values are different. There is a simple explanation to that behaviour. In the case of Second-Order Cone the objective function is uu02 while in the case of a Rotated Second-Order Cone is uu022. However, the values of u are the same in both problems.

Exponential Cone

An exponential Cone is a set of the form:

Kexp={(x,y,z)R3:yexp(x/y)z,y0}

It is represented in JuMP using the MOI set ExponentialCone.

Example: Entropy Maximization

We want to maximize the entropy function H(x)=xlog(x) subject to linear inequality constraints.

maxi=1nxilog(xi)s.t. 1x=1Axb

We just need to use the following transformation:

txlog(x)txlog(1/x)(t,x,1)Kexp

An example in Julia would be:

n = 15;
m = 10;
A = randn(m, n);
b = rand(m, 1);

model = Model(optimizer_with_attributes(ECOS.Optimizer, "printlevel" => 0))
@variable(model, t[1:n])
@variable(model, x[1:n])
@objective(model, Max, sum(t))
@constraint(model, sum(x) == 1.0)
@constraint(model, A * x .<= b )
# Cannot use the exponential cone directly in JuMP, hence we use MOI to specify the set.
@constraint(model, con[i = 1:n], [t[i], x[i], 1.0] in MOI.ExponentialCone())

optimize!(model);

Positive Semidefinite Cone

The set of Positive Semidefinite Matrices of dimension n form a cone in Rn. We write this set mathematically as:

S+n={XSn:zXz0,zRn}

A PSD cone is represented in JuMP using the MOI sets PositiveSemidefiniteConeTriangle (for upper triangle of a PSD matrix) and PositiveSemidefiniteConeSquare (for a complete PSD matrix). However, it is preferable to use the PSDCone shortcut as illustrated below.

Example: Largest Eigenvalue of a Symmetrix Matrix

Suppose A has eigenvalues λ1λ2λn. Then the matrix tIA has eigenvalues tλ1, tλ2, , tλn. Note that tIA is PSD exactly when all these eigenvalues are non-negative, and this happends for values tλ1. Thus, we can model the problem of fiding the largest eigenvalue of a symmetrix matrix as:

λ1=maxts.t. tIA0

using LinearAlgebra
using SCS

A = [3 2 4;
     2 0 2;
     4 2 3]

model = Model(optimizer_with_attributes(SCS.Optimizer, "verbose" => 0))
@variable(model, t)
@objective(model, Min, t)
@constraint(model, t .* Matrix{Float64}(I, 3, 3) - A in PSDCone())

optimize!(model)

Which give us λ1=8.

Other Cones and Functions

For other cones supported by JuMP, check out the MathOptInterface Manual. A good resource for learning more about functions which can be modelled using cones is the MOSEK Modeling Cookbook. Also Check this link to find out all the different solvers and their supported problem types

Mixed - Integer Conic example

Suppose we have a drone which we want to fly avoiding obstacles, how can we model and compute the optimal trajectory?

Avoiding Obstacles

Let (x(t),y(t))t[0,1] represent the position at each time t[0,1].

  • Step 1: Discretize time intro intervals 0=T1<T2<<TN=1 and then describe position by polynomials {pi:[Ti,Ti+1]>R2}i=1N such that:

(x(t),y(t))=pi(t)t[Ti,Ti+1]

  • Step 2: “Safe polyhedrons” Pr={xR2:Arxbr} such that: i,r s.t pi(t)Prt[Ti,Ti+1]

    • pi(t)Prqi,r(t)0t
    • Sum-of-Squares (SOS): qi,r(t)=jrj2 where rj(t) is a polynomial function
    • Boyund degree of polynomials: SDP.

Using JuMP.jl, PolyJuMP.jl, SumOfSquares.jl, MI-SDP Solver Pajarito.jl for a 9 region, 8 time steps problem, we get optimal “smoothness” in 651 seconds as shown in the picture above.

While for 60 horizontal segments & obstacle every 5: Optimal “clicks” in 80 seconds.

Avoiding Obstacles

Check more here

Continuous solver?

  • The Hypatia.jl solver: conic interior point algorithms and interfaces (Chris Coey, MIT)
    • A homogeneous interior-point solver for non - symmetric cones
    • Versatility & performance = More Cones
      • Two dozen predefined standard and exotic cones: e.g SDP, Sum-of-Squares and “Matrix” Sum-of-Squares for convexity/shape constraints.
    • Customizable: “Bring your own barrier” = " Bring your own cone"
    • Take advantage of Natural formulations.
    • Take advantage of Julia: multi-precision arithmetic, abstract linear operators, etc.
  • Modeling with new and nonsymmetric cones (Lea Kapelevich, MIT)
  • Tulip.jl: An interior-point LP solver with abstract linear algebra (Mathieu Tanneau, Polytechnique Montréal)
  • Set Programming with JuMP (Benoît Legat, UC Louvain)
  • JuliaMoments (Tillmann Weisser, Los Alamos National Laboratory) -Dual of Sum-of-Squares
Daniel Pereda
Daniel Pereda
Data Scientist

My research interests include optimization, game theory and operation research.

Related