chc.dynamics¶
Stability tier: stable.
Dynamics: the known mechanism, the learned residual, and their additive hybrid.
Dynamics
¶
Bases: Protocol
A vector field f(t, x, u) -> dx/dt.
DampedOscillator
¶
Bases: Module
Known 2-state linear system: a driven damped harmonic oscillator.
State x = [position, velocity], control u = [force]:
ẍ + 2ζω ẋ + ω² x = u.
omega and zeta are kept as (dynamic) leaves so they can later be identified as
physical parameters p rather than hard-coded.
LinearDynamics
¶
Bases: Module
Known linear system ẋ = A x + B u; the exactly-integrable part used in splitting.
HybridDynamics
¶
Bases: Module
f(x, u, t) = f_known(x, u, t) + r_θ(x, u, t).
The residual carries only the unknown part. With a ZeroResidual this
reduces exactly to the known dynamics.
Fitting the residual by prediction error (chc.train) makes its control channel the
observational response, which is the wrong object under a confounded logging policy;
chc.dynamics_id.fit_causal_residual is the identified alternative, restricted to a
control-affine residual.
DrivenDynamics
¶
Bases: Module
f(t, x, u) + G w(t): a plant pushed by exogenous drivers whose path the plan can see.
levels[k] is the drivers' value at t = start + k * dt, and between two points they move
linearly -- a first-order hold. A zero-order hold would not do: RK4's last stage of step k
is the first of step k + 1, both at t = (k + 1) * dt, so no function of t alone can
hold one level through a step. Past either end the nearest segment is extended, so a plan
longer than the forecast extrapolates it; a horizon-step plan wants horizon + 1 levels.
The term reads neither x nor u. It moves the drift and never the control channel, so
what is priced on the channel -- the barrier's gamma*, the tube's model error -- is left
alone, and the forecast enters the barrier's drift term at every step.
drivers(t)
¶
The drivers at time t, linear between the two grid points around it.