ERKStep
The ERKStep factory wraps a configurable explicit Runge–Kutta
integrator. It accepts any ERKTableau
and ships with adaptive integral step-control defaults. The factory performs
staged right-hand-side evaluations on the GPU and supports optional driver
and observable callbacks.
Defaults
algorithm="erk" integrates with the dormand-prince-54
tableau — explicit Dormand–Prince 5(4), seven stages, with an
embedded fourth-order error estimate — under adaptive integral
control (integral_gain=1.2, safety=0.9, step-size growth clamped
to 0.2–10.0×). dopri54, rk45, and ode45 are aliases for
the same scheme; the other named schemes in the
ERK tableau registry resolve to this
class too, falling back to fixed-step control when a tableau has no
error estimate (Default settings). Explicit methods need no
nonlinear or linear solver.
- class cubie.integrators.algorithms.ERKStep(precision: type[float16] | type[float32] | type[float64] | dtype[float16] | dtype[float32] | dtype[float64], n_states: int, dxdt_fn: Callable | None = None, observables_fn: Callable | None = None, drivers_fn: Callable | None = None, get_solver_helper_fn: Callable | None = None, tableau: ERKTableau = ERKTableau(a=((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.075, 0.225, 0.0, 0.0, 0.0, 0.0, 0.0), (0.9777777777777777, -3.7333333333333334, 3.5555555555555554, 0.0, 0.0, 0.0, 0.0), (2.9525986892242035, -11.595793324188385, 9.822892851699436, -0.2908093278463649, 0.0, 0.0, 0.0), (2.8462752525252526, -10.757575757575758, 8.906422717743473, 0.2784090909090909, -0.2735313036020583, 0.0, 0.0), (0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0)), b=(0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0), c=(0.0, 0.2, 0.3, 0.8, 0.8888888888888888, 1.0, 1.0), order=5, b_hat=(0.08991319444444444, 0.0, 0.4534890685834082, 0.6140625, -0.2715123820754717, 0.08904761904761904, 0.025), embedded_order=4, dense_prediction_ratio_float16=0.0, dense_prediction_ratio_float32=0.0, dense_prediction_ratio_float64=0.0, defaults={}), n_drivers: int = 0, **kwargs)[source]
Bases:
ODEExplicitStepGeneric explicit Runge–Kutta step with configurable tableaus.
- __init__(precision: type[float16] | type[float32] | type[float64] | dtype[float16] | dtype[float32] | dtype[float64], n_states: int, dxdt_fn: Callable | None = None, observables_fn: Callable | None = None, drivers_fn: Callable | None = None, get_solver_helper_fn: Callable | None = None, tableau: ERKTableau = ERKTableau(a=((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.075, 0.225, 0.0, 0.0, 0.0, 0.0, 0.0), (0.9777777777777777, -3.7333333333333334, 3.5555555555555554, 0.0, 0.0, 0.0, 0.0), (2.9525986892242035, -11.595793324188385, 9.822892851699436, -0.2908093278463649, 0.0, 0.0, 0.0), (2.8462752525252526, -10.757575757575758, 8.906422717743473, 0.2784090909090909, -0.2735313036020583, 0.0, 0.0), (0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0)), b=(0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0), c=(0.0, 0.2, 0.3, 0.8, 0.8888888888888888, 1.0, 1.0), order=5, b_hat=(0.08991319444444444, 0.0, 0.4534890685834082, 0.6140625, -0.2715123820754717, 0.08904761904761904, 0.025), embedded_order=4, dense_prediction_ratio_float16=0.0, dense_prediction_ratio_float32=0.0, dense_prediction_ratio_float64=0.0, defaults={}), n_drivers: int = 0, **kwargs) None[source]
Initialise the Runge–Kutta step configuration.
This constructor creates an ERK step object and automatically selects appropriate default step controller settings based on whether the tableau has an embedded error estimate. Tableaus with error estimates default to adaptive stepping (integral controller), while errorless tableaus default to fixed stepping.
- Parameters:
precision – Floating-point precision for CUDA computations (np.float32 or np.float64).
n_states – Number of state variables in the ODE system.
dxdt_fn – Compiled CUDA device function computing state derivatives. Should match signature expected by the integration kernel.
observables_fn – Optional compiled CUDA device function computing observable quantities from the state.
drivers_fn – Optional compiled CUDA device function computing time-varying driver inputs.
get_solver_helper_fn – Factory function returning solver helper for implicit stages (not used in explicit methods but included for interface consistency).
tableau – Explicit Runge–Kutta tableau describing the coefficients used by the integrator. Defaults to
DEFAULT_ERK_TABLEAU(Dormand-Prince 5(4)).n_drivers – Number of driver variables in the system.
**kwargs – Optional parameters passed to config classes. See ERKStepConfig for available parameters. None values are ignored.
Notes
The step controller defaults are selected dynamically:
If
tableau.has_error_estimateisTrue: UsesERK_ADAPTIVE_DEFAULTS(integral controller)If
tableau.has_error_estimateisFalse: UsesERK_FIXED_DEFAULTS(fixed-step controller)
This automatic selection prevents incompatible configurations where an adaptive controller is paired with an errorless tableau. Users can still override these defaults by explicitly specifying step controller settings when creating a
Solveror callingsolve_ivp().Examples
Create an ERK step with the default Dormand-Prince tableau:
>>> from cubie.integrators.algorithms.generic_erk import ERKStep >>> import numpy as np >>> step = ERKStep(precision=np.float32,n_states=3) >>> step.algorithm_defaults["step_controller"] 'i'
Create an ERK step with Classical RK4 (errorless):
>>> from cubie.integrators.algorithms.generic_erk_tableaus import ( ... CLASSICAL_RK4_TABLEAU ... ) >>> step = ERKStep( ... precision=np.float32, n_states=3, tableau=CLASSICAL_RK4_TABLEAU ... ) >>> step.algorithm_defaults["step_controller"] 'fixed'
- build_step(dxdt_fn: Callable, observables_fn: Callable, drivers_fn: Callable | None, numba_precision: type, n: int, n_drivers: int) StepCache[source]
Compile the explicit Runge–Kutta device step.
- default_tableau = ERKTableau(a=((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.075, 0.225, 0.0, 0.0, 0.0, 0.0, 0.0), (0.9777777777777777, -3.7333333333333334, 3.5555555555555554, 0.0, 0.0, 0.0, 0.0), (2.9525986892242035, -11.595793324188385, 9.822892851699436, -0.2908093278463649, 0.0, 0.0, 0.0), (2.8462752525252526, -10.757575757575758, 8.906422717743473, 0.2784090909090909, -0.2735313036020583, 0.0, 0.0), (0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0)), b=(0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0), c=(0.0, 0.2, 0.3, 0.8, 0.8888888888888888, 1.0, 1.0), order=5, b_hat=(0.08991319444444444, 0.0, 0.4534890685834082, 0.6140625, -0.2715123820754717, 0.08904761904761904, 0.025), embedded_order=4, dense_prediction_ratio_float16=0.0, dense_prediction_ratio_float32=0.0, dense_prediction_ratio_float64=0.0, defaults={})
Tableau a bare family alias builds on;
Nonefor fixed schemes.
- classmethod family_defaults(tableau=None) AlgorithmDefaults[source]
Adaptive or fixed defaults by the tableau’s error estimate.
- property optimisation_candidates: Tuple[Dict[str, Any], ...]
other_smallunrolling crossed withstateplacement, plus a sharedstage_rhsat full unrolling.
- class cubie.integrators.algorithms.generic_erk.ERKStepConfig(precision: type[float16] | type[float32] | type[float64] | dtype[float16] | dtype[float32] | dtype[float64], n_states: int = 1, n_drivers: int = 0, is_adaptive: bool = True, dxdt_fn: Callable | None = None, observables_fn: Callable | None = None, drivers_fn: Callable | None = None, get_solver_helper_fn: Callable | None = None, tableau: ERKTableau = ERKTableau(a=((0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), (0.075, 0.225, 0.0, 0.0, 0.0, 0.0, 0.0), (0.9777777777777777, -3.7333333333333334, 3.5555555555555554, 0.0, 0.0, 0.0, 0.0), (2.9525986892242035, -11.595793324188385, 9.822892851699436, -0.2908093278463649, 0.0, 0.0, 0.0), (2.8462752525252526, -10.757575757575758, 8.906422717743473, 0.2784090909090909, -0.2735313036020583, 0.0, 0.0), (0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0)), b=(0.09114583333333333, 0.0, 0.44923629829290207, 0.6510416666666666, -0.322376179245283, 0.13095238095238096, 0.0), c=(0.0, 0.2, 0.3, 0.8, 0.8888888888888888, 1.0, 1.0), order=5, b_hat=(0.08991319444444444, 0.0, 0.4534890685834082, 0.6140625, -0.2715123820754717, 0.08904761904761904, 0.025), embedded_order=4, dense_prediction_ratio_float16=0.0, dense_prediction_ratio_float32=0.0, dense_prediction_ratio_float64=0.0, defaults={}), stage_rhs_location: str = 'local', stage_accumulator_location: str = 'local', *, jit_flags: JITFlags = NOTHING, unroll: UnrollFlags = NOTHING)[source]
Bases:
ExplicitStepConfigConfiguration describing an explicit Runge–Kutta integrator.
- Parameters:
tableau (cubie.integrators.algorithms.generic_erk_tableaus.ERKTableau) – Butcher tableau coefficients for the ERK method.
stage_rhs_location (str) – Memory location for the stage RHS buffer (
'local'or'shared').stage_accumulator_location (str) – Memory location for the stage accumulator buffer (
'local'or'shared').
- tableau: ERKTableau