Operator Calculus, Co.
Browse Studio documentation
On this page

Quick Reference πŸ“Œ

  • integrator_info(ctx) β€” snapshot the attached integrator’s current parameters.
  • set_integrator_* setters β€” tune adaptive, noise, and timestep parameters at runtime without recreating the integrator.
  • integrator_step(ctx, integrator[, dt[, auto_advance]]) β€” manually drive a single integrator step outside the main ooc.step loop.
  • step_metrics_latest(ctx) β€” timing and error for the most recent step.
  • step_metrics_history(ctx[, limit]) β€” ring-buffer of up to 128 past step metrics tables.

Integrator Info πŸ”

Returns a table describing the currently attached integrator, or nil if no integrator is attached.

local info = ooc.integrator_info(ctx)
if info then
    ooc.log("method=%s adaptive=%s current_dt=%.4f",
        info.name, tostring(info.adaptive_enabled), info.current_dt)
end

Returned Fields

Field Type Description
name string Integrator type name (e.g. "rk4", "rkf45")
adaptive_enabled boolean Whether adaptive step-size control is active
enable_stochastic boolean Whether stochastic noise injection is on
stochastic_strength double Noise amplitude
noise string Active noise type ("gaussian", "uniform", "laplace")
random_seed integer Current RNG state seed
min_dt double Minimum allowed timestep
max_dt double Maximum allowed timestep
current_dt double Most recently accepted timestep
tolerance double Normalized error tolerance for adaptive control; RKF45 uses a scaled infinity norm for real fields and scaled RMS magnitude for complex fields
safety double Safety factor for next-step prediction

Tip

integrator_info reflects the primary attached integrator. When using set_integrator_sequence, it returns info for the first integrator in the sequence.


Runtime Setters πŸ”§

All setters operate on the currently attached integrator (or the primary integrator in a sequence). They return true on success and false if no integrator is attached or the operation is not supported by the active method.

Adaptive Control

set_integrator_adaptive(ctx, enabled)

Enable or disable adaptive step-size control.

ooc.set_integrator_adaptive(ctx, true)

set_integrator_min_dt(ctx, value)

Set the minimum timestep for adaptive control.

ooc.set_integrator_min_dt(ctx, 1.0e-5)

set_integrator_max_dt(ctx, value)

Set the maximum timestep for adaptive control.

ooc.set_integrator_max_dt(ctx, 0.5)

set_integrator_tolerance(ctx, value)

Set the RMS error tolerance that governs step acceptance.

ooc.set_integrator_tolerance(ctx, 1.0e-4)

set_integrator_safety(ctx, value)

Set the safety factor (typically 0.8–0.95) applied when predicting the next step size.

ooc.set_integrator_safety(ctx, 0.85)

Stochastic Noise

set_integrator_stochastic(ctx, enabled)

Enable or disable stochastic noise injection.

ooc.set_integrator_stochastic(ctx, true)

set_integrator_stochastic_strength(ctx, strength)

Set the noise amplitude.

ooc.set_integrator_stochastic_strength(ctx, 0.05)

set_integrator_noise(ctx, name)

Set the noise distribution. Accepted values: "gaussian", "uniform", "laplace".

ooc.set_integrator_noise(ctx, "laplace")

set_integrator_seed(ctx, seed)

Set the RNG seed (positive integer). Pass 0 to auto-reseed.

ooc.set_integrator_seed(ctx, 42)

Integrator Step πŸš€

Manually drives a single integrator step. Useful for custom step loops, multi-rate schemes, or testing integrators in isolation.

Argument Type Default Description
ctx context β€” Simulation context
integrator integrator handle β€” The integrator to step
dt double context timestep Requested timestep; must be positive
auto_advance boolean true When true, advances the simulation clock by the accepted step and records step metrics automatically

Returns: true on success, or false, error_code on failure.

When auto_advance = true, the function calls sim_context_accept_step (advancing time) and sim_context_record_step_metrics (updating the history ring). Set auto_advance = false only for caller-owned probe steps where you intentionally do not want public time counters or step metrics advanced. There is no companion integrator_step(..., 0, true) β€œcommit later” flow; if you need normal time advancement and metrics, keep auto_advance = true.

local integrator = ooc.create_context_integrator(ctx, "rk4", { initial_dt = 0.01 })

-- Manual step loop
for i = 1, 1000 do
    local ok, err = ooc.integrator_step(ctx, integrator, 0.01)
    if not ok then
        ooc.log("step failed: code %d", err)
        break
    end
end

Step Metrics πŸ“ˆ

Step metrics are recorded automatically by ooc.step and by integrator_step when auto_advance = true. Up to 128 steps are kept in a ring buffer.

step_metrics_latest(ctx)

Returns the most recent step’s metrics table, or nil if no step has been taken.

local m = ooc.step_metrics_latest(ctx)
if m then
    ooc.log("step=%d accepted_dt=%.4f rms_err=%.2e wall=%.2fms",
        m.step_index, m.accepted_dt, m.rms_error, m.step_wall_ms)
end

step_metrics_history(ctx[, limit])

Returns an array of up to limit recent step metric tables (oldest first), capped at 128. Defaults to returning the full 128-entry history.

local history = ooc.step_metrics_history(ctx, 20)
for _, m in ipairs(history) do
    ooc.log("[%d] dt=%.4f err=%.2e", m.step_index, m.accepted_dt, m.rms_error)
end

Step Metrics Fields

Field Type Description
step_index integer Monotonically increasing step counter
requested_dt double The dt that was requested
accepted_dt double The dt actually committed (may differ for adaptive methods)
next_dt double Predicted next step size (adaptive only)
rms_error double Normalized error estimate from the active method. RKF45 uses a scaled infinity norm for real fields and scaled RMS magnitude for complex fields.
step_wall_ns integer Total wall-clock time for the step in nanoseconds
step_wall_ms double Same, in milliseconds
integrator_wall_ns integer Time spent inside the integrator only (nanoseconds)
integrator_wall_ms double Same, in milliseconds
operator_wall_ns integer Time spent evaluating operators (nanoseconds)
operator_wall_ms double Same, in milliseconds
dirty_writes integer Number of operator writes that modified field state
stable_writes integer Number of operator writes that left field state unchanged
active_warp_mask integer Internal bitmask of active operator warps

Usage Examples πŸ“–

Monitor adaptive step drift

ooc.set_integrator_adaptive(ctx, true)
ooc.set_integrator_tolerance(ctx, 5.0e-5)

for step = 1, 500 do
    ooc.step(ctx)
    local m = ooc.step_metrics_latest(ctx)
    if m and m.rms_error > 1.0e-3 then
        ooc.log("warning: high error at step %d (err=%.2e, dt=%.4f)",
            m.step_index, m.rms_error, m.accepted_dt)
    end
end

Performance profiling with history

for i = 1, 200 do ooc.step(ctx) end

local history = ooc.step_metrics_history(ctx)
local total_ms = 0.0
for _, m in ipairs(history) do
    total_ms = total_ms + m.step_wall_ms
end
ooc.log("avg step wall: %.3f ms over %d samples", total_ms / #history, #history)