On this page:
1.1 The problem SCS solves
1.2 Cones
1.2.1 Box cones
1.2.2 Semidefinite cones
1.3 Building matrices and vectors
1.4 Settings
1.5 Solving and reading results
1.5.1 Direct vs. indirect solver
1.5.2 Warm starting and re-solving
9.2

1 Guide🔗ℹ

1.1 The problem SCS solves🔗ℹ

SCS solves the convex quadratic cone program

minimize (/ 1 2) xᵀPx + cᵀx
subject to Ax + s = b, sK

over the variable x ∈ ℝⁿ and slack s ∈ ℝᵐ, where P is symmetric positive semidefinite, A is m×n, and K is a closed convex cone. SCS simultaneously produces a solution to the dual problem; the dual variable is returned as scs-result-y. See the upstream algorithm notes for the precise primal/dual pair.

In Racket you supply A and the optional P as compressed-sparse-column matrices (scs:matrix / scs:sparse-matrix), b and c as vectors or lists, and K as a make-cone value, then call solve.

1.2 Cones🔗ℹ

The cone K is a Cartesian product of primitive cones. The rows of A (and the entries of b and s) must appear in this exact order, which is also the order of the make-cone keywords:

  • zero cone — #:zero equality rows (s = 0).

  • positive orthant — #:positive inequality rows (s ≥ 0).

  • box cone — #:box-lower / #:box-upper; see Box cones.

  • second-order (Lorentz) cones — #:soc, a list of block sizes; each block (t, u) satisfies ‖u‖₂ ≤ t.

  • positive semidefinite cones — #:psd, a list of matrix dimensions; see Semidefinite cones.

  • exponential cones — #:exp-primal / #:exp-dual counts of triples; the primal cone is the closure of {(x,y,z) : y·e^(x/y) ≤ z, y > 0}.

  • power cones — #:power, a list of parameters in [-1, 1] (negative values select the dual power cone).

This mirrors the cone ordering documented in the SCS cones reference.

1.2.1 Box cones🔗ℹ

The box cone is {(t, r) : t·l ≤ r ≤ t·u} with a leading scale variable t. To impose plain bounds l ≤ y ≤ u, arrange A and b so the first box row’s slack is a constant 1 (a row of zeros in A with the matching b entry equal to 1) and the remaining rows carry y. make-cone takes the bounds with #:box-lower and #:box-upper; their length is the number of box-constrained entries, and SCS’s bsize is that length plus one. Model predictive control is a worked example.

1.2.2 Semidefinite cones🔗ℹ

For a k×k symmetric matrix, the PSD cone slack is the lower triangle stacked column-wise with the off-diagonal entries scaled by √2; the block length is k(k+1)/2. So a 2×2 matrix [[a b] [b c]] is represented by (a, √2·b, c). #:psd takes the list of k values. See the cones reference and Semidefinite program.

1.3 Building matrices and vectors🔗ℹ

scs:matrix builds a matrix from a dense, row-major sequence of values:

(scs:matrix 3 2     ; 3 rows, 2 columns
            -1 1
             1 0
             0 1)

scs:sparse-matrix builds one from explicit (row col value) triples, which is convenient for a quadratic P (supply only the upper triangle):

(scs:sparse-matrix 2 2
                   '(0 0 3)
                   '(0 1 -1)
                   '(1 1 2))

Both return a CSC matrix suitable for #:A or #:P. The right-hand side b and objective c are passed to solve as plain vectors or lists.

1.4 Settings🔗ℹ

make-settings produces a settings value populated with SCS’s defaults, overridden by the keywords you pass. Unlike the C library, verbose? defaults to #f (libraries should be quiet). The most common knobs are the convergence tolerances #:eps-abs and #:eps-rel (SCS default 0.0001) and #:max-iters. See the upstream settings reference for the full list and defaults. Passing no #:settings to solve uses the defaults.

1.5 Solving and reading results🔗ℹ

solve returns an scs-result. Check solved? (true when the exit flag is 1, SCS_SOLVED); scs-result-status is the human-readable status string and scs-result-status-val the integer exit flag. The exit flags follow the SCS exit-flag reference: 1 solved, 2 solved-inaccurate, -1 unbounded, -2 infeasible, and -3 through -7 for the indeterminate/failed/interrupted and inaccurate-certificate cases.

The primal solution is scs-result-x, the dual is scs-result-y, and the slack is scs-result-s; scs-result-pobj and scs-result-dobj are the primal and dual objectives.

1.5.1 Direct vs. indirect solver🔗ℹ

By default solve uses the direct linear-system solver. Pass #:indirect? #t to use the indirect (conjugate-gradient) solver, which can scale better on very large sparse problems.

1.5.2 Warm starting and re-solving🔗ℹ

When a sequence of problems differs only in b or c, you can keep one solver workspace and update it instead of rebuilding from scratch. This is done through the scs/foreign layer with scs-init, scs-update, and scs-solve (passing a warm flag of 1 to the re-solve). Lasso with warm starting and Model predictive control show the pattern.