solprop.backends.multistep#
The interaction-picture Adams march every CPU backend steps with (SEP 13, SEP 14).
One accepted step of a mature method costs one expensive source evaluation (explicit Adams-Bashforth and PEC) or two (PECE), against seven for the reference backend’s IP-DOPRI5. The march keeps a short history of transported derivatives, re-anchored at every accepted step, and decides each step on a local-defect estimate formed from that history without another evaluation (SEP 13 sections 4.1–4.3).
The interaction picture is anchored at the start of each step, z_n. With
U(z_2, z_1) = exp(Phi(z_2) - Phi(z_1)), the variable v(z) = U(z_n, z) a(z)
obeys v' = g(z) = U(z_n, z) N(U(z, z_n) v, z). A history derivative is stored in
the current anchor’s frame; accepting a step re-anchors every one of them by the step’s
own propagator, which is the multiplication the Runge-Kutta march already performs on
its state, so no table is queried backwards. Every derivative keeps its position and
the identity of the field it was evaluated at – the accepted field, or the predicted
one PEC stores in its place.
The march is shared: a backend supplies two hooks of the step driver,
_adams_source (one source evaluation at a lab-frame field, returned in the step’s
anchor frame) and _adams_propagator, and the driver’s own state, landing and
recording do the rest. numpy_ref evaluates through its reference passes and
numba_cpu through its fused stage kernels (SEP 14 phase 2).
Lifecycle, owned here and not by the shared driver’s Runge-Kutta march (SEP 13 section 6.1):
a trial computes its predictor, its single source call and its estimate without touching the history; only an accepted step commits, so a rejection leaves the accepted history exactly as it was;
PECE decides acceptance before its second call, so a rejection costs one call;
explicit Adams-Bashforth rejects for free on a history estimate before the call, and checks the step again afterwards with the new derivative (section 4.3), at the cost of the call it has made;
a hard kink is landed on and the history restarted on its far side; a save plane is a pure observation and keeps the history;
a load or a resume starts afresh, at order one, and its startup calls are counted.
Module Attributes
Consecutive rejections after which the history is restarted at order one. |
|
Factor by which a neighbouring order's predicted step must win to be adopted. |
|
Share of an order's negative-real stability interval the order choice allows. |
Functions
|
Return a trial's transported-compensation tables, for a resident engine. |
|
Return a coupled trial's flow and moments |
|
Return an exponential trial's coefficient tables, for a resident engine. |
|
Return each exponential defect factored: a divided difference and a polynomial. |
|
Return a fused trial's coefficient tables, for an engine that applies them. |
|
Return whether a problem's complete source is structurally zero. |
Classes
|
What |
|
The field arithmetic of a fused Adams step, in NumPy (SEP 14 phase 2). |
|
March a reference backend's state with an interaction-picture Adams method. |
|
Expensive source evaluations of one run, by purpose (SEP 13 section 5). |
|
A step's frozen coupled block on the bins that carry one (SEP 16 phase 5). |
|
The reference passes beside a coupled flow (SEP 16 phase 5). |
|
The field arithmetic of an exponential Adams step, in NumPy (SEP 16 phase 2). |
|
The Adams history and its field arithmetic, on host arrays (SEP 16 phase 3b). |
- class solprop.backends.multistep.AdamsEngine(*args, **kwargs)[source]#
Bases:
ProtocolWhat
AdamsMarchasks of the engine that holds its history (SEP 16).The march keeps the controller; an engine keeps the history’s rows and does every state-sized operation, so that a backend can keep them where its state lives.
HostHistoryis the reference;docs/dev/stepper.mdstates the contract.- dense: Any#
The general path’s last accepted step (a
_DenseSteporNone), which the march sets for observation.
- exponential_accept(keep, free, *, interpolate)[source]#
Adopt the held exponential trial.
- Parameters:
- keepnumpy.ndarray
The history rows kept,
int64.- freeint
The row the new sample takes.
- interpolatebool
Whether the step’s interpolant is kept for dense observation.
- exponential_trial(z, dz, nodes, slots, order, orders)[source]#
Form an exponential trial; return its scored norms.
- Parameters:
- z, dzfloat
The anchor and the step, m.
- nodeslist of float
The history’s normalised positions, newest first.
- slotsnumpy.ndarray
Their store rows,
int64.- orderint
The step’s order.
- orderslist of int
The orders scored, the step’s own first.
- Returns:
- numpy.ndarray
One scaled norm per scored order.
- fused_accept(keep, free, *, interpolate)[source]#
Adopt the held interaction-formulation trial.
- Parameters:
- keepnumpy.ndarray
The history rows kept,
int64.- freeint
The row the new sample takes.
- interpolatebool
Whether the step’s interpolant is kept for dense observation.
- fused_trial(z, dz, nodes, slots, order, orders)[source]#
Form an interaction-formulation trial; return its scored norms.
- Parameters:
- z, dzfloat
The anchor and the step, m.
- nodeslist of float
The history’s normalised positions, newest first.
- slotsnumpy.ndarray
Their store rows,
int64.- orderint
The step’s order.
- orderslist of int
The orders scored, the step’s own first.
- Returns:
- numpy.ndarray
One scaled norm per scored order.
- hold()[source]#
Return the accepted state, to restore after a dense observation.
- Returns:
- object
A handle
restore()takes.
- load_rows(rows, shape)[source]#
Install rows
snapshot_rows()returned, refusing rows it does not keep.- Parameters:
- rowscollections.abc.Mapping
The rows, by name.
- shapetuple of int
The state’s shape.
- Raises:
- BackendError
If the rows are another engine’s, missing, or of the wrong shape; nothing is installed then.
- observe(position)[source]#
Return the masked field at position inside the last accepted step.
- Parameters:
- positionfloat
The observation, m.
- Returns:
- object
The field, as the backend holds a state.
- restore(z, held)[source]#
Make a held accepted state current again at z.
- Parameters:
- zfloat
Its position, m.
- heldobject
What
hold()returned.
- snapshot_rows()[source]#
Return host copies of the rows a resume needs to continue the history.
- Returns:
- dict
The rows by name, each
(n_slots, *shape), in the engine’s own names (HostHistory.snapshot_rowsstates the host engine’s).
- class solprop.backends.multistep.AdamsKernels(*, helpers=Helpers(name='numba'))[source]#
Bases:
objectThe field arithmetic of a fused Adams step, in NumPy (SEP 14 phase 2).
Three passes serve a step of the one-order-higher PEC family: the predictor’s lab-frame field, the corrected field with the defects of the current and the neighbouring orders, and the history’s transport to the new anchor. The history is a store of rows, newest first by
slots.numba_cpucompiles each pass into one traversal (solprop.backends.numba_cpu.multistep); this is the reference the compiled form is checked against.- Parameters:
- helperssolprop._helpers.Helpers, optional
The owning backend’s implementation of the Adams basis (SEP 29 section 6.6); the shared Numba one by default.
- correct(state, propagator, source, store, slots, corrector, rows, dz, mask, divisor)[source]#
Return the corrected lab-frame field and the scaled norms of the defects.
With
X = (source, store[slots[0]], ...), the field isU (a_n + dz sum_t c_t X_t)and each norm is the weak norm ofU dz sum_t rows[r, t] X_tover the in-band bins.- Parameters:
- state, propagatornumpy.ndarray
As for
predict().- sourcenumpy.ndarray
The source at the predicted field, in the anchor’s frame.
- storenumpy.ndarray
The history rows.
- slotsnumpy.ndarray
The rows after the source, newest first,
int64.- correctornumpy.ndarray
The corrector’s weights over
X, zero past its own nodes.- rowsnumpy.ndarray
One defect’s weights over
Xper row, shape(n_rows, 1 + n_slots).- dzfloat
The step, m.
- masknumpy.ndarray
The in-band bins, Boolean.
- divisornumpy.ndarray
The norm’s scale per bin.
- Returns:
- tuple
The corrected field and one norm per row.
- predict(state, propagator, store, slots, weights, dz)[source]#
Return the predictor’s lab-frame field
U (a_n + dz sum_t w_t g_t).- Parameters:
- statenumpy.ndarray
The accepted state at the anchor.
- propagatornumpy.ndarray
U(z_n + dz, z_n).- storenumpy.ndarray
The history rows.
- slotsnumpy.ndarray
The rows the predictor combines, newest first,
int64.- weightsnumpy.ndarray
One integrated weight per row.
- dzfloat
The step, m.
- Returns:
- numpy.ndarray
The predicted field at the end of the step.
- transport(store, slots, propagator, new_slot, source)[source]#
Re-anchor the history at the step’s end and store the new derivative.
- Parameters:
- storenumpy.ndarray
The history rows, updated in place.
- slotsnumpy.ndarray
The rows of the kept history,
int64.- propagatornumpy.ndarray
U(z_n + dz, z_n).- new_slotint
The free row the new derivative goes to.
- sourcenumpy.ndarray
The new derivative in the step’s anchor frame.
- weights(nodes, upper=1.0)[source]#
Return the integrated weights of an interpolant on distinct nodes.
- Parameters:
- nodeslist of float or numpy.ndarray
The normalised nodes, accepted positions and so distinct.
- upperfloat, optional
The integral’s upper limit.
- Returns:
- numpy.ndarray
One weight per node, as
integrated_weightsgives them.
- class solprop.backends.multistep.AdamsMarch(backend, method, kernels=None, exponential=None, *, compensation='transported')[source]#
Bases:
objectMarch a reference backend’s state with an interaction-picture Adams method.
- Parameters:
- backendsolprop.backends.driver.StepDriver
The backend whose state, source evaluation and propagators are used. It owns the step history and the statistics rows; this object owns the derivative history and the call ledger.
- methodsolprop.stepper.multistep.Multistep
The method.
- kernelsAdamsKernels or None, optional
The field arithmetic of the fused path;
Nonetakes the NumPy reference.- exponentialExponentialKernels or None, optional
The exponential formulation’s field arithmetic;
Nonetakes the NumPy reference. Used only when the method’s formulation is"exponential".- compensation{‘transported’, ‘untransported’}, optional
How a varying operator’s linear compensation is integrated (SEP 16 Q8):
"transported", the delivered treatment, or"untransported", kept as a test witness only.
- begin_run()[source]#
Start a run’s accounting afresh: the call ledger and the last rejection.
Called by
set_initial(), so that a backend loaded for another run counts that run’s calls alone and chooses its first order as a fresh backend would (SEP 22 section 4.7). A resume restores its persisted ledger afterwards.
- export_refusal()[source]#
Return why this march cannot carry its history across a resume, or
None.The fused and exponential paths keep their history in an engine, and every engine exports and installs its rows (
AdamsEngine, SEP 29 section 6.6). The general path combines a list of host arrays one product at a time and keeps no store a snapshot could hold.- Returns:
- str or None
The reason, or
Nonewhen the march exports and installs its history.
- load(snapshot)[source]#
Continue from a snapshot taken where the backend’s state now stands.
The backend has been loaded at the snapshot’s position; this installs the accepted state exactly as it was held, the history, the order, the rejection count and the proposed step, so that the march goes on as the uninterrupted one would have. Nothing is changed when the snapshot cannot be used.
- Parameters:
- snapshotsolprop.output.schema.MarchSnapshot
What
snapshot()returned, possibly read back from a file.
- Returns:
- str or None
Nonewhen the history was continued, otherwise why it starts afresh.
- march_to(target)[source]#
Step the backend’s state adaptively to target, landing on it exactly.
- Parameters:
- targetfloat
Position to reach, m.
- Raises:
- ConvergenceError
If the proposal falls below the contract’s
dz_min.
- replay_step(dz, end, slack)[source]#
Take one prescribed step from the backend’s position and accept it.
The unit a lockstep batch advances each member by (
solprop.backends.batch.LockstepRunner): the budget, the startup of an empty history, the step and, when end is a hard kink, the restart.- Parameters:
- dzfloat
The step, m.
- endfloat
The schedule’s edge it ends on, m.
- slackfloat
How far an edge may sit from a kink it lands on, m.
- Returns:
- float
The step’s scaled error norm, recorded and not acted on.
- Raises:
- ConvergenceError
If the norm is not finite: the field has diverged, and a replay cannot reject the step.
- snapshot()[source]#
Return the march’s state at its accepted position, for a resume.
- Returns:
- solprop.output.schema.MarchSnapshot or None
The snapshot, or
Nonewhere there is nothing a resume could continue: no history yet, the march ahead of an interpolated observation, or a march that cannot carry its history (export_refusal()).
- solprop.backends.multistep.COLLAR_STABILITY = 1.0#
Share of an order’s negative-real stability interval the order choice allows.
- class solprop.backends.multistep.CallLedger(startup=0, predictor=0, corrected=0, rejected=0, accepted_steps=0, rejected_steps=0, restarts=0, failure_restarts=0, dense_observations=0, orders=<factory>)[source]#
Bases:
objectExpensive source evaluations of one run, by purpose (SEP 13 section 5).
- Attributes:
- startupint
Evaluations at an accepted field to start or restart the history.
- predictorint
Evaluations at a predicted field, accepted or not.
- correctedint
PECE’s evaluations at the corrected, accepted field.
- rejectedint
Evaluations spent on steps that were then rejected (included in the above).
- accepted_steps, rejected_stepsint
Step counts.
- restartsint
History restarts at hard kinks.
- failure_restartsint
History restarts after
RESTART_AFTERconsecutive rejections.- dense_observationsint
Save planes observed by interpolation instead of a landing; none costs a call.
- orderslist of int
The predictor order of every accepted step.
- classmethod from_record(record)[source]#
Restore validated cumulative counts without restoring numerical history.
- Parameters:
- recordmapping
Persisted counter fields and accepted predictor orders.
- Returns:
- CallLedger
Independently owned counters.
- Raises:
- BackendError
If a counter is absent, unknown, negative or not an integer.
- class solprop.backends.multistep.CoupledBlock(active, vectors, triangular, section, end_weights=None, residual=None, basis=None)[source]#
Bases:
objectA step’s frozen coupled block on the bins that carry one (SEP 16 phase 5).
Beside a coupled flow the cumulative diagonal
Phiis a multiple of the identity in the channel axis (docs/dev/kernel-contract.md,coupled_flow), so the step’s reference isB = (Delta Phi / h) I + G_swithG_s = Z T Z^Hthe frozen block of the section the step is anchored in, and the two parts commute.- Attributes:
- activenumpy.ndarray
Which bins carry a block, bool, shape
(n_omega,).- vectors, triangularnumpy.ndarray
ZandTof the section’s block, 1/m forT, shape(n_active, n_modes, n_modes).- sectionint
The section the step is anchored in.
- end_weightsnumpy.ndarray or None
The flow’s term weights at the step’s end, read on the step’s side of a section edge (
StageScalars.flow_weights);Nonewithout a residual.- residualcallable or None
(state, weights) -> R_s(z) statefor a frozen-residual flow: the generator at the position the weights belong to less this section’s frozen block, on the active bins the error norm scores and zero elsewhere, as the Runge-Kutta stage applies it;Nonefor a constant-Schur flow.- basistuple or None
The section’s eigenbasis
(W, Y, lambda, route), assolprop.translate.coupled.schur_eigenbasis()returns it: the bins on the route take their matrix functions asW f(x + h lambda) Y, the compiled backends’ evaluation.None, the reference’s, takes every bin from the augmented exponential.
- class solprop.backends.multistep.CoupledExponentialKernels(*, helpers=Helpers(name='numba'))[source]#
Bases:
ExponentialKernelsThe reference passes beside a coupled flow (SEP 16 phase 5).
A coupled trial’s flow and moments are
_MatrixMoments(coupled_moments()): matrices in the channel axis on the bins that carry a block, elementwise elsewhere. The passes areExponentialKernels’ with those products.- carry_coupled(exponent, dz, rows, slots, spans, block)[source]#
Return each sample’s compensation carried to the step’s end (SEP 16 4.5).
C_j = (D(z_j) - x / h) u_j + R_s(z_j) u_j: the diagonal chord’s difference of rates and the frozen-residual’s residual relative to the step’s section, formed from the sample’s own flow weights – so that a step in a new section rebuilds the history’s residual against its block – and carried by the reference’s forward flowexp((1 - theta_j) h B).- Parameters:
- exponentnumpy.ndarray
x = Delta Phiover the step.- dzfloat
The step, m.
- rowstuple
The history’s rates and states, by slot, and each slot’s flow weights.
- slotsnumpy.ndarray
The samples carried, newest first.
- spansnumpy.ndarray
1 - theta_jper sample.- blockCoupledBlock
The step’s frozen block.
- Returns:
- numpy.ndarray
One carried row per sample.
- correct(state, flow, moments, source, store, slots, corrector, rows, dz, mask, divisor, extra=None)[source]#
Return the corrected field and the defects’ norms through the block.
- Parameters:
- statenumpy.ndarray
The accepted state at the anchor.
- flow, moments_MatrixMoments or numpy.ndarray
The coupled trial’s flow and moments.
- sourcenumpy.ndarray
The untransported source at the predicted field.
- storenumpy.ndarray
The history rows.
- slotsnumpy.ndarray
The rows after the source, newest first,
int64.- correctornumpy.ndarray
The corrector’s coefficients.
- rowsnumpy.ndarray
One defect’s coefficients per row.
- dzfloat
The step, m.
- masknumpy.ndarray
The in-band bins, Boolean.
- divisornumpy.ndarray
The norm’s scale per bin.
- extratuple or None, optional
A varying operator’s compensation terms.
- Returns:
- tuple
The corrected field and one norm per row.
- coupled_moments(exponent, count, block, dz)[source]#
Return a coupled trial’s flow and moments (
coupled_moments()).- Parameters:
- exponentnumpy.ndarray
Delta Phiover the step.- countint
The moments formed.
- blockCoupledBlock
The step’s frozen block.
- dzfloat
The step, m.
- Returns:
- _MatrixMoments
The flow and the moments.
- predict(state, flow, moments, store, slots, coefficients, dz)[source]#
Return the predicted field through the trial’s block.
- Parameters:
- statenumpy.ndarray
The accepted state at the anchor.
- flow, moments_MatrixMoments or numpy.ndarray
The coupled trial’s flow and moments.
- storenumpy.ndarray
The history rows.
- slotsnumpy.ndarray
The rows the predictor combines, newest first,
int64.- coefficientsnumpy.ndarray
The predictor’s Lagrange coefficients.
- dzfloat
The step, m.
- Returns:
- numpy.ndarray
The predicted lab-frame field at the end of the step.
- class solprop.backends.multistep.ExponentialKernels(*, helpers=Helpers(name='numba'))[source]#
Bases:
objectThe field arithmetic of an exponential Adams step, in NumPy (SEP 16 phase 2).
The history is a store of untransported source rows, newest first by
slots. A trial formsM_k = k! phi_{k+1}(x),x = h Dper element, once, and applies every formula it needs in the monomial basis of its interpolant,h sum_k M_k (sum_j c_jk F_j)(solprop.backends.exponential), so no per-node weight volume is formed. Accepting a step re-anchors nothing. The compiled backends’ kernels are checked against these passes.- Parameters:
- helperssolprop._helpers.Helpers, optional
The owning backend’s implementation of the Adams basis (SEP 29 section 6.6); the shared Numba one by default.
- apply(moments, coefficients, values, dz)[source]#
Return
dz sum_k M_k (sum_j c_jk X_j)over the given rows.- Parameters:
- momentsnumpy.ndarray
M_kfrommoments().- coefficientsnumpy.ndarray
c_jk, shape(len(values), n_k)withn_k <= len(moments).- valueslist of numpy.ndarray
The samples
X_j.- dzfloat
The step, m.
- Returns:
- numpy.ndarray
The increment.
- carry(exponent, dz, rates, states, slots, spans)[source]#
Return each history sample’s compensation carried to the step’s end.
exp(s_j x) (D(z_j) - x / dz) u_jwiths_j = 1 - theta_j, the difference of rates formed before the state multiplies it (SEP 16 4.2).- Parameters:
- exponentnumpy.ndarray
x = Phi(z + h) - Phi(z).- dzfloat
The step, m.
- rates, statesnumpy.ndarray
The history’s rates and states, by slot.
- slotsnumpy.ndarray
The samples carried, newest first,
int64.- spansnumpy.ndarray
1 - theta_jper sample: the flow’s length in steps.
- Returns:
- numpy.ndarray
One carried row per sample.
- correct(state, flow, moments, source, store, slots, corrector, rows, dz, mask, divisor, extra=None)[source]#
Return the corrected field and the scaled norms of the defects.
With
X = (source, store[slots[0]], ...), the field isexp(x) u_n + dz sum_k M_k sum_j corrector[j, k] X_jand each norm is the weak norm ofdz sum_k M_k sum_j rows[r, j, k] X_jover the in-band bins; both are already at the end of the step. A varying operator’s compensation adds its own corrector term to the field and one term to each defect.- Parameters:
- state, flow, momentsnumpy.ndarray
As for
predict().- sourcenumpy.ndarray
The untransported source at the predicted field.
- storenumpy.ndarray
The history rows.
- slotsnumpy.ndarray
The rows after the source, newest first,
int64.- correctornumpy.ndarray
The corrector’s coefficients over
X, shape(width, n_k), zero past its own nodes.- rowsnumpy.ndarray
One defect’s coefficients over
Xper row, shape(n_rows, width, n_k).- dzfloat
The step, m.
- masknumpy.ndarray
The in-band bins, Boolean.
- divisornumpy.ndarray
The norm’s scale per bin.
- extratuple or None, optional
The compensation’s corrector term and its term in each defect, or
Nonefor a constant operator.
- Returns:
- tuple
The corrected field and one norm per row.
- coupled()[source]#
Return the passes this backend takes beside a coupled flow.
- Returns:
- CoupledExponentialKernels
The reference’s; a compiled backend returns its own.
- defect_rows(nodes, orders, width)[source]#
Return the defects’ coefficients in the form
correct()takes.- Parameters:
- nodeslist of float
The history’s normalised positions, newest first.
- orderslist of int
The orders scored, the step’s own first.
- widthint
1 + max(orders).
- Returns:
- numpy.ndarray
The monomial rows of
_exponential_rows, shape(len(orders), width, width).
- flow(exponent)[source]#
Return the step’s exact linear flow
exp(x).- Parameters:
- exponentnumpy.ndarray
x = Phi(z + h) - Phi(z).
- Returns:
- numpy.ndarray
exp(x), the propagator the interaction formulation would apply.
- moments(exponent, count)[source]#
Return
k! phi_{k+1}(x)fork < countalong a new leading axis.- Parameters:
- exponentnumpy.ndarray
x = Phi(z + h) - Phi(z), in the canonical layout.- countint
The most interpolation nodes any formula of the trial has.
- Returns:
- numpy.ndarray
Shape
(count, *x.shape).
- predict(state, flow, moments, store, slots, coefficients, dz)[source]#
Return the predicted field
exp(x) u_n + dz sum_k M_k sum_j c_jk F_j.- Parameters:
- statenumpy.ndarray
The accepted state at the anchor.
- flownumpy.ndarray
exp(x), the step’s exact linear flow.- momentsnumpy.ndarray
M_kfrommoments().- storenumpy.ndarray
The history rows.
- slotsnumpy.ndarray
The rows the predictor combines, newest first,
int64.- coefficientsnumpy.ndarray
The predictor’s Lagrange coefficients, shape
(len(slots), len(slots)).- dzfloat
The step, m.
- Returns:
- numpy.ndarray
The predicted lab-frame field at the end of the step.
- class solprop.backends.multistep.HostHistory(backend, method, kernels, exponential, compensation)[source]#
Bases:
objectThe Adams history and its field arithmetic, on host arrays (SEP 16 phase 3b).
AdamsMarchkeeps the controller – the orders, the slots, rejection, restarts, the budget and the ledger – and hands every state-sized operation to an engine: the startup sample, a trial’s predictor, source, corrector and defect norms, the adoption and transport of an accepted step, and dense observation. This engine holds the history in a NumPy store and applies the given kernels (NumPy, ornumba_cpu’s compiled passes); a backend may supply its own throughsolprop.backends.driver.StepDriver._adams_engine, as Kokkos does to keep the history resident in its engine. Between a trial and its acceptance the engine holds the trial; nothing else is carried across calls but the store and the last accepted step for dense observation.- Parameters:
- backendsolprop.backends.driver.StepDriver
The backend whose state, source evaluation and propagators are used.
- methodsolprop.stepper.multistep.Multistep
The method.
- kernelsAdamsKernels
The interaction formulation’s fused arithmetic.
- exponentialExponentialKernels or None
The exponential formulation’s arithmetic,
Nonefor the interaction one.- compensation{‘transported’, ‘untransported’}
A varying operator’s compensation treatment (SEP 16 Q8).
- exponential_accept(keep, free, *, interpolate)[source]#
Adopt the held exponential trial; the new sample takes row free.
- Parameters:
- keepnumpy.ndarray
The history rows kept,
int64; nothing moves in this formulation.- freeint
The row the new sample takes.
- interpolatebool
Whether the step’s interpolant is kept for dense observation.
- exponential_trial(z, dz, nodes, slots, order, orders)[source]#
Form one exponential trial and return the scaled norms of its defects.
The arithmetic of
fused_trial()with untransported samples: the predictor and the corrector integrate their interpolants exactly against the step’s flowexp(x),x = Phi(z + h) - Phi(z); the defects of the neighbouring orders are scored from the same moments. A varying operator adds the compensation of its samples (SEP 16 section 4.2). The trial is held forexponential_accept().- Parameters:
- z, dzfloat
The anchor and the step, m.
- nodeslist of float
The history’s normalised positions, newest first.
- slotsnumpy.ndarray
Their store rows,
int64.- orderint
The step’s order.
- orderslist of int
The orders scored, the step’s own first.
- Returns:
- numpy.ndarray
One scaled norm per scored order.
- fused_accept(keep, free, *, interpolate)[source]#
Adopt the held fused trial: the state, its interpolant, the new sample.
- Parameters:
- keepnumpy.ndarray
The history rows kept,
int64; each is re-anchored at the step’s end.- freeint
The row the new sample takes.
- interpolatebool
Whether the step’s interpolant is kept for dense observation.
- fused_trial(z, dz, nodes, slots, order, orders)[source]#
Form one fused trial and return the scaled norms of its scored defects.
The predictor’s lab-frame field, the source there (one call, labelled a predictor), and in one pass the corrected field and each scored order’s defect: its
k + 1-node corrector through the new source less itsk-node predictor. The trial is held forfused_accept().- Parameters:
- z, dzfloat
The anchor and the step, m.
- nodeslist of float
The history’s normalised positions, newest first.
- slotsnumpy.ndarray
Their store rows,
int64.- orderint
The step’s order.
- orderslist of int
The orders scored, the step’s own first.
- Returns:
- numpy.ndarray
One scaled norm per scored order.
- hold()[source]#
Return the accepted state, to restore after a dense observation.
- Returns:
- object
The backend’s host copy of the accepted state.
- load_rows(rows, shape)[source]#
Install rows
snapshot_rows()returned, for a state of shape.- Parameters:
- rowscollections.abc.Mapping
The rows, by name.
- shapetuple of int
The state’s shape.
- Raises:
- BackendError
If a row is missing, does not have the store’s shape, or is one this history does not keep – the native engine’s applied frozen-residual generators (
"applied") among them.
- property n_slots: int[source]#
The history store’s rows: the method’s order and two more.
- Returns:
- int
order + 2.
- observe(position)[source]#
Return the field at position inside the last accepted step.
- Parameters:
- positionfloat
The observation, m, inside the last accepted step.
- Returns:
- object
The masked lab-frame field at position, as the backend holds a state: a host array, or Kokkos’s native state loaded with it.
- restore(z, held)[source]#
Make a held accepted state current again at z.
- Parameters:
- zfloat
Its position, m.
- heldobject
What
hold()returned.
- snapshot_rows()[source]#
Return copies of the rows a resume needs to continue the history.
- Returns:
- dict
"store", the samples; for a compensated march also"states"and"rates", and"weights_<row>"for each row a frozen-residual flow weights.
- start(z, *, stored)[source]#
Evaluate the source at the accepted state, the history’s first sample.
- Parameters:
- zfloat
The accepted position, m.
- storedbool
Whether the sample goes to the store’s row zero (the fused and exponential paths) or is returned alone (the general path).
- Returns:
- numpy.ndarray
The sample: the transported source in the interaction formulation, the untransported one in the exponential formulation.
- solprop.backends.multistep.ORDER_HYSTERESIS = 1.2#
Factor by which a neighbouring order’s predicted step must win to be adopted.
- solprop.backends.multistep.RESTART_AFTER = 3#
Consecutive rejections after which the history is restarted at order one.
- solprop.backends.multistep.compensation_tables(nodes, order, orders, *, helpers)[source]#
Return a trial’s transported-compensation tables, for a resident engine.
The weights
_Compensationapplies (SEP 16 section 4.2, ADR-042), over the carried rowsexp((1 - theta_j) x) (D(z_j) - x / h) u_jof the history samples and the endpoint term(D(z + h) - x / h) u_pred, each sum still to be multiplied by the step.- Parameters:
- nodeslist of float
The history’s normalised positions, newest first.
- orderint
The step’s order.
- orderslist of int
The orders scored, the step’s own first.
- helperssolprop._helpers.Helpers
The engine’s backend’s implementation of the Adams basis.
- Returns:
- tuple
The spans
1 - theta_jof thewidth - 1carried samples; the predictor’s weights over theordernewest of them; the corrector’s over(endpoint, newest, ...); and each scored order’s defect weights over the same, shape(len(orders), width), withwidth = 1 + max(orders).
- solprop.backends.multistep.coupled_moments(exponent, count, block, dz, *, eigen=<function _eigen_functions>, diagonal=None)[source]#
Return a coupled trial’s flow and moments
k! phi_{k+1}(h B),k < count.The reference’s evaluation (SEP 16 section 4.5): on each bin of the block the functions of
X = Delta Phi I + h T, upper triangular, are read off the first block row of the exponential of the augmented matrix[[X, I, 0, ...], [0, 0, I, ...], ..., [0, ..., 0]]–exp(X),phi_1(X), …,phi_count(X)– and carried back byZ; off the block the diagonal functions ofExponentialKernels. With the block’s eigenbasis (CoupledBlock.basis), the bins on its route instead takeW f(Delta Phi + h lambda) Y, every bin in one pass: the route and its gate are the compiled flow actions’ (solprop.translate.coupled.eigenbasis_limit()), and the bins off it keep the augmented exponential.- Parameters:
- exponentnumpy.ndarray
Delta Phiover the step, the same in every channel.- countint
The moments formed.
- blockCoupledBlock
The step’s frozen block.
- dzfloat
The step, m.
- eigencallable, optional
Writes the eigenbasis route’s bins,
(shift, dz, count, basis, matrices, flow_matrix):_eigen_functions, or a compiled backend’s kernel.- diagonalcallable or None, optional
(exponent, count) -> momentsoff the block;Nonefor the reference’sExponentialKernels.moments().
- Returns:
- _MatrixMoments
The flow and the moments.
- solprop.backends.multistep.exponential_tables(nodes, order, orders, *, helpers)[source]#
Return an exponential trial’s coefficient tables, for a resident engine.
- Parameters:
- nodeslist of float
The history’s normalised positions, newest first.
- orderint
The step’s order.
- orderslist of int
The orders scored, the step’s own first.
- helperssolprop._helpers.Helpers
The engine’s backend’s implementation of the Adams basis.
- Returns:
- tuple
The predictor’s Lagrange coefficients over the
ordernewest rows, shape(order, order); the corrector’s over(source, newest, ...), shape(width, width)withwidth = 1 + max(orders); and the factored defect rows offactored_defect_rows().
- solprop.backends.multistep.factored_defect_rows(nodes, orders, width)[source]#
Return each exponential defect factored: a divided difference and a polynomial.
Order
k’s defect, itsk + 1-node corrector through the new sample less itsk-node predictor, vanishes at the predictor’s nodes, so it isf[1, theta_0, ..., theta_{k-1}] prod_{j<k} (theta - theta_j): one divided difference of the samples times one polynomial, whose integral against the flow is one combination of the moments. That is2 (k + 1)products an element instead of(k + 1) n_k, the monomial rows of_exponential_rows.- Parameters:
- nodeslist of float
The history’s normalised positions, newest first.
- orderslist of int
The orders scored, the step’s own first.
- widthint
1 + max(orders): the samples and the moments of the trial.
- Returns:
- numpy.ndarray
Shape
(len(orders), 2 width): the divided-difference coefficients over(source, newest, ...), then the node polynomial’s ascending monomial coefficients.
- solprop.backends.multistep.fused_tables(nodes, order, orders, *, helpers)[source]#
Return a fused trial’s coefficient tables, for an engine that applies them.
The interaction formulation’s tables of
HostHistory.fused_trial(), which a resident engine (ADR-043) receives instead of forming them.- Parameters:
- nodeslist of float
The history’s normalised positions, newest first.
- orderint
The step’s order.
- orderslist of int
The orders scored, the step’s own first.
- helperssolprop._helpers.Helpers
The engine’s backend’s implementation of the Adams basis.
- Returns:
- tuple
The predictor’s integrated weights over the
ordernewest rows; the corrector’s weights over(source, newest, ...), zero past its nodes; and one defect row per scored order over the same samples.
- solprop.backends.multistep.source_absent(problem)[source]#
Return whether a problem’s complete source is structurally zero.
No response is compiled beyond the accumulation, and no in-stage absorber, no atomic response and no general or spatial pipeline adds a term: SEP 16 section 4.2 then requires the exact chord rather than an interpolated compensation, which need not cancel even at the endpoint. Decided from the problem’s structure, never from a sample that happens to vanish.
- Parameters:
- problemsolprop.translate.problem.KernelProblem
The problem.
- Returns:
- bool
Whether every source evaluation is identically zero.