Getting Started
This tutorial introduces ConicIP.jl's problem formulation, core API, and solution interpretation. By the end you will have solved your first optimization problem in under a minute.
Problem Formulation
ConicIP solves optimization problems of the form
minimize ½ yᵀQy - cᵀy
subject to Ay ≥_K b
Gy = dwhere ≥_K denotes a generalized inequality with respect to a cone K.
Arguments at a Glance
| Argument | Size | Description |
|---|---|---|
Q | n × n | Positive semidefinite Hessian (use spzeros(n,n) for LPs) |
c | n | Linear objective term (vector) |
A | m × n | Inequality constraint matrix |
b | m | Inequality right-hand side (vector) |
cone_dims | Vector of (String,Int) | Cone specification for rows of A |
G | p × n | Equality constraint matrix (optional) |
d | p | Equality right-hand side (vector, optional) |
Cone Specification
The cone_dims argument is a vector of (type, dimension) tuples describing how the rows of A and b are partitioned into cone constraints:
("R", n)– nonnegative orthant: the firstnrows satisfyAy - b ≥ 0("Q", m)– second-order cone: the nextmrows satisfy‖(Ay-b)[2:end]‖ ≤ (Ay-b)[1]("S", k)– semidefinite cone (experimental): the nextkrows represent a vectorized symmetric matrix that must be positive semidefinite, wherek = n(n+1)/2
For example, [("R", 3), ("Q", 5)] means the first 3 rows of Ay ≥ b are nonnegative constraints, and the next 5 rows form a second-order cone constraint.
Example: Box-Constrained QP
Let's solve a box-constrained quadratic program: minimize ½ yᵀQy - cᵀy subject to 0 ≤ y ≤ 1.
We encode the box constraints 0 ≤ y ≤ 1 as [I; -I] y ≥ [0; -1].
using ConicIP, SparseArrays, LinearAlgebra, Random
Random.seed!(42)
n = 10
Q = sparse(Diagonal(rand(n) .+ 0.1))
c = randn(n)
# Encode 0 ≤ y ≤ 1 as [I; -I] y ≥ [0; -1]
A = sparse([I(n); -I(n)])
b = [zeros(n); -ones(n)]
cone_dims = [("R", 2n)]
sol = conicIP(Q, c, A, b, cone_dims; verbose=false)
sol.status:OptimalThe primal solution:
round.(sol.y, digits=4)10-element Vector{Float64}:
0.0
0.0
1.0
0.0313
0.0
0.9955
0.0
0.0
0.0
0.0Interpreting the Solution
The solver returns a Solution struct with these key fields:
| Field | Description |
|---|---|
sol.y | Primal variables (vector) |
sol.v | Dual variables for inequality constraints |
sol.w | Dual variables for equality constraints |
sol.status | :Optimal, :Infeasible, :Unbounded, :Abandoned, or :Error |
sol.pobj, sol.dobj | Primal and dual objective values |
sol.prFeas | Primal feasibility residual |
sol.duFeas | Dual feasibility residual |
sol.muFeas | Complementarity residual |
sol.Iter | Number of iterations |
Let's inspect the convergence residuals:
(prFeas=sol.prFeas, duFeas=sol.duFeas, muFeas=sol.muFeas)(prFeas = 1.0331927562766044e-16, duFeas = 1.0246771995780095e-16, muFeas = 6.672332164139473e-8)All residuals are well below the default tolerance (optTol = 1e-6).
Using JuMP Instead
You can also model problems via JuMP instead of the direct conicIP API. Here's the same box-constrained QP:
using JuMP
model = Model(() -> ConicIP.Optimizer(verbose=false))
@variable(model, 0 <= x[i=1:n] <= 1)
@objective(model, Min, 0.5 * sum(Q[i,i] * x[i]^2 for i in 1:n) - sum(c[i] * x[i] for i in 1:n))
optimize!(model)
termination_status(model)OPTIMAL::TerminationStatusCode = 1The JuMP solution matches the direct API:
round.(value.(x), digits=4)10-element Vector{Float64}:
0.0
0.0
1.0
0.0313
0.0
0.9953
0.0
0.0
0.0
0.0Next Steps
- Linear Programs – LPs with equality constraints and duals
- Quadratic Programs – portfolio optimization on the simplex
- Second-Order Cone Programs – norm minimization and mixed cones
- JuMP Integration – full guide on using ConicIP through JuMP