ButcherTableau
ButcherTableau(a: tuple[tuple[float, ...], ...], b: tuple[float, ...], c: tuple[float, ...], order: int, name: str, b_error: tuple[float, ...] | None = None, mid: tuple[float, ...] | None = None)Coefficient table defining one explicit Runge-Kutta method.
Given a step from to , the method evaluates stage derivatives and combines them into the new state:
Parameters
atuple of tuple of floati holds exactly i entries, so a[0]
is empty. An implicit method needs those entries, so it is written
square: every row holds all s. Sequences of any kind are accepted
and coerced to nested tuples.btuple of float1.ctuple of floati must equal
sum(a[i]), the standard consistency condition.orderintnamestrb_errortuple of float= Noneis_adaptive reports. Must sum
to 0, since both solutions are consistent.midtuple of float= Noneb_error is given.Raises
ValueErrora / b / c disagree on stage count, if any row of a
has the wrong length for a strictly lower-triangular matrix, if b
does not sum to 1, if any c[i] != sum(a[i]), or if order
or name are unset.Notes
Six derived properties read the table rather than being stored on it, so they cannot fall out of step with the coefficients:
stages— how many derivatives a step evaluates,len(b).is_adaptive— whetherb_erroris present, which is what sends a solve to the adaptive stepper instead of the fixed-grid one.is_implicit— whether any stage depends on itself or on a later one, which is what forces a nonlinear solve per step.is_dirk— whether the stage matrix is lower triangular including the diagonal, so the stages can be solved one at a time.is_fsal— whether the last stage already evaluated the right-hand side at the new state, in which case the next step reuses it and the method costs one evaluation less than it has stages.mid_order— the order to whichmidreproduces the true midpoint. This bounds every interpolated value and is not implied byorder: a method can take third-order steps and interpolate to first.
The constructor validates the table on the way in — stage counts agree,
b sums to one, each c[i] equals sum(a[i]), and b_error
sums to zero — so an inconsistent tableau fails where it is written rather
than as a silent loss of order several steps into a solve.
Examples
The classical fourth-order method, written out in full:
>>> import lucid.diffeq as diffeq
>>> rk4 = diffeq.ButcherTableau(
... a=((), (0.5,), (0.0, 0.5), (0.0, 0.0, 1.0)),
... b=(1 / 6, 1 / 3, 1 / 3, 1 / 6),
... c=(0.0, 0.5, 0.5, 1.0),
... order=4,
... name="rk4",
... )
>>> rk4.stages
4See Also
- lucid.diffeq.odeint—Consumes a tableau, by name or by instance.
Used by 8
Constructors
1Properties
6bool: Whether the tableau carries an embedded error estimate.
Adaptive methods pair two solutions of different order; their weight
difference (b_error) estimates the local error, which is what a
step-size controller needs. A tableau without it can only be stepped
on a fixed grid.
bool: Whether the stage matrix is lower triangular, diagonal included.
Diagonally implicit methods still couple each stage to itself, but not
to any stage after it, so the stages can be solved one at a time. For
a state of n elements that means s solves of size n rather
than one of size s*n — the difference between a dense Jacobian of
n**2 entries and one of (s*n)**2.
bool: Whether the last stage derivative equals f(t + dt, y_next).
True when the final stage row reproduces the solution weights, so the stage already evaluated the right-hand side at the new state. That derivative can then be reused as the next step's first stage, saving one call per accepted step — a real saving when the right-hand side is a neural network.
bool: Whether any stage depends on itself or on a later stage.
An explicit method computes its stages in order, each from the ones before it. An implicit one does not: the stage equations are coupled, so a step has to solve a nonlinear system instead of evaluating a recipe. That is a different solver, not a different coefficient set, which is what this flag selects.
int: Order to which mid reproduces the state at the midpoint.
Zero when the tableau carries no mid at all.
The dense output is a quartic anchored on the midpoint estimate, so
this bounds how accurate any interpolated value can be — and it is not
implied by order. Several tableaux pair a genuinely derived
interpolant with their steps (dopri5 and tsit5 reach 4 here,
dopri8 reaches 5) while others carry only a first-order
placeholder: a half-step of Euler, which is what mid reduces to
when its weights put 1/2 in a single slot. bosh3 takes third
order steps and interpolates to first, and nothing about the method's
name says so.
Computed from the quadrature conditions the midpoint weights would have to satisfy, the same way the collocation tableaux verify their own order at import:
int: Number of stage derivatives evaluated per step.
Equals the number of right-hand-side calls the method makes for each step, which is the dominant cost when the right-hand side is a neural network.