On this page:
<require>
<provide>
3.8.1 Building the solver
<setup>
3.8.2 Solve, update, re-solve
<run>
<run-example>
<*>

3.8 Warm starting and re-solving🔗ℹ

When you solve a sequence of problems that differ only in the right-hand side b or the objective c, you can keep one solver, swap in the new data, and re-solve warm starting from the previous solution. This is much cheaper than rebuilding from scratch, and it is the pattern behind the lasso (Lasso along a regularization path) and MPC (Model predictive control) examples.

The high-level make-solver builds a reusable solver; solver-solve! solves it (warm starting automatically on every call after the first), and solver-update! swaps in a new b and/or c. No native memory is managed by hand.

We reuse the linear program of Linear program, solving first with bounds b = (1, 1) (giving x = (1, 1)), then updating to b = (2, 3) (giving x = (2, 3)).

(require scs)

(provide run-example)

3.8.1 Building the solver🔗ℹ

make-solver takes the same problem description as solve the constraint matrix, the right-hand side, the objective, and the cone — but returns a reusable solver instead of solving immediately:

(define A
  (scs:matrix 4 2
               1   0
               0   1
              -1   0
               0  -1))
(define s
  (make-solver #:A A
               #:b #(1.0 1.0 0.0 0.0)
               #:c #(-1.0 -1.0)
               #:cone (make-cone #:positive 4)
               #:settings (make-settings #:eps-abs 1e-9 #:eps-rel 1e-9)))

3.8.2 Solve, update, re-solve🔗ℹ

The first solver-solve! is a cold start. solver-update! swaps in the new b, and the second solver-solve! warm starts from the previous iterate automatically:

<run> ::=
(define r1 (solver-solve! s))
(define x1 (scs-result-x r1))
 
(solver-update! s #:b #(2.0 3.0 0.0 0.0))
(define r2 (solver-solve! s))
(define x2 (scs-result-x r2))
 
(list (list (scs-result-exit-flag r1) x1)
      (list (scs-result-exit-flag r2) x2))

(define (run-example)
  <setup>
  <run>)

Running it.

(run-example)
; '((1 #(1.0 1.0)) (1 #(2.0 3.0)))

For full control — driving the C workspace directly, custom solution buffers, deterministic release — the scs/foreign layer is still available; make-solver is the ergonomic path for the common case.

<*> ::=