Skip to content

Operators

Every operator is a discrete-time state-space operator:

y[t]   = g(s[t], u[t], ε[t])      output
s[t+1] = f(s[t], u[t], ε[t])      update

with state s, inputs u, random numbers ε and outputs y. All values are arrays with one entry per lane, so one call steps every lane of a batch.

Four kinds

Kind What it is Examples
Sources No inputs: values from outside the plant. constant, schedule (a profile driven by events), ou, ar, clock
Dynamic operators A response to inputs, usually with a state. first_order, fopdt, integrator, variable_delay, saturation, stiction, sum, product, weighted_mean, log_linear
Feedback operators Controllers. pid (with limits, anti-windup, a filtered derivative and MAN/AUTO/CAS modes)
Observation operators Stages of an instrument. lag, bias, white_noise, clip, quantize, sample_hold, delay, gate

Cascade, ratio, feedforward, split-range and selector control are compositions of these operators, not operators of their own. The operator reference gives each operator's equations, ports and parameters.

Direct feedthrough

An operator declares which inputs affect its output in the same step: its direct feedthrough. A first-order lag has none: its output is its state, so its input only affects the next step. A sum passes every input through at once. The compiler uses these declarations to order the operators in each step and to find algebraic loops (see Graphs and roles).

Parameters

Each operator declares its parameters once, with a unit, a description, a range and whether it may change during a run. The catalog, the reference pages and the scenario checks all come from these declarations.

Parameters are given in physical units: a time constant in seconds, a gain in output units per input unit. Each operator discretizes its equations exactly for the step it runs at (zero-order hold), so changing dt changes the resolution of the data, not the plant, and never requires retuning. A first-order lag with time constant τ uses a = exp(−dt/τ); a first-order-plus-dead-time response handles dead times that are not a whole number of steps. Ornstein–Uhlenbeck sources are given by their stationary standard deviation, which stays the same at any step.

A parameter stays a compiled constant unless an event targets it; then it becomes a signal (see Events). Structural parameters, such as a dead time or a buffer size, cannot change during a run.

Missing values

Linear dynamic operators hold their state when an input is NaN instead of being poisoned by it, so a missing value (a removed sensor, a flow that stopped) does not spread NaN through the plant for the rest of the run. A weighted mean leaves out inputs without weight, so a feed that does not flow needs no defined property.

Small and pure

Operators are small: a template is many tiny operators rather than one big one, which keeps each piece testable and the causal graph fine-grained. output and update are pure functions of arrays, so a fused, compiled step can be generated later.