Docs

Regulation & tracking

Not every loop is an optimization. In regulation you have a target response and you want to hold the measured output at it while the device drifts. This is the runtime's strongest, most-validated regime. Use mode="regulation" or the swc_regulate driver.

Minimal loop

copyfrom swc import swc_regulate

x, history = swc_regulate(
    measure=lambda x: read_output(x),   # current measured response, vector in [0,1]^N
    x0=initial_config,
    target=setpoint_vector,             # where you want the output held
    license_key="EVAL-...",
    rounds=200)
# x is the final configuration; history is the list of configs, one per round
# (history[-1] == x). Compute tracking error yourself from your own measurements.

Full example: tracking a drifting target

A complete loop you can adapt. Each round reads the output once, sends it to the runtime, applies the returned configuration, and logs the tracking error so you can watch it converge and hold.

copyfrom swc import SWCOptimizer
import numpy as np

N = 8
setpoint = np.full(N, 0.5)
opt = SWCOptimizer(license_key="EVAL-...", n=N,
                   mode="regulation", target=list(setpoint))
x = opt.start([1.5708] * N)        # start at pi/2

errors = []
for r in range(200):
    y = read_output(x)             # ONE measurement this round
    x = opt.step(list(y), target=list(setpoint))
    errors.append(float(np.mean((np.asarray(y) - setpoint) ** 2)))
opt.end()

print(f"final tracking MSE: {np.mean(errors[-10:]):.2e}")

Sign-varying plants are handled automatically

You do not need to calibrate or configure anything for plants whose control→observable map has an unusual polarity — including channels whose target sits across zero, negative-gain responses, or mixed sign per channel. At the start of a regulation session the runtime spends a few rounds applying a small probe to measure each channel’s drive direction directly, then drives using what it measured. This is why the loop below, with a target that requires a channel to cross zero, converges with no extra code:

copyfrom swc import SWCOptimizer
import math

N = 4
target_angles = [0.5, -0.3, 1.0, 0.2]            # note the negative
setpoint = [-0.5 * math.sin(a) for a in target_angles]

def read_output(x):
    return [-0.5 * math.sin(xi) for xi in x]     # your plant

with SWCOptimizer(license_key="EVAL-...", n=N,
                  mode="regulation", target=setpoint) as opt:
    x = opt.start([0.0] * N)
    for _ in range(120):
        x = opt.step(read_output(x), target=setpoint)
# every channel reaches its target, including the one that crosses zero

The only requirement is that each channel’s response is locally monotonic — moving the control moves its measurement consistently in one direction over the operating range. Sign, gain, and shape are all learned. See the compatibility page for the full list of plant types this covers.

How it behaves

Regulation is the opposite of decision-style optimization on one axis: more measurements per round reduce the tracking error (roughly as 1/N for N reads), so spend reads here when you need precision. On a simple, well-behaved plant with measurements to spare, a fairly-tuned PI controller matches it — we report that honestly. The runtime separates when measurements are scarce: at one measurement per round under drift it updates every round from a single read, while finite-difference and SPSA gradient methods must spend several measurements per step and fall behind the moving target — 3 to 10 times tighter, widening with channel count. See the regulation demo for a live, equal-budget comparison. If your problem is binary or combinatorial, use optimization mode instead.

Nonlinear plants: where it pulls ahead of tuned PID

A fixed-gain PI or PID controller assumes one slope for the whole operating range. On a non-monotonic or strongly nonlinear plant — where the control→observable slope changes, or even reverses, across the range — that assumption is wrong somewhere, so a fixed-gain controller is necessarily mistuned in part of the space. The runtime re-estimates each channel’s local sensitivity from measurements every round, so it stays matched as the operating point moves. In benchmarks against a best-tuned PI (gains swept to its optimum), the runtime tracks 2–4× tighter on nonlinear plants, and the margin grows with how nonlinear the plant is. The flip side, stated honestly: against an instantaneous catastrophic discontinuity — a sudden full sign reversal of an already-converged channel, or a large step shock — a fixed-sign integral controller can claw back faster than the runtime’s adaptive estimate, so the runtime’s strength is continuous nonlinearity and drift, not abrupt shocks.

Target reachability

The runtime estimates each channel’s drive direction from your measurements, so it adapts to plants whose sensitivity differs from a textbook phase–power transfer, including crossing through zero. The one requirement is that your target must be physically reachable by the channel. If a channel’s output simply cannot reach its target value (for example, asking for a normalized power above 1, or a value the device cannot produce), that channel will settle at the nearest boundary and the step response will include a saturated flag naming it. When you see that flag, rescale or bias the target into the achievable range rather than adding rounds.