SCS: Splitting Conic Solver
SCS (Splitting Conic Solver) is a numerical optimization package for solving large-scale convex cone problems, including linear programs (LPs), second-order cone programs (SOCPs), and semidefinite programs (SDPs). It uses an operator-splitting method (ADMM) with Anderson acceleration for fast convergence. The current version is 3.2.11, with frequent patch releases.
Warnings
- gotcha Installing SCS with optional backends (MKL, GPU) requires specific `pip install -Csetup-args` flags and pre-installed libraries (e.g., MKL, cuDSS, CUDA Toolkit). A standard `pip install scs` will use the default sparse direct solver (QDLDL), which may not be optimal for performance-critical applications.
- gotcha Problem data `P` and `A` must be `scipy.sparse.csc_matrix`, and `b` and `c` must be `numpy.ndarray`. While SCS attempts conversion, providing data in the correct format directly avoids potential overhead or unexpected behavior.
- gotcha SCS versions before 3.x have experienced compatibility issues with newer NumPy versions, sometimes failing installation or requiring specific NumPy versions to be pre-installed.
- gotcha Warm-starting solutions can significantly improve performance for solving sequences of similar problems, but incorrect use or stale warm-start data can lead to slower convergence or suboptimal results.
Install
-
pip install scs -
pip install scs -Csetup-args=-Dlink_mkl=true -
pip install scs -Csetup-args=-Dlink_cudss=true -Csetup-args=-Dint32=true
Imports
- SCS
import scs solver = scs.SCS(data, cone)
Quickstart
import numpy as np
import scipy.sparse as sp
import scs
# Define problem dimensions
m, n = 4, 2
# Create problem data matrices (P, A as sparse CSC, b, c as numpy arrays)
P = sp.eye(n, format="csc") # Quadratic cost (identity for simplicity)
A = sp.random(m, n, density=0.5, format="csc", random_state=1)
b = np.random.randn(m)
c = np.random.randn(n)
data = {"P": P, "A": A, "b": b, "c": c}
# Define the cone: 'l' for non-negative cone of length m
cone = {"l": m}
# Initialize the SCS solver
solver = scs.SCS(data, cone, verbose=False)
# Solve the problem
sol = solver.solve()
print(f"Solver status: {sol['info']['status']}")
if sol['info']['status'] == 'solved':
print(f"Primal solution (x): {sol['x']}")
print(f"Dual solution (y): {sol['y']}")