API Reference
Solver
The main entry point for solving conic optimization problems.
ConicIP.conicIP — Function
conicIP(Q, c, A, b, conedims, G, d; kktsolver = defaultkktsolver, optTol = 1e-6, DTB = 0.01, verbose = true, maxRefinementSteps = 3, maxIters = 100, cache_nestodd = false, infeasTol = 1e-7, infeasAbsTol = 1e-9, staticReg = 0.0, certFallback = true, certFallbackIters = 50, refinementThreshold = optTol/1e7)
Interior point solver for the system
minimize ½yᵀQy - cᵀy
s.t Ay >= b
Gy = dc, b, d are vectors (or any AbstractVector)
cone_dims is an array of tuples (Cone Type, Dimension)
e.g. [("R",2),("Q",4)] means
(y₁, y₂) in R+
(y₃, y₄, y₅, y₆) in QSDP Cones are NOT supported and purely experimental at this point.
Returns a Solution whose status is one of
:Optimal—max(rDu, rPr, rCp, rEq) < optTol.:Infeasible/:Unbounded— a ray passed a screen and was accepted by the corresponding validator;has_certificateis thentrue.:AlmostInfeasible/:AlmostUnbounded— set only at loop exhaustion, when the best iterate carries a ray that validates at100*infeasTolbut not atinfeasTol. The best iterate is retained.:Abandoned— iteration limit reached with no verdict.:Error— nonfinite residuals, or a KKT factorization failure (the reason is recorded insol.message). Rank-deficientGhanded directly toconicIPtypically lands here; usepreprocess_conicIPto trim redundant rows first.staticRegregularizes only theQblock of the KKT system and cannot repair a rank-deficientG.
Structurally degenerate inputs are handled exactly before any factorization: an all-zero row of G is deflated (dᵢ = 0) or answered with a certified :Infeasible (dᵢ ≠ 0), and a variable absent from Q, A, and G is deflated (cⱼ = 0) or answered with a certified :Unbounded (cⱼ ≠ 0).
Selected keyword arguments:
infeasTol— infeasibility-certificate tolerance, decoupled fromoptTol.infeasAbsTol— absolute tolerance for certificate validation.staticReg— static KKT regularization scale;0(default) disables it.preprocess_conicIPenables it when it detects rank deficiency.certFallback— enable fallback certificate solve on stall.
The parameter solve3x3gen allows the passing of a custom solver for the KKT System, as follows
julia> L = solve3x3gen(F,F⁻ᵀ,Q,A,G)
Then this
julia> (a,b,c) = L(y,w,v)
solves the system
┌ ┐ ┌ ┐ ┌ ┐
│ Q G' -A' │ │ a │ = │ y │
│ G │ │ b │ │ w │
│ A FᵀF │ │ c │ │ v │
└ ┘ └ ┘ └ ┘We can also wrap a 2x2 solver using pivot3gen(solve2x2gen) The 2x2 solves the system
julia> L = solve2x2gen(F,F⁻ᵀ,Q,A,G)
Then this
julia> (a,b) = L(y,w)
solves the system
┌ ┐ ┌ ┐ ┌ ┐
│ Q + Aᵀinv(FᵀF)A G' │ │ a │ = │ y │
│ G │ │ b │ │ w │
└ ┘ └ ┘ └ ┘ConicIP.preprocess_conicIP — Function
ConicIP with preprocessing to ensure the following rank constraints
Primal equailty constraints : Gx = d Rank condition : rank(G) = size(G,1)
Dual equality constraints : [ Q A' G'] = c Rank condition : rank([Q A' G']) = size(Q,1)
Inconsistent data is reported with a certificate whenever one can be constructed and verified against the original problem data:
Gy = dinconsistent →:Infeasiblewith a Farkas ray(w,v)c ∉ range([Q Aᵀ Gᵀ])→:Unboundedwith a recession rayy
Rank deficiency that is not an inconsistency is handled by opting into conicIP's static KKT regularization rather than by perturbing Q.
Solution
The solver returns a Solution struct containing primal/dual variables, status, and convergence information.
ConicIP.Solution — Type
SolutionReturn type of conicIP and preprocess_conicIP.
Fields
y::Vector{Float64}– primal variablesw::Vector{Float64}– dual variables for equality constraints (Gy = d)v::Vector{Float64}– dual variables for inequality constraints (Ay ≥_K b)s::Vector{Float64}– cone slack variables (Ay - s = b, s ∈ K)status::Symbol–:Optimal,:Infeasible,:Unbounded,:AlmostInfeasible,:AlmostUnbounded,:Abandoned, or:ErrorIter::Integer– number of interior-point iterationsMu::Real– final complementarity gap parameterprFeas::Real– primal feasibility residualduFeas::Real– dual feasibility residualmuFeas::Real– complementarity residualpobj::Real– primal objective valuedobj::Real– dual objective valuehas_certificate::Bool– the returned vectors carry a verified ray certifying infeasibility or unboundedness (see the table below)
Field conventions by status
| status | y | w | v | s | pobj/dobj | has_certificate |
|---|---|---|---|---|---|---|
:Optimal | solution | dual (eq) | dual (ineq), ∈ K | slack, ∈ K | real | false |
:Infeasible with ray | all NaN | ray w̄ | ray v̄ ∈ K | all NaN | NaN | true |
:Unbounded with ray | ray ȳ | all NaN | all NaN | A*ȳ | NaN | true |
:Infeasible/:Unbounded without ray | all NaN | all NaN | all NaN | all NaN | NaN | false |
:Abandoned, :AlmostInfeasible, :AlmostUnbounded, :Error | best iterate | best iterate | best iterate | best iterate | best iterate | false |
The infeasibility ray is normalized so that dᵀw̄ - bᵀv̄ = -1 with Gᵀw̄ - Aᵀv̄ ≈ 0; the unboundedness ray is normalized so that cᵀȳ = +1 with Qȳ ≈ 0, Gȳ ≈ 0 and Aȳ ∈ K. See validate_infeasibility_certificate and validate_unboundedness_certificate.
A 12-argument constructor is provided which defaults has_certificate to false.
Key fields:
| Field | Type | Description |
|---|---|---|
y | Matrix | Primal variables |
w | Matrix | Dual variables for equality constraints (Gy = d) |
v | Matrix | Dual variables for inequality constraints (Ay ≥ b) |
status | Symbol | Termination status (see below) |
pobj | Real | Primal objective value |
dobj | Real | Dual objective value |
prFeas | Real | Primal feasibility residual |
duFeas | Real | Dual feasibility residual |
muFeas | Real | Complementarity residual |
Iter | Integer | Number of iterations |
Mu | Real | Final barrier parameter |
Status values:
| Status | Meaning |
|---|---|
:Optimal | Converged to an optimal solution |
:Infeasible | Problem is primal infeasible (validated Farkas ray when has_certificate) |
:Unbounded | Problem is dual infeasible / primal unbounded (validated recession ray when has_certificate) |
:AlmostInfeasible | Iteration limit with a near-validating infeasibility candidate (no certificate) |
:AlmostUnbounded | Iteration limit with a near-validating unboundedness candidate (no certificate) |
:Abandoned | Solver stalled (step size too small or numerical issues) |
:Error | Solver encountered an error |
See Troubleshooting Solver Output in the Mathematical Background for guidance on non-optimal statuses.
Certificate Validation
Infeasibility and unboundedness claims are backed by rays validated against the original problem data. See The Certificate Pipeline in the Mathematical Background.
ConicIP.CertificateCheck — Type
CertificateCheckVerdict returned by the certificate validators.
Fields
valid::Bool– all checks passedfarkas_residual::Float64– ‖·‖_∞ of the linear residual of the rayseparation::Float64– the (pre-normalization) separation value; must be > 0cone_margin::Float64– blockwise minimum cone margin of the ray (≥ 0 if in K)finite::Bool– the candidate ray had only finite entries
ConicIP.cone_margin — Function
cone_margin(x, cone_dims)Blockwise minimum margin of x with respect to the cone K described by cone_dims. Nonnegative iff x ∈ K; the magnitude measures the distance to the boundary (violation depth when negative).
Per block:
"R" minimum(x[I])
"Q" x[I][1] - ‖x[I][2:end]‖
"S" eigmin(Symmetric(mat(x[I])))Returns +Inf when there are no blocks.
ConicIP.validate_infeasibility_certificate — Function
validate_infeasibility_certificate(Q, c, A, b, cone_dims, G, d, w, v;
abstol, reltol)Validate (w,v) as a Farkas ray proving primal infeasibility of {y : Ay ≥_K b, Gy = d}. A valid ray satisfies
Gᵀw̄ - Aᵀv̄ ≈ 0, v̄ ∈ K, dᵀw̄ - bᵀv̄ = -1Returns (check::CertificateCheck, w̄, v̄) with the ray normalized so that dᵀw̄ - bᵀv̄ = -1. If the separation -(dᵀw - bᵀv) is nonpositive, or the candidate has nonfinite entries, the verdict is invalid and the candidates are returned unchanged (no normalization).
ConicIP.validate_unboundedness_certificate — Function
validate_unboundedness_certificate(Q, c, A, b, cone_dims, G, d, y;
abstol, reltol)Validate y as a recession ray proving ½yᵀQy - cᵀy is unbounded below over the feasible set. A valid ray satisfies
Qȳ ≈ 0, Gȳ ≈ 0, Aȳ ∈ K, cᵀȳ = +1so that the objective decreases without bound along ȳ. Returns (check::CertificateCheck, ȳ) with the ray normalized so that cᵀȳ = +1. If the separation cᵀy is nonpositive, or the candidate has nonfinite entries, the verdict is invalid and the candidate is returned unchanged.
When the iterate loop exhausts with evidence of a ray, the solver can recover a certificate by solving an auxiliary min-norm QP:
ConicIP.fallback_infeasibility_ray — Function
fallback_infeasibility_ray(Q, c, A, b, cone_dims, G, d;
kktsolver = default_kktsolver, maxIters = 50)Solve the minimum-norm Farkas auxiliary QP and return a candidate infeasibility ray (w, v), or nothing if the auxiliary solve does not reach :Optimal (which includes the common case that the original problem is feasible, making the auxiliary problem infeasible).
The returned pair is not validated and not normalized — pass it to validate_infeasibility_certificate.
ConicIP.fallback_unbounded_ray — Function
fallback_unbounded_ray(Q, c, A, b, cone_dims, G, d;
kktsolver = default_kktsolver, maxIters = 50)Solve the minimum-norm recession auxiliary QP and return a candidate unboundedness ray y, or nothing if the auxiliary solve does not reach :Optimal (in particular when no recession ray exists).
The Qy = 0 rows are omitted when Q is identically zero, which keeps the auxiliary system at its smallest for the LP case. The returned ray is not validated and not normalized — pass it to validate_unboundedness_certificate.
JuMP / MathOptInterface
ConicIP.Optimizer — Type
Optimizer(; kwargs...)MathOptInterface optimizer wrapping the ConicIP interior-point solver. Use as a JuMP solver via Model(ConicIP.Optimizer).
Options
Settable as constructor keywords or through MOI.RawOptimizerAttribute / JuMP's set_attribute:
verbose::Bool– print solver iterations (default:false)optTol::Float64– optimality tolerance (default:1e-6)maxIters::Int– maximum iterations (default:100)infeasTol::Float64– infeasibility/unboundedness certificate tolerance (default:1e-7)kktsolver–"auto"(default; picks by cone mix and sparsity viachoose_kktsolver),"qr","sparse","2x2", or a solver functionpreprocess::Bool– remove redundant equality rows viapreprocess_conicIPbefore solving (default:true)- plus
infeasAbsTol,DTB,maxRefinementSteps,staticReg,certFallback,certFallbackIters,cache_nestodd— forwarded toconicIP
MOI.Silent is supported and overrides verbose.
Supported Constraints
- Vector:
Zeros,Nonnegatives,Nonpositives,SecondOrderCone,PositiveSemidefiniteConeTriangle - Scalar:
EqualTo,GreaterThan,LessThan
KKT Solver Functions
Three built-in KKT solvers are provided, and the default picks among them automatically per problem. See the KKT Solvers guide for detailed usage and custom solver development.
ConicIP.default_kktsolver — Function
default_kktsolver(Q, A, G, cone_dims)The default kktsolver for conicIP: dispatches to the solver picked by choose_kktsolver. Satisfies the standard kktsolver interface, so it can be passed anywhere a concrete solver can.
ConicIP.choose_kktsolver — Function
choose_kktsolver(Q, A, G, cone_dims; nnz_per_col_max = 10, size_min = 1000)Pick a KKT solver from the problem's cone mix, size, and sparsity (issue #10). Returns one of the solver constructors, chosen by:
- any SDP cone ⇒
kktsolver_qr— the dense double-QR method is the numerically robust choice for the dense SDP scaling blocks; n + m + p < size_min⇒kktsolver_qr— dense factorization wins at small sizes and matches the historical default exactly;- average structural nonzeros per column of
[Q; A; G]abovennz_per_col_max⇒kktsolver_qr— sparse-typed but dense-ish data (e.g. many small SOCs with a 10%-denseA) factors faster densely; - otherwise ⇒
kktsolver_sparse.
The decision is by structural nonzero counts, never by storage type.
ConicIP.kktsolver_qr — Function
Solves the 3x3 system
┌ ┐ ┌ ┐ ┌ ┐
│ Q G' -A' │ │ y' │ = │ y │
│ G │ │ w' │ │ w │
│ A FᵀF │ │ v' │ │ v │
└ ┘ └ ┘ └ ┘by the double QR method described in CVXOPT http://www.seas.ucla.edu/~vandenbe/publications/coneprog.pdf section 10.2
ConicIP.kktsolver_sparse — Function
Solves the 3x3 system
┌ ┐ ┌ ┐ ┌ ┐
│ Q G' -A' │ │ y' │ = │ y │
│ G │ │ w' │ │ w │
│ A FᵀF │ │ v' │ │ v │
└ ┘ └ ┘ └ ┘By lifting the large diagonal plus rank 3 blocks of FᵀF
Intelligently chooses between solve3x3gensparselift and solve3x3gensparsedense by approximating the number of non-zeros in both and choosing the form with more sparsity. The former is better for large second order cones, while the latter is better if the constraints are the product of many small cones.
ConicIP.kktsolver_2x2 — Function
Solves the 2x2 system
┌ ┐ ┌ ┐ ┌ ┐
│ Q + A'F⁻¹F⁻ᵀA G' │ │ y' │ = │ y │
│ G │ │ w' │ │ w │
└ ┘ └ ┘ └ ┘ConicIP.pivot — Function
pivot(kktsolver_2x2)Wrap a 2-by-2 KKT solver into a 3-by-3 solver by pivoting on the third component. The inner solver handles the Schur complement system; pivot reconstructs the full solution.
See also conicIP for the KKT solver interface specification.
Block Diagonal Matrices
The Nesterov-Todd scaling matrix is represented as a block diagonal matrix where each block corresponds to a cone in the cone specification.
ConicIP.Block — Type
Block(size::Int)
Block(Blk::Vector)Block diagonal matrix type. Each diagonal block can be a different matrix type (Diagonal, SymWoodbury, VecCongurance, or dense Matrix).
Used internally to represent the Nesterov-Todd scaling matrix, where each block corresponds to a cone in the cone specification.
Supports arithmetic (*, +, -, inv, adjoint, ^), conversion to sparse and Matrix, and block-wise function application via broadcastf.
Indexing
B[i]returns thei-th diagonal blockB[i] = Msets thei-th diagonal block
ConicIP.block_idx — Function
block_idx(A::Block)Return a vector of UnitRange{Int} giving the row/column index ranges for each diagonal block of A.
ConicIP.broadcastf — Function
broadcastf(op, A::Block)
broadcastf(op, A::Block, B::Block)
broadcastf(op, A::Block, x::Union{Vector,Matrix})Apply function op block-wise to the diagonal blocks of A (and optionally B or the corresponding segments of x).
Utilities
ConicIP.Id — Function
Id(n)Create an n-by-n identity matrix as Diagonal(ones(n)).
ConicIP.VecCongurance — Type
VecCongurance(R)Linear operator representing a congruence transform in vectorized form. The action W * x computes vecm(R' * mat(x) * R).
Used internally as the Nesterov-Todd scaling matrix for semidefinite cones.
ConicIP.mat — Function
mat(x)Convert a vectorized symmetric matrix (scaled lower-triangular form) back to a full symmetric matrix. Inverse of vecm.
ConicIP.mat! — Function
mat!(Z, x)In-place mat: fill the symmetric matrix Z from the vectorized form x. Z must be ord(x) square.
ConicIP.vecm — Function
vecm(Z)Vectorize a symmetric matrix Z into scaled lower-triangular form. Off-diagonal entries are scaled by √2 so that dot(vecm(X), vecm(Y)) == tr(X*Y). Inverse of mat.
ConicIP.vecm! — Function
vecm!(x, Z)In-place vecm: write the vectorized form of the symmetric matrix Z into x, which must have length n(n+1)/2.
ConicIP.imcols — Function
imcols(A, b, ϵ = 1e-8)
Removes redundant inequalities in a system of equations
Ax = b
and checks if the equations are consistent. Returns (R, consistent) where R are the indices of a maximal independent row set.
Internal
These functions are implementation details and not part of the public API.
ConicIP.inv_adjoint! — Function
inv_adjoint!(dest::Block, src::Block)Compute adjoint(inv(src)) block-wise, reusing the dest Block shell. Avoids allocating two intermediate Blocks for inv(F)'.
ConicIP.pivotgen — Function
Wrapper around solve2xegen to solve 3x3 systems by pivoting on the third component.
ConicIP.placeholder — Function
Creates a matrix with the same sparsity structure as F
ConicIP.identical_sparse_structure — Function
Checks if two sparse matrices have the same sparse structure
ConicIP.count_lift — Function
Estimates for the number of nonzeros of lift(F)
ConicIP.count_dense — Function
Estimates the number of nonzeros of F
ConicIP._psd_moi_vecm_info — Function
Return (perm, is_offdiag) where perm[moi_k] is the vecm position for MOI triangle position moi_k, and is_offdiag[moi_k] is true when position moi_k corresponds to an off-diagonal entry.
ConicIP._psd_vecm_to_moi — Function
Convert a vector from vecm order (solver convention) to MOI triangle order, dividing off-diagonal entries by √2.
ConicIP._psd_scale_input! — Function
Reorder rows of Ai and entries of bi from MOI triangle order to vecm order, and scale off-diagonal rows by √2.