Semidefinite Programs (Experimental)
Semidefinite cone support in ConicIP is experimental. It works for small problems but has not been extensively tested.
A semidefinite cone constraint requires a symmetric matrix to be positive semidefinite. In ConicIP, matrices are stored in a vectorized form using vecm and mat.
Vectorization Convention
The cone specification ("S", k) describes a semidefinite cone where k = n(n+1)/2 is the dimension of the vectorized representation of an n × n symmetric matrix.
vecm(Z)vectorizes a symmetric matrix, scaling off-diagonal entries by√2so thatdot(vecm(X), vecm(Y)) == tr(X*Y).mat(x)reconstructs the symmetric matrix from its vectorized form.
Example: Projection onto the PSD Cone
Project the diagonal matrix diag(1, 1, 1, -1, -1, -1) onto the cone of positive semidefinite matrices. The expected result clips the negative eigenvalues to zero: diag(1, 1, 1, 0, 0, 0).
using ConicIP, SparseArrays, LinearAlgebra
# 6×6 matrix → vectorized dimension k = 6*7/2 = 21
k = 21
Q = sparse(1.0I, k, k)
target = diagm(0 => [1.0, 1, 1, -1, -1, -1])
c = ConicIP.vecm(target)
A = sparse(1.0I, k, k)
b = zeros(k)
cone_dims = [("S", k)]
sol = conicIP(Q, c, A, b, cone_dims; verbose=false, optTol=1e-7)
sol.status:OptimalReconstruct the matrix from the solution and check its eigenvalues:
result = ConicIP.mat(sol.y)
round.(eigvals(Symmetric(result)), digits=4)6-element Vector{Float64}:
0.0
0.0
0.0
1.0
1.0
1.0The negative eigenvalues have been projected to (approximately) zero.
Understanding vecm and mat
Let's see how the vectorization works on a small example:
X = [1.0 2.0 3.0;
2.0 5.0 6.0;
3.0 6.0 9.0]
v = ConicIP.vecm(X)6-element Vector{Float64}:
1.0
2.8284271247461903
4.242640687119286
5.0
8.485281374238571
9.0The vector v has length n(n+1)/2 = 6. Off-diagonal entries are scaled by √2:
round.(v, digits=4)6-element Vector{Float64}:
1.0
2.8284
4.2426
5.0
8.4853
9.0Reconstruct the original matrix:
X_recovered = ConicIP.mat(v)
round.(X_recovered, digits=4)3×3 Matrix{Float64}:
1.0 2.0 3.0
2.0 5.0 6.0
3.0 6.0 9.0