Drivers¶
External forcing functions that inject the drive signal Ψ(t) into the Kuramoto equation. The built-in drivers cover the standard physical, informational, and symbolic channel profile. Binding specs may also preserve named driver sections for extension channels, while custom actuation code decides how those channels affect Ψ(t).
Pipeline position¶
PhysicalDriver.compute(t) ──→ Ψ_P(t)
InformationalDriver.compute(t) ──→ Ψ_I(t) ──→ UPDEEngine.step(..., ζ, Ψ, ...)
SymbolicDriver.compute(step) ──→ Ψ_S(k)
SupervisorPolicy.decide() ──→ ControlAction(knob="zeta") ──→ ζ(t)
The supervisor controls the drive strength ζ; the driver controls the drive phase Ψ. Together they form the external forcing term ζ·sin(Ψ - θ_i) in the Kuramoto ODE.
Common interface¶
All drivers implement compute(t_or_step) → float for single evaluation
and compute_batch(array) → NDArray for vectorised evaluation.
Theory¶
The drive term in the Kuramoto ODE is:
The third term \(\zeta \sin(\Psi - \theta_i)\) represents external forcing. The supervisor controls \(\zeta\) (drive strength); the driver controls \(\Psi\) (drive phase). When \(\zeta > 0\), oscillators are pulled toward the target phase \(\Psi(t)\).
Physical Driver¶
Sinusoidal external drive:
Models periodic physical forcing — cardiac pacemaker signals, power grid reference frequency (50/60 Hz), mechanical vibration sources, plasma heating pulses.
Parameters:
| Parameter | Type | Constraint | Description |
|---|---|---|---|
frequency |
float |
> 0 | Drive frequency in Hz |
amplitude |
float |
>= 0 | Peak amplitude (default 1.0) |
Batch mode: compute_batch(t_array) vectorises over a NumPy array
of time values for efficient integration.
psi_physical ¶
Physical-channel sinusoidal reference-phase driver.
PhysicalDriver generates finite sinusoidal drive values from a positive
frequency and non-negative amplitude. Scalar and vector compute paths reject
boolean, complex, non-numeric, and non-finite time inputs so external forcing
cannot inject invalid values into UPDE integration.
Classes¶
PhysicalDriver ¶
Sinusoidal external drive: Psi_P(t) = amplitude * sin(2pifrequency*t).
Initialise a physical sinusoidal reference driver.
Parameters¶
frequency : float Positive drive frequency in hertz. amplitude : float, default=1.0 Non-negative peak drive amplitude.
Raises¶
ValueError If either parameter is a boolean alias, non-real, non-finite, or outside its allowed numeric range.
Source code in src/scpn_phase_orchestrator/drivers/psi_physical.py
Methods:¶
compute ¶
compute_batch ¶
Vectorised Psi_P over an array of time values.
Parameters¶
t_array : FloatArray
Time samples, shape (T,).
Returns¶
FloatArray Vectorised Psi_P over an array of time values.
Source code in src/scpn_phase_orchestrator/drivers/psi_physical.py
Informational Driver¶
Linear ramp drive with modular wrapping:
Models information cadence — packet arrival rates, event stream clocks, data pipeline heartbeats. The phase advances at a constant rate \(f_c\) Hz, producing a sawtooth waveform that resets at \(2\pi\).
This driver is appropriate when the domain has a natural clock rate (e.g. 100 Hz monitoring cadence) and the goal is to synchronise oscillators to that cadence.
Parameters:
| Parameter | Type | Constraint | Description |
|---|---|---|---|
cadence_hz |
float |
> 0 | Information cadence in Hz |
psi_informational ¶
Informational-channel cadence reference-phase driver.
InformationalDriver maps a positive event cadence to wrapped phase-drive
values in [0, 2*pi). Constructor and compute paths reject invalid numeric
inputs so cadence-driven forcing remains bounded and deterministic.
Classes¶
InformationalDriver ¶
External drive Psi_I(t) = 2picadence_hzt (mod 2pi).
Initialise an informational cadence reference driver.
Parameters¶
cadence_hz : float Positive event cadence in hertz.
Raises¶
ValueError If the cadence is a boolean alias, non-real, non-finite, or not positive.
Source code in src/scpn_phase_orchestrator/drivers/psi_informational.py
Methods:¶
compute ¶
compute_batch ¶
Vectorised Psi_I over an array of time values.
Parameters¶
t_array : FloatArray
Time samples, shape (T,).
Returns¶
FloatArray Vectorised Psi_I over an array of time values.
Source code in src/scpn_phase_orchestrator/drivers/psi_informational.py
Symbolic Driver¶
Deterministic phase sequence:
where \(s = [s_0, s_1, \ldots, s_{N-1}]\) is a pre-defined phase sequence that repeats with period \(N\).
Models symbolic/semiotic patterns — language token sequences, musical motifs, protocol state machines, ritual rhythms. The sequence encodes a pattern that the oscillator network is driven to reproduce.
Parameters:
| Parameter | Type | Constraint | Description |
|---|---|---|---|
sequence |
list[float] |
non-empty | Phase values (radians) |
Usage:
from scpn_phase_orchestrator.drivers.psi_symbolic import SymbolicDriver
# Musical 4/4 pattern: downbeat, weak, medium, weak
pattern = [0.0, np.pi, np.pi/2, np.pi]
driver = SymbolicDriver(pattern)
# Step 0 → 0.0, step 1 → π, step 4 → 0.0 (wraps)
psi = driver.compute(step=0)
psi_symbolic ¶
Symbolic-channel cyclic sequence reference driver.
SymbolicDriver exposes deterministic cyclic lookup over finite real symbolic
phase values. It rejects empty, boolean-containing, multi-dimensional,
non-finite, or non-integer step inputs before returning drive values for
symbolic or semiotic simulations.
Classes¶
SymbolicDriver ¶
Deterministic phase sequence driver for symbolic/semiotic channels.
Initialise a cyclic symbolic reference sequence.
Parameters¶
sequence : list[float] Non-empty one-dimensional phase sequence in radians.
Raises¶
ValueError If the sequence is empty, multi-dimensional, non-finite, or carries Python or NumPy boolean aliases.
Source code in src/scpn_phase_orchestrator/drivers/psi_symbolic.py
Methods:¶
compute ¶
compute_batch ¶
Vectorised symbolic phase lookup over an array of step indices.
Parameters¶
steps : IntArray Number of replay steps.
Returns¶
FloatArray Vectorised symbolic phase lookup over an array of step indices.
Source code in src/scpn_phase_orchestrator/drivers/psi_symbolic.py
API summary¶
All drivers share the same interface:
| Method | Signature | Description |
|---|---|---|
compute |
(t: float) → float or (step: int) → float |
Single evaluation |
compute_batch |
(array) → NDArray |
Vectorised evaluation |
Input validation¶
| Driver | Validation | Raises |
|---|---|---|
| PhysicalDriver | frequency > 0, amplitude >= 0, finite real scalar and vector time inputs, no Python or NumPy boolean aliases |
ValueError |
| InformationalDriver | cadence_hz > 0, finite real scalar and vector time inputs, no Python or NumPy boolean aliases |
ValueError |
| SymbolicDriver | len(sequence) > 0, one-dimensional finite real sequence, integer step inputs, no Python or NumPy boolean aliases |
ValueError |
Output ranges¶
| Driver | Output range |
|---|---|
| PhysicalDriver | [-amplitude, +amplitude] |
| InformationalDriver | [0, 2π) |
| SymbolicDriver | values from input sequence |
Integration example¶
from scpn_phase_orchestrator.drivers.psi_physical import PhysicalDriver
from scpn_phase_orchestrator.upde.engine import UPDEEngine
driver = PhysicalDriver(frequency=1.0, amplitude=0.5)
eng = UPDEEngine(n=8, dt=0.01)
for step_i in range(1000):
t = step_i * 0.01
psi = driver.compute(t) # Ψ(t)
zeta = 0.3 # from supervisor
phases = eng.step(phases, omegas, knm, zeta, psi, alpha)
The compute_batch method is useful when pre-computing an
entire Ψ trajectory:
import numpy as np
t_array = np.arange(0, 10.0, 0.01)
psi_trajectory = driver.compute_batch(t_array)
Choosing a driver¶
| Domain | Driver | Rationale |
|---|---|---|
| Power grid (50 Hz) | PhysicalDriver(50.0) | Reference frequency |
| Cardiac pacemaker | PhysicalDriver(1.2) | Heart rate |
| API monitoring (100 Hz) | InformationalDriver(100.0) | Polling cadence |
| Protocol FSM | SymbolicDriver([0, π/2, π, 3π/2]) | State sequence |
| Music sync | SymbolicDriver(beat_phases) | Rhythm pattern |
| No external drive | Set ζ = 0 | Third term vanishes |