OP Engine¶
op_engine
¶
Numerical methods for structured deterministic and stochastic dynamics.
RandomStream = np.random.Generator | np.random.SeedSequence
module-attribute
¶
An advancing NumPy generator or a replayable seed-sequence initialization.
Scalar = float | Array
module-attribute
¶
A Python float or a backend-native rank-zero numerical array.
ActionOperator(shape, dtype, namespace, matvec, transpose_matvec=None)
dataclass
¶
Caller-owned, real linear action at a fixed linearization/context.
matvec maps (shape[1],) to (shape[0],) without changing namespace,
dtype or device. Matrix application applies that callback column by column.
transpose_matvec represents the Euclidean transpose of the same
fixed map, not an inverse or a weighted adjoint. Linearity and the correctness
of the transpose are the provider's obligations; neither is inferred from
a numerical probe. Only real float32/float64 actions are supported.
Attributes:
| Name | Type | Description |
|---|---|---|
shape |
tuple[int, int]
|
Output and input dimensions. |
dtype |
object
|
Native real floating dtype shared by inputs and outputs. |
namespace |
Any
|
Array-API namespace returned by :func: |
matvec |
Callable[[Array], Array]
|
Linear vector application. |
transpose_matvec |
Callable[[Array], Array] | None
|
Optional Euclidean transpose vector application. |
T
property
¶
Return the explicitly supplied real Euclidean transpose.
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If no transpose callback was supplied. |
__matmul__(other)
¶
Apply the action without densifying or coercing the input.
Returns:
| Type | Description |
|---|---|
Array
|
Vector or matrix of independent output columns. |
Source code in src/op_engine/linear_operator.py
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | |
__post_init__()
¶
Validate static metadata and callback availability.
Raises:
| Type | Description |
|---|---|
ValueError
|
If dimensions are invalid. |
TypeError
|
If dtype or callbacks are unsupported. |
Source code in src/op_engine/linear_operator.py
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | |
AdaptiveScheduleProvenance
¶
Bases: NamedTuple
Static compatibility fields and descriptive adaptive-discovery metadata.
Backend, dtype, discovery controls, and reference regime are descriptive. Replay checks method, state layout, relevant operator/kernel settings, and the caller's structural model identity. Callback semantics are not inferred.
AdaptiveTauLeapingConfig(leap_tolerance=0.03, critical_threshold=10, exact_fallback_multiplier=10.0, max_steps=1000000, max_retries=20, forcing_breakpoints=())
dataclass
¶
Controls for bounded adaptive tau-leaping.
Attributes:
| Name | Type | Description |
|---|---|---|
leap_tolerance |
float
|
Relative leap-condition tolerance. |
critical_threshold |
int
|
A reaction is critical when fewer than this many firings would exhaust one of its reactants. Zero disables critical classification. |
exact_fallback_multiplier |
float
|
Use exact SSA when the proposed leap is less than this multiple of the mean time to the next event. Zero disables this fallback. |
max_steps |
int
|
Maximum accepted leaps or exact events per output interval. |
max_retries |
int
|
Maximum post-leap rejections before failing. |
forcing_breakpoints |
tuple[float, ...]
|
Strictly increasing finite forcing-change times. Leaps end at these boundaries; exact events at or beyond a boundary are discarded. Rates must be right-continuous and constant in time between boundaries for exact fallback. |
__post_init__()
¶
Validate adaptive controls.
Raises:
| Type | Description |
|---|---|
ValueError
|
If a control is outside its valid range. |
Source code in src/op_engine/adaptive_tau.py
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | |
AdaptiveTauLeapingSolver(core, stoichiometry, reactant_stoichiometry, *, reaction_axis='state', dependency_incidence=None, propensity_orders=None)
¶
Adaptive non-negative Poisson tau-leaping with exact critical events.
The implementation follows the Cao-Gillespie-Petzold species-based pre-leap selector. Reactions near exhaustion are bounded to at most one collective exact event. A negative post-leap proposal is rejected and retried at half the attempted tau; populations and firing counts are never clipped.
Initialize the reaction and reactant structures.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
core
|
ModelCore
|
Model state and output-time container. |
required |
stoichiometry
|
Array
|
Net integer state changes by reaction. |
required |
reactant_stoichiometry
|
Array
|
Non-negative integer reactant counts by
species and reaction. This cannot be inferred safely from net
stoichiometry for catalytic reactions. For a reaction with a
positive |
required |
reaction_axis
|
str | int
|
State axis changed by reaction firings. |
'state'
|
dependency_incidence
|
Array | None
|
Optional |
None
|
propensity_orders
|
Array | None
|
Optional |
None
|
Source code in src/op_engine/adaptive_tau.py
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | |
n_reactions
property
¶
Return the number of reaction channels.
run(propensity_func, poisson_sampler=None, ssa_sampler=None, *, config=None, rng=None)
¶
Advance a bounded adaptive trajectory through the output grid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
propensity_func
|
PropensityFunction
|
Reaction-channel propensities. |
required |
poisson_sampler
|
PoissonSampler | None
|
Backend-specific noncritical Poisson sampler. |
None
|
ssa_sampler
|
SSASampler | None
|
Backend-specific exact-event sampler. |
None
|
config
|
AdaptiveTauLeapingConfig | None
|
Optional adaptive, retry, and forcing controls. |
None
|
rng
|
RandomStream | None
|
One NumPy stream shared by call-local Poisson/exact samplers; supply instead of both explicit samplers. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If either sampler is absent or rng conflicts with a sampler. |
TypeError
|
If rng is unsupported or used with non-NumPy state. |
RuntimeError
|
If a step guard, retry guard, or non-negativity invariant fails. |
Source code in src/op_engine/adaptive_tau.py
706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 | |
ApplicableOperator
¶
Bases: Protocol
Shape-bearing operator with vector and column-matrix application.
dtype
property
¶
Return the operator's native real floating dtype.
shape
property
¶
Return the two-dimensional operator shape.
__matmul__(other)
¶
Apply the operator to a vector or matrix of independent columns.
Source code in src/op_engine/linear_operator.py
39 40 41 | |
Array
¶
Bases: Protocol
Minimal Array-API duck type used at public numerical boundaries.
The contract intentionally matches :class:op_system.Array and
:class:flepimop2.typing.Array. It captures only the surface inspected at
package boundaries: shape, dtype, and scalar extraction. Runtime namespace
discovery is delegated to :func:op_engine.array_namespace, which accepts
standard-compliant arrays and native arrays such as torch.Tensor through
array-api-compat. No backend module is stored in solver configuration.
BandedOperator(bands, lower, upper)
dataclass
¶
Real NumPy operator in SciPy's diagonal-ordered band storage.
bands[upper + i - j, j] stores matrix entry (i, j). Construction
copies the input and application touches only valid band entries. The
retained storage is read-only; construct a new operator when coefficients,
mesh or stage change. No dense matrix or factorization cache is created.
T
property
¶
Return the real Euclidean transpose without dense assembly.
dtype
property
¶
Return the native storage dtype.
shape
property
¶
Return square operator dimensions.
__matmul__(other)
¶
Apply valid bands to a vector or independent RHS columns.
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
NumPy array with the same shape and dtype as the RHS. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If namespace or dtype differs. |
ValueError
|
If RHS dimensions disagree. |
Source code in src/op_engine/scipy_operator.py
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | |
__post_init__()
¶
Copy and validate storage and static bandwidths.
Raises:
| Type | Description |
|---|---|
ValueError
|
If dimensions, bandwidths or valid band entries are invalid. |
TypeError
|
If storage is not native NumPy float32/float64. |
Source code in src/op_engine/scipy_operator.py
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | |
BatchedDirectSSASolver(core, stoichiometry)
¶
Advance independent replicates with local clocks and one local network.
A callback taking (times, state) returns (channel, replicate) hazards.
It must use each replicate's own time, preserve the state, and remain constant
between jumps and declared forcing boundaries. Generic callbacks assert that
independence themselves; the compiled-model adapter checks it structurally.
Examples:
>>> import numpy as np
>>> from op_engine import FiringRecorder, ModelCore
>>> core = ModelCore(2, 3, np.array([0.0, 1.0, 2.0]))
>>> core.set_initial_state(np.array([[10.0] * 3, [0.0] * 3]))
>>> counts = FiringRecorder((0,))
>>> solver = BatchedDirectSSASolver(core, np.array([[-1.0], [1.0]]))
>>> def hazards(times, state):
... return 0.5 * state[:1]
>>> solver.run(hazards, rng=np.random.SeedSequence(7), recorder=counts)
>>> core.state_array.shape, counts.counts.shape
((3, 2, 3), (2, 1, 3))
>>> bool(np.all(core.state_array.sum(axis=1) == 10.0))
True
Validate a NumPy local stoichiometric matrix against the bank state.
Raises:
| Type | Description |
|---|---|
ValueError
|
The local network or core layout is invalid. |
TypeError
|
State or stoichiometry is not a NumPy array. |
Source code in src/op_engine/batched_ssa.py
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | |
run(propensity_func, *, rng, replicate_ids=None, config=None, recorder=None)
¶
Store bank trajectories and optional counts at the core's output times.
A root SeedSequence is framed by stable unsigned 64-bit replicate IDs using scheme OPB1 and native PCG64DXSM. Explicit generators advance in place. Replay is bank/order/shard invariant for identical inputs and schedules; changing an actual forcing declaration can change paths.
Raises:
| Type | Description |
|---|---|
ValueError
|
IDs, state, schedules or callback hazards are invalid. |
RuntimeError
|
A population becomes invalid, time stagnates or a per-replicate interval event limit is exceeded. |
Source code in src/op_engine/batched_ssa.py
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | |
BatchedSSAConfig(max_events=1000000, forcing_breakpoints=(), replicate_breakpoints=())
dataclass
¶
Exact event limits and shared/per-replicate forcing declarations.
max_events applies to each replicate in each output interval. Local
schedules follow the input replicate order and are unioned with the shared
schedule. Output times do not change the forcing or resample pending events.
__post_init__()
¶
Validate and snapshot all declarations before executing callbacks.
Source code in src/op_engine/batched_ssa.py
47 48 49 50 51 52 53 54 | |
CompiledObservableLike
¶
Bases: Protocol
Read-only structural compiler surface; core imports no compiler or provider.
coordinates
property
¶
Output axes and their coordinate labels.
definition
property
¶
Scientific name, units and description.
eval_fn
property
¶
Native flat-state evaluator.
measure_requirements
property
¶
Physical measures already applied by the evaluator.
output_shape
property
¶
Output dimensions excluding time.
parameter_shapes
property
¶
Direct parameters and complete native buffer shapes.
state_dependencies
property
¶
Direct state base dependencies.
time_dependent
property
¶
Whether the expression explicitly references time.
CompiledReactionNetwork(stoichiometry, reactant_stoichiometry, channel_reactions, channel_names, _blocks, _reactions, _event_shapes, _params, reactants_complete=False, incomplete_reactions=(), dependency_incidence=None, propensity_orders=None)
dataclass
¶
Flat stochastic network compiled from typed reaction artifacts.
channel_reactions retains the parent reaction name for every expanded
source-cell channel. channel_names adds integer coordinates and is
intended for diagnostics only.
n_channels
property
¶
Return the number of expanded reaction channels.
n_state
property
¶
Return the number of flattened state cells.
mean_drift(time, state)
¶
Return deterministic mean drift from the compiled channels.
Returns:
| Type | Description |
|---|---|
Array
|
|
Source code in src/op_engine/reactions.py
179 180 181 182 183 184 185 186 187 188 189 190 191 | |
propensity(time, state)
¶
Evaluate every reaction and concatenate its source-cell rates.
The stochastic core stores the state as (n_state, 1). A flat
state is accepted as well so the same callback can construct hybrid
mean drift. Returned shape mirrors the input convention.
Returns:
| Type | Description |
|---|---|
Array
|
Propensities in the evolving state's array namespace. |
Source code in src/op_engine/reactions.py
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | |
CoreSolver(core, operators=None, *, operator_axis='state')
¶
Semi-implicit solver operating on a ModelCore time/state grid.
Initialize CoreSolver.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
core
|
ModelCore
|
ModelCore instance to solve. |
required |
operators
|
CoreOperators | StageOperatorFactory | None
|
Default operator spec (tuple or factory) for implicit stages. |
None
|
operator_axis
|
str | int
|
Axis along which operators act (name or index). |
'state'
|
Source code in src/op_engine/core_solver.py
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 | |
last_adaptive_schedule
property
¶
Return the schedule recorded or replayed by the latest adaptive run.
last_nonlinear_diagnostics
property
¶
Return nonlinear diagnostics from the latest SDIRK run or replay.
last_state_diagnostics
property
¶
Return output-state checks from the latest run/replay, if enabled.
adaptive_explicit_step(rhs_func, *, method, t, dt, y, first_stage=None, forcing_breakpoints=())
¶
Attempt one explicit step and return its local-error estimate.
This functional boundary does not mutate :class:ModelCore history
and does not extract host scalars. Provider integrations can compose
it with backend-native adaptive controller loops.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rhs_func
|
RHSFunction
|
Function computing the explicit RHS F(t, y). |
required |
method
|
str
|
Explicit solver method name. |
required |
t
|
Scalar
|
Step start time as a Python float or backend-native scalar. |
required |
dt
|
Scalar
|
Step size as a Python float or backend-native scalar. |
required |
y
|
Array
|
State at the step start. |
required |
first_stage
|
Array | None
|
Optional cached derivative at |
None
|
forcing_breakpoints
|
tuple[float, ...]
|
Static known jumps. The caller must clip the step at the next jump. RHS times use native one-sided neighbors; declared forcing disables first-stage reuse. |
()
|
Returns:
| Type | Description |
|---|---|
ExplicitStepResult
|
Candidate state, local error estimate, controller order, and |
ExplicitStepResult
|
reusable derivative stages. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/op_engine/core_solver.py
3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 | |
fixed_explicit_step(rhs_func, *, method, t, dt, y, first_stage=None, forcing_breakpoints=())
¶
Take one functional fixed step with an explicit method.
This boundary does not mutate :class:ModelCore history, so callers
can compose it with backend-native loop primitives and apply the
completed trajectory once. It is the supported public step kernel
for external drivers such as jax.lax.scan; the method and state
shape are static, while t, dt, y, and RHS parameters may
be traced. RHS results must preserve the configured state shape and
the namespace of y.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rhs_func
|
RHSFunction
|
Function computing the explicit RHS F(t, y). |
required |
method
|
str
|
Explicit solver method name. |
required |
t
|
Scalar
|
Step start time as a Python float or backend-native scalar. |
required |
dt
|
Scalar
|
Step size as a Python float or backend-native scalar. |
required |
y
|
Array
|
State at the step start. |
required |
first_stage
|
Array | None
|
Optional derivative at |
None
|
forcing_breakpoints
|
tuple[float, ...]
|
Static known jumps. The caller must clip the step at the next jump. RHS times use native one-sided neighbors; declared forcing disables first-stage reuse. |
()
|
Returns:
| Type | Description |
|---|---|
Array
|
Next state and an FSAL derivative for Dormand--Prince, or |
Array | None
|
|
tuple[Array, Array | None]
|
with one step outside the scan so its structure stays fixed. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/op_engine/core_solver.py
3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 | |
replay_adaptive_schedule(rhs_func, schedule, *, config)
¶
Replay a recorded adaptive mesh through the configured method.
Replay bypasses error norms and accept/reject decisions while invoking
the same high-order step kernels used by a live adaptive solve. With a
JAX state, the static Python schedule can therefore be traced by
jax.jit and differentiated with respect to array-valued model inputs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rhs_func
|
RHSFunction
|
Function computing the explicit RHS F(t, y). |
required |
schedule
|
AdaptiveStepSchedule
|
Accepted step mesh recorded by an adaptive run. |
required |
config
|
RunConfig
|
Matching adaptive run configuration. |
required |
Returns:
| Type | Description |
|---|---|
NonlinearIntegrationDiagnostics | None
|
Array-valued nonlinear diagnostics for SDIRK2, otherwise |
NonlinearIntegrationDiagnostics | None
|
Opt-in output-state checks are available through |
NonlinearIntegrationDiagnostics | None
|
attr: |
Raises:
| Type | Description |
|---|---|
TypeError
|
If schedule has the wrong type or the state changes array ecosystems during replay. |
ValueError
|
If config is not adaptive, the output grid differs, required provenance is absent, or structural provenance differs. |
Source code in src/op_engine/core_solver.py
5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 | |
run(rhs_func, *, config=None)
¶
Advance the ModelCore state through its time grid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rhs_func
|
RHSFunction
|
Function computing the explicit RHS F(t, y). |
required |
config
|
RunConfig | None
|
Optional run configuration. If None, defaults are used. |
None
|
Returns:
| Type | Description |
|---|---|
NonlinearIntegrationDiagnostics | None
|
Array-valued nonlinear diagnostics for SDIRK2, otherwise |
NonlinearIntegrationDiagnostics | None
|
Opt-in output-state checks are available through |
NonlinearIntegrationDiagnostics | None
|
attr: |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the state changes array ecosystems during a run. |
ValueError
|
If invalid parameters are provided. |
Examples:
>>> import numpy as np
>>> from op_engine import ModelCore
>>> from op_engine.core_solver import RunConfig
>>> core = ModelCore(1, 1, np.linspace(0.0, 1.0, 11))
>>> core.set_initial_state(np.array([[1.0]]))
>>> def decay(time, state):
... return -state
>>> CoreSolver(core).run(decay, config=RunConfig(method="rk4"))
>>> np.allclose(core.state_array[-1, 0, 0], np.exp(-1.0), rtol=1e-5)
True
Source code in src/op_engine/core_solver.py
5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 | |
DenseNewtonSolver(config=NewtonConfig())
dataclass
¶
Portable dense Newton solver with statically unrolled iterations.
The solver has no hidden warm-start state. Every call begins from the
explicit initial_guess supplied by the numerical method. Automatic
differentiation follows the performed Newton iterations; this class does
not install an implicit-function or custom derivative rule.
Attributes:
| Name | Type | Description |
|---|---|---|
config |
NewtonConfig
|
Static iteration, tolerance, and damping configuration. |
solve(problem, initial_guess)
¶
Run a fixed number of dense Newton updates.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
problem
|
NonlinearProblem
|
Residual and dense Jacobian callbacks. |
required |
initial_guess
|
Array
|
Explicit warm start in the desired array namespace. |
required |
Returns:
| Type | Description |
|---|---|
NonlinearSolveResult
|
Candidate root with array-valued convergence diagnostics. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If callbacks change namespace or dtype. |
ValueError
|
If no dense Jacobian is supplied or shapes are invalid. |
Source code in src/op_engine/nonlinear_solver.py
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 | |
DerivativeArtifact
¶
Bases: Protocol
Structural compiler boundary, with no runtime compiler dependency.
Matrices have shapes (N,N), (N,Q), (M,N), (M,Q). The producer declares supported operations and must represent the same smooth RHS/measurements.
model
property
¶
Identify the derivative producer's source model.
observable_names
property
¶
Give the ordered scalar measurement coordinates.
parameter_names
property
¶
Give RHS and measurement parameter coordinates.
state_names
property
¶
Give the ordered expanded state coordinates.
evaluate(t, y, **parameters)
¶
Evaluate native derivatives without changing coordinates or graphs.
Source code in src/op_engine/sensitivities.py
94 95 96 97 98 | |
DerivativeMatrices
¶
Bases: Protocol
Four native matrices in declared physical state/parameter coordinates.
DiffusionConfig(coeff, dtype=np.float64, bc='neumann')
dataclass
¶
Configuration for diffusion-like linear operators.
Attributes:
| Name | Type | Description |
|---|---|---|
coeff |
float
|
Physical diffusion coefficient D (units length^2 / time). |
dtype |
DTypeLike
|
Floating dtype (e.g. np.float64). |
bc |
str
|
Boundary condition; either "neumann" or "absorbing". |
__post_init__()
¶
Validate context-free diffusion parameters.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the coefficient or boundary condition is invalid. |
Source code in src/op_engine/matrix_ops.py
157 158 159 160 161 162 163 164 165 166 167 168 | |
DirectSSAConfig(max_events=1000000, forcing_breakpoints=())
dataclass
¶
Configuration for Gillespie's exact direct SSA.
Attributes:
| Name | Type | Description |
|---|---|---|
max_events |
int
|
Maximum number of events applied in one output interval. This guard detects explosive or otherwise pathological processes. |
forcing_breakpoints |
tuple[float, ...]
|
Strictly increasing times at which external forcing may change. Propensities must be constant in time between these boundaries while the state is unchanged. Forcing is right-continuous; an event at a boundary is discarded and redrawn. |
__post_init__()
¶
Validate the event-count guard and snapshot forcing boundaries.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the event-count guard or forcing schedule is invalid. |
Source code in src/op_engine/stochastic_solver.py
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | |
DirectSSASolver(core, stoichiometry, *, reaction_axis='state')
¶
Gillespie direct SSA for an exact continuous-time reaction process.
All reaction channels and batch cells form one flattened categorical event space. This is the superposition of the independent batched processes, so each accepted event changes exactly one batch cell. Propensities must be constant in time between events and declared forcing boundaries. Requested output times only observe the path and never cause an event to be resampled.
Initialize a reaction network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
core
|
ModelCore
|
Model state and output-time container. |
required |
stoichiometry
|
Array
|
Integer-valued matrix shaped (n_species, n_reactions). |
required |
reaction_axis
|
str | int
|
State axis changed by reaction firings. |
'state'
|
Source code in src/op_engine/stochastic_solver.py
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | |
n_reactions
property
¶
Return the number of reaction channels.
run(propensity_func, ssa_sampler=None, *, config=None, rng=None, recorder=None)
¶
Advance an exact reaction trajectory through the core output grid.
An event drawn beyond an output boundary is retained for the following interval. A pending event at or beyond a forcing boundary is discarded. Zero total propensity waits for the next forcing boundary without sampling; with no future boundary it is absorbing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
propensity_func
|
PropensityFunction
|
Reaction-channel propensities, constant in time between events and configured forcing boundaries. |
required |
ssa_sampler
|
SSASampler | None
|
Backend-specific exponential/categorical sampler. |
None
|
config
|
DirectSSAConfig | None
|
Optional event-count guard and forcing schedule. |
None
|
rng
|
RandomStream | None
|
Explicit NumPy stream; supply instead of ssa_sampler. |
None
|
recorder
|
FiringRecorder | None
|
Optional accepted-firing diagnostics, reset for this run. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If a sampler/stream is absent or both are supplied. |
TypeError
|
If rng is unsupported or used with non-NumPy state. |
RuntimeError
|
If an interval exceeds its event limit or a reaction produces a negative population. |
Source code in src/op_engine/stochastic_solver.py
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 | |
EquilibriumDomain
¶
Bases: StrEnum
Whether declared one-sided state constraints affect interpretation.
FiringRecorder(channels=None)
¶
Record selected channels in output intervals, without adding state rows.
Counts are NumPy int64 diagnostics, even when the evolving state uses another
namespace. Intervals are (t[i], t[i+1]]. A forcing change wins a tie with
a candidate event, so that discarded event is not counted. Reusing a recorder
starts a fresh record. Recording never consumes random numbers.
Examples:
>>> import numpy as np
>>> from op_engine import DirectSSASolver, ModelCore
>>> core = ModelCore(2, 1, np.array([0.0, 1.0]))
>>> core.set_initial_state(np.array([[10.0], [0.0]]))
>>> counts = FiringRecorder((0,))
>>> solver = DirectSSASolver(core, np.array([[-1.0], [1.0]]))
>>> def hazards(time, state):
... return state[:1]
>>> solver.run(hazards, rng=np.random.default_rng(4), recorder=counts)
>>> counts.counts.shape, counts.cumulative.shape
((1, 1, 1), (2, 1, 1))
>>> int(counts.counts.sum()) == int(core.state_array[-1, 1, 0])
True
Select local reaction indices; None records every channel.
Raises:
| Type | Description |
|---|---|
ValueError
|
Channel selections contain invalid or duplicate indices. |
Source code in src/op_engine/firing.py
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | |
counts
property
¶
Return read-only (interval, selected channel, batch...) counts.
Raises:
| Type | Description |
|---|---|
RuntimeError
|
The recorder has not been attached to a run. |
cumulative
property
¶
Return cumulative counts at output times, including an initial zero.
record(interval, flat_event_index)
¶
Count one accepted event in its channel and batch cell.
Raises:
| Type | Description |
|---|---|
RuntimeError
|
Recording has not started or an interval count overflows. |
Source code in src/op_engine/firing.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | |
start(n_intervals, reaction_shape, reaction_axis)
¶
Allocate a fresh record for a solver's validated reaction layout.
Raises:
| Type | Description |
|---|---|
ValueError
|
A selected channel is outside the reaction layout. |
Source code in src/op_engine/firing.py
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | |
GridGeometry(n, dx)
dataclass
¶
Geometry of a 1D spatial grid.
Attributes:
| Name | Type | Description |
|---|---|---|
n |
int
|
Number of grid points. |
dx |
float
|
Grid spacing. |
__post_init__()
¶
Validate context-free grid geometry.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the grid size or spacing is invalid. |
Source code in src/op_engine/matrix_ops.py
129 130 131 132 133 134 135 136 137 138 139 140 | |
LinearSolveCandidate(value, success, iterations, message='')
dataclass
¶
Callback output before the engine verifies the original residual.
success reports the solver's own termination status. A false status
cannot be overridden by a small residual. Iterations use the concrete
callback's declared unit and must fit its requested budget.
LinearSolveDiagnostics(converged, residual_norm, tolerance, iterations, message)
dataclass
¶
Eager convergence evidence, one entry per RHS column (one for vectors).
LinearSolveError(result)
¶
Bases: RuntimeError
A checked eager solve failed; result retains per-column evidence.
Retain the failed result and identify failed RHS columns.
Source code in src/op_engine/linear_operator.py
255 256 257 258 259 260 261 262 | |
LinearSolveOptions(rtol=1e-08, atol=1e-10, max_iterations=100)
dataclass
¶
Per-column true-residual tolerance and callback iteration budget.
A column passes when ||b - A x||_2 <= max(atol, rtol * ||b||_2).
max_iterations counts the callback's documented iteration unit; a
concrete adapter must declare whether this means inner steps or cycles.
__post_init__()
¶
Validate static tolerances and iteration budget.
Raises:
| Type | Description |
|---|---|
ValueError
|
If a tolerance or iteration budget is invalid. |
Source code in src/op_engine/linear_operator.py
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | |
LinearSolveRequest(operator, rhs, options=LinearSolveOptions(), preconditioner=None, context=None)
dataclass
¶
Explicit eager solve inputs; assembly and cache ownership stay external.
preconditioner is an optional approximate inverse action with the same
square shape, namespace and dtype as the operator. The concrete solver must
document its side and use, or reject it. context is caller-owned metadata
identifying mesh, coefficients, stage size/scale and preconditioner version.
A callback that caches preparation must invalidate whenever any of these
change. The engine creates no cache for this callback path.
LinearSolveResult(value, diagnostics)
dataclass
¶
Candidate solution with independently recomputed residual diagnostics.
LocalSpectrum
¶
Bases: StrEnum
Strict classification of an assessed reduced linear spectrum.
LocalStabilityConfig(residual_tolerance, spectral_absolute_tolerance, spectral_relative_tolerance, boundary_tolerance, finite_difference_step=None)
dataclass
¶
Explicit numerical thresholds for :func:local_stability.
residual_tolerance and boundary_tolerance may be scalars or one
value per state coordinate. Spectral tolerances have inverse-time units;
their effective band is absolute + relative * max(abs(eigenvalue)).
__post_init__()
¶
Reject invalid scalar controls before evaluating a model.
Raises:
| Type | Description |
|---|---|
ValueError
|
A spectral tolerance is negative, non-finite or not scalar. |
Source code in src/op_engine/equilibrium_stability.py
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | |
LocalStabilityResult(status, classification, message, state, time, coordinates, coordinate_system, time_unit, jacobian_source, jacobian_reference, model_digest, solver_converged, residual_tolerance, boundary_tolerance, fixed_mask, nonnegative_mask, domain=EquilibriumDomain.UNSPECIFIED, raw_residual=None, active_residual=None, residual_scaled_rms=None, boundary_coordinates=(), finite_difference_steps=None, jacobian=None, full_eigenvalues=None, active_jacobian=None, active_eigenvalues=None, invariant_rows=None, invariant_rank=0, constraint_rank=0, constraint_svd_tolerance=None, tangent_basis=None, tangent_jacobian=None, tangent_eigenvalues=None, conservation_error=None, conservation_tolerance=None, invariant_flow_error=None, invariant_flow_tolerance=None, expected_conservation_neutral_modes=0, observed_active_neutral_modes=None, effective_spectral_tolerance=None, spectral_abscissa=None, leading_eigenvalue=None, leading_timescale=None, timescale_kind=None)
dataclass
¶
Evidence and interpretation from one local linearization.
LocalStabilityStatus
¶
Bases: StrEnum
Numerical status, independent of any spectral classification.
ModelCore(n_states, n_subgroups, time_grid, *, options=None)
¶
Core state and time manager for time-evolving models.
Examples:
>>> import numpy as np
>>> core = ModelCore(1, 1, np.array([0.0, 0.5, 1.0]))
>>> core.set_initial_state(np.array([[2.0]]))
>>> core.get_current_state().shape
(1, 1)
>>> core.get_time_at(1)
0.5
Initialize ModelCore.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_states
|
int
|
Number of state variables. |
required |
n_subgroups
|
int
|
Number of subgroups (e.g., age groups). |
required |
time_grid
|
ndarray
|
1D array of times, shape (n_timesteps,). |
required |
options
|
ModelCoreOptions | None
|
Optional ModelCoreOptions for additional configuration. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
if time_grid is invalid or any shapes mismatch. |
Source code in src/op_engine/model_core.py
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | |
current_time
property
¶
Current simulation time t = time_grid[current_step].
Returns:
| Type | Description |
|---|---|
float
|
Current time as a float. |
state_ndim
property
¶
Number of state tensor dimensions (rank).
Returns:
| Type | Description |
|---|---|
int
|
State tensor rank as an integer. |
advance_timestep(next_state)
¶
Alias for apply_next_state, for solver-friendly naming.
Source code in src/op_engine/model_core.py
622 623 624 | |
apply_deltas(deltas)
¶
Apply state deltas, advancing the timestep.
Supports alternate solver implementations (e.g., splitting updates, additive increments) without forcing allocation of y_next.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
deltas
|
Array
|
State deltas to apply, shape state_shape. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
if deltas has incorrect shape. |
Source code in src/op_engine/model_core.py
554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 | |
apply_next_state(next_state)
¶
Set the next state directly, advancing the timestep.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
next_state
|
Array
|
State at the next timestep, shape state_shape. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
if next_state has incorrect shape. |
Source code in src/op_engine/model_core.py
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 | |
apply_trajectory(trajectory)
¶
Adopt a complete trajectory produced by a whole-grid solver.
This provides one functional update for strategies such as Diffrax that return every requested output at once. It avoids replaying immutable history through one concatenation per time point.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
trajectory
|
Array
|
Array shaped |
required |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the trajectory changes the active array namespace. |
ValueError
|
If the trajectory shape is invalid. |
Source code in src/op_engine/model_core.py
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 | |
axis_index(axis)
¶
Resolve an axis name or integer into an axis index.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
axis
|
str | int
|
Axis name or index. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Axis index as an integer. |
Raises:
| Type | Description |
|---|---|
IndexError
|
if axis index is out of bounds. |
ValueError
|
if axis name is unknown. |
Source code in src/op_engine/model_core.py
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | |
get_axis_coords(axis)
¶
Return coordinate array for a given axis, or None if not set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
axis
|
str | int
|
Axis name or index. |
required |
Returns:
| Type | Description |
|---|---|
ndarray | None
|
Coordinate array for the axis, or None if not set. |
Source code in src/op_engine/model_core.py
278 279 280 281 282 283 284 285 286 287 288 289 290 | |
get_current_state()
¶
Return the current state.
Returns:
| Type | Description |
|---|---|
Array
|
Current state, shape state_shape. |
Source code in src/op_engine/model_core.py
515 516 517 518 519 520 521 522 | |
get_dt(step_idx)
¶
Return dt for the step [t_step_idx, t_step_idx+1].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
step_idx
|
int
|
Timestep index in [0, n_timesteps - 1]. |
required |
Returns:
| Type | Description |
|---|---|
float
|
dt as a float. |
Raises:
| Type | Description |
|---|---|
IndexError
|
if step_idx is out of bounds. |
Source code in src/op_engine/model_core.py
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | |
get_state_at(step)
¶
Return the state at a given timestep from history.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
step
|
int
|
Timestep index in [0, n_timesteps). |
required |
Returns:
| Type | Description |
|---|---|
Array
|
State at the given timestep, shape state_shape. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
if history is not stored. |
IndexError
|
if step is out of bounds. |
Source code in src/op_engine/model_core.py
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 | |
get_time_at(step_idx)
¶
Return time at a given step index.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
step_idx
|
int
|
Timestep index in [0, n_timesteps). |
required |
Returns:
| Type | Description |
|---|---|
float
|
Time as a float. |
Raises:
| Type | Description |
|---|---|
IndexError
|
if step_idx is out of bounds. |
Source code in src/op_engine/model_core.py
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | |
reshape_for_axis_solve(x, axis)
¶
Reshape a state-like tensor into 2D for an axis-local operator solve.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
ndarray
|
State-like tensor of shape state_shape. |
required |
axis
|
str | int
|
Axis name or index along which to reshape. |
required |
Returns:
| Type | Description |
|---|---|
tuple[ndarray, tuple[int, ...], int]
|
(x2d, original_shape, axis_index) |
Raises:
| Type | Description |
|---|---|
ValueError
|
if x does not have shape state_shape. |
Source code in src/op_engine/model_core.py
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 | |
set_initial_state(initial_state)
¶
Set the initial state at time_grid[0].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
initial_state
|
Array
|
Initial state, shape state_shape. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
if initial_state has incorrect shape. |
Source code in src/op_engine/model_core.py
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | |
unreshape_from_axis_solve(x2d, original_shape, axis)
¶
Inverse of reshape_for_axis_solve.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x2d
|
ndarray
|
2D array of shape (axis_len, batch). |
required |
original_shape
|
tuple[int, ...]
|
Original full shape before reshape. |
required |
axis
|
str | int
|
Axis name or index along which the reshape was done. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Reconstructed array of shape original_shape. |
Source code in src/op_engine/model_core.py
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 | |
validate_state_shape(arr, *, msg=None)
¶
Validate that arr has state_shape.
This is intentionally small and solver-friendly; higher layers can reuse it to avoid duplicating shape checks for intermediate/stage states.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
arr
|
Array
|
Array to validate. |
required |
msg
|
str | None
|
Optional custom error message prefix. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
if arr does not have shape state_shape. |
Source code in src/op_engine/model_core.py
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | |
NewtonConfig(max_iterations=8, rtol=1e-08, atol=1e-10, damping=1.0)
dataclass
¶
Static configuration for the portable dense Newton solver.
Attributes:
| Name | Type | Description |
|---|---|---|
max_iterations |
int
|
Exact number of Newton updates to unroll. |
rtol |
float
|
Relative convergence tolerance against the initial residual norm. |
atol |
float
|
Absolute convergence tolerance. |
damping |
float
|
Fixed multiplier applied to every Newton update. |
__post_init__()
¶
Validate static solver parameters.
Raises:
| Type | Description |
|---|---|
ValueError
|
If an iteration count or tolerance is invalid. |
Source code in src/op_engine/nonlinear_solver.py
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | |
NewtonKrylovConfig(max_iterations=8, rtol=1e-08, atol=1e-10, damping=1.0, linear_options=(lambda: LinearSolveOptions(rtol=1e-06, atol=0.0))(), max_backtracks=12, backtrack_factor=0.5, armijo=0.0001)
dataclass
¶
Bases: NewtonConfig
Outer RMS tolerances, inner true-residual gate and Armijo backtracking.
Inherited max_iterations is a maximum number of applied Newton updates,
not an exact unroll count. The outer gate is atol + rtol * initial_rms.
Inner options independently use the checked linear solver's L2 gate
max(atol, rtol * ||rhs||) and its documented iteration budget.
Attributes:
| Name | Type | Description |
|---|---|---|
linear_options |
LinearSolveOptions
|
Explicit inner tolerance and iteration budget. |
max_backtracks |
int
|
Maximum reductions after the initial damped trial. |
backtrack_factor |
float
|
Multiplicative step-length reduction, strictly in (0,1). |
armijo |
float
|
Required fractional RMS decrease per unit step, strictly in (0,1). |
__post_init__()
¶
Validate outer, inner and globalization settings.
Raises:
| Type | Description |
|---|---|
TypeError
|
If inner options do not use the existing checked contract. |
ValueError
|
If backtracking settings are invalid. |
Source code in src/op_engine/newton_krylov.py
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | |
NewtonKrylovSolver(config=NewtonKrylovConfig(), linear_solver=ScipyGmresSolver(), preconditioner_factory=None)
dataclass
¶
Stateless eager NumPy Newton-GMRES with a per-linearization inverse factory.
The default inner solver is :class:ScipyGmresSolver (left inverse
preconditioning). A failed checked inner solve returns nonlinear
nonconvergence without applying its candidate; malformed callbacks and
arbitrary linear-solver exceptions remain fatal. The integration boundary
applies its existing fixed/adaptive/replay failure policy.
Attributes:
| Name | Type | Description |
|---|---|---|
config |
NewtonKrylovConfig
|
Outer/inner tolerances and bounded line search. |
linear_solver |
LinearSolver
|
Existing checked eager linear-solver callback. |
preconditioner_factory |
InversePreconditionerFactory | None
|
Optional factory receiving the exact current
request, operator and :class: |
__post_init__()
¶
Validate explicit configuration and callbacks.
Raises:
| Type | Description |
|---|---|
TypeError
|
If configuration or callbacks are unsupported. |
Source code in src/op_engine/newton_krylov.py
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | |
solve(problem, initial_guess)
¶
Return a root candidate and explicit eager termination evidence.
Returns:
| Type | Description |
|---|---|
NonlinearSolveResult
|
Owned candidate and residual with checked inner/outer diagnostics. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If input or callback arrays are not native real NumPy float32/float64 with matching shape/dtype/namespace. |
ValueError
|
If the state is empty or no residual JVP is supplied. |
Source code in src/op_engine/newton_krylov.py
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | |
NewtonKrylovTermination
¶
Bases: IntEnum
Eager termination codes, retained in stage/integration diagnostics.
NewtonLinearization(iteration, iterate, problem_context)
dataclass
¶
Unique per-linearization preconditioner context, with an owned iterate.
iterate is a read-only snapshot. Its full shape, dtype and coefficients,
problem_context (including SDIRK scale/time when applicable) and this
record's identity define the preparation lifetime. A factory is invoked
afresh for every linearization; a caller retaining a cache owns invalidation.
No iterate history is retained in solve diagnostics.
NonlinearConvergenceError(result)
¶
Bases: RuntimeError
Raised by an eager boundary when a nonlinear solve did not converge.
Store the failed result and its diagnostics.
Source code in src/op_engine/nonlinear_solver.py
322 323 324 325 326 327 328 329 330 | |
NonlinearIntegrationConvergenceError(diagnostics)
¶
Bases: RuntimeError
Raised after validating failed array-valued integration diagnostics.
Store diagnostics for the invalid integration or frozen mesh.
Source code in src/op_engine/core_solver.py
663 664 665 666 667 668 669 670 671 672 673 | |
NonlinearIntegrationDiagnostics
¶
Bases: NamedTuple
Array-valued nonlinear diagnostics for one integration or replay.
Every array is in the state array's namespace, so the record can cross a
compiled JAX boundary. stages_per_step maps flattened stage fields back
to attempted steps. Rejected adaptive attempts remain present with
step_accepted=False.
require_converged()
¶
Return valid diagnostics or invalidate a failed compiled replay.
Returns:
| Type | Description |
|---|---|
NonlinearIntegrationDiagnostics
|
This unchanged diagnostic record. |
Raises:
| Type | Description |
|---|---|
NonlinearIntegrationConvergenceError
|
If an accepted or replayed step contains a failed nonlinear stage. |
Source code in src/op_engine/core_solver.py
645 646 647 648 649 650 651 652 653 654 655 656 657 | |
NonlinearMethodConfig(rhs_jacobian=None, solver=DenseNewtonSolver(), rhs_jvp=None)
dataclass
¶
Configuration for fully nonlinear integration methods.
Derivatives act on the entire RHS state, including cross-axis coupling.
They are deliberately separate from :attr:RunConfig.jacobian, whose
operators act only along CoreSolver.operator_axis for linearly implicit
methods. Supply at least one derivative form and a solver that supports it.
The default dense solver requires rhs_jacobian.
Attributes:
| Name | Type | Description |
|---|---|---|
rhs_jacobian |
FullRhsJacobianFunction | None
|
Dense full-system Jacobian with shape
|
solver |
NonlinearSolver
|
Backend-neutral nonlinear solver implementation. |
rhs_jvp |
FullRhsJvpFunction | None
|
Optional full RHS derivative action |
__post_init__()
¶
Validate the method boundary without selecting an array backend.
Raises:
| Type | Description |
|---|---|
TypeError
|
If a callback or nonlinear solver is invalid, or neither derivative form is supplied. |
Source code in src/op_engine/core_solver.py
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 | |
NonlinearProblem(residual, jacobian=None, jvp=None, context=None)
dataclass
¶
Residual and optional derivative actions for a nonlinear equation.
residual(x) must return an array with the same shape, dtype, and array
namespace as x. jacobian(x) returns a dense square array acting on
the flattened residual. jvp(x, vector) returns J(x) @ vector with
the same structure as x. Solvers may require either derivative form;
:class:DenseNewtonSolver specifically requires jacobian.
Attributes:
| Name | Type | Description |
|---|---|---|
residual |
NonlinearResidual
|
Residual function whose root is sought. |
jacobian |
NonlinearJacobian | None
|
Optional dense Jacobian function. |
jvp |
JacobianVectorProduct | None
|
Optional matrix-free Jacobian-vector product. |
context |
object | None
|
Caller-owned stage/linearization metadata; no cache is created. |
__post_init__()
¶
Validate callback presence.
Raises:
| Type | Description |
|---|---|
TypeError
|
If a supplied callback is not callable. |
Source code in src/op_engine/nonlinear_solver.py
62 63 64 65 66 67 68 69 70 71 72 73 74 75 | |
NonlinearSolveDiagnostics(converged, iterations, residual_evaluations, jacobian_evaluations, initial_residual_norm, residual_norm, step_norm, linear_solves=(), termination=0, jvp_evaluations=0, backtracks=0)
dataclass
¶
Array-safe diagnostics from a nonlinear solve.
converged and the norm fields are zero-dimensional arrays in the
initial guess's namespace. Keeping them on-device avoids an accidental
host synchronization or tracer conversion in compiled code.
Attributes:
| Name | Type | Description |
|---|---|---|
converged |
Array
|
Boolean array indicating finite residual convergence. |
iterations |
int
|
Number of nonlinear updates performed. |
residual_evaluations |
int
|
Number of residual evaluations performed. |
jacobian_evaluations |
int
|
Number of dense Jacobian evaluations performed. |
initial_residual_norm |
Array
|
RMS norm before the first update. |
residual_norm |
Array
|
RMS norm after the final update. |
step_norm |
Array
|
RMS norm of the final damped update. |
linear_solves |
tuple[LinearSolveDiagnostics, ...]
|
Checked eager inner solves in execution order. |
termination |
int
|
Optional eager solver termination code (zero is unspecified). |
jvp_evaluations |
int
|
Number of residual derivative actions evaluated. |
backtracks |
int
|
Number of step-length reductions attempted. |
NonlinearSolveResult(value, residual, diagnostics)
dataclass
¶
Candidate root, final residual, and convergence diagnostics.
NonlinearSolver
¶
Bases: Protocol
Backend-neutral interface implemented by nonlinear solvers.
solve(problem, initial_guess)
¶
Return a candidate root and explicit convergence diagnostics.
Source code in src/op_engine/nonlinear_solver.py
166 167 168 169 170 171 172 | |
NonlinearStageContext(time, step_size, diagonal_step, stage_index)
dataclass
¶
Explicit SDIRK stage metadata, freshly bound on every stage and retry.
NonlinearWorkDiagnostics
¶
Bases: NamedTuple
Ragged eager inner-solve evidence using only namespace-preserving arrays.
solves_per_stage maps linear solves to flattened stages;
columns_per_solve maps residual/threshold/convergence entries to those
solves. Iteration counts are per solve. Termination, JVP and backtracking
counts are per stage. Zero termination means unspecified (the dense
default). Tolerances and L2 residuals use the integration diagnostic dtype;
the checked inner convergence flag was computed before this conversion.
NumpyPoissonSampler(seed=None, *, rng=None)
¶
Seeded stateful Poisson sampler for NumPy tau-leaping runs.
Create a NumPy generator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seed
|
int | None
|
Optional seed passed to :func: |
None
|
rng
|
RandomStream | None
|
Advancing generator or replayable SeedSequence; excludes seed. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If both seed and rng are supplied. |
TypeError
|
If rng has an unsupported type. |
Source code in src/op_engine/stochastic_solver.py
177 178 179 180 181 182 183 184 185 186 187 188 189 190 | |
__call__(mean, step_index)
¶
Draw Poisson firing counts in the NumPy namespace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mean
|
Array
|
Non-negative Poisson means. |
required |
step_index
|
int
|
Accepted-step index; unused by the stateful generator. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
NumPy integer firing-count array. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
Source code in src/op_engine/stochastic_solver.py
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | |
NumpySSASampler(seed=None, *, rng=None)
¶
Seeded stateful direct-SSA sampler for NumPy runs.
Create a NumPy generator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seed
|
int | None
|
Optional seed passed to :func: |
None
|
rng
|
RandomStream | None
|
Advancing generator or replayable SeedSequence; excludes seed. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If both seed and rng are supplied. |
TypeError
|
If rng has an unsupported type. |
Source code in src/op_engine/stochastic_solver.py
215 216 217 218 219 220 221 222 223 224 225 226 227 228 | |
__call__(total_rate, probabilities, draw_index)
¶
Draw an exponential wait and flattened categorical event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
total_rate
|
Array
|
Positive scalar sum of all propensities. |
required |
probabilities
|
Array
|
Normalized batched reaction probabilities. |
required |
draw_index
|
int
|
Draw index; unused by the stateful generator. |
required |
Returns:
| Type | Description |
|---|---|
SSASample
|
A NumPy scalar waiting time and integer event index. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If either input is not a NumPy array. |
Source code in src/op_engine/stochastic_solver.py
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | |
NumpyThinningSampler(seed=None, *, rng=None)
¶
Seeded stateful thinning sampler for NumPy reaction networks.
Create or reuse a NumPy generator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seed
|
int | None
|
Optional legacy integer seed. |
None
|
rng
|
RandomStream | None
|
Advancing generator or replayable SeedSequence; excludes seed. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If both seed and rng are supplied. |
TypeError
|
If rng has an unsupported type. |
Source code in src/op_engine/thinning_ssa.py
149 150 151 152 153 154 155 156 157 158 159 160 161 162 | |
__call__(bound_rate, draw_index)
¶
Draw a candidate wait and uniform in the input dtype.
Returns:
| Type | Description |
|---|---|
ThinningSample
|
Scalar NumPy sampling arrays. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the bound rate is not a NumPy array. |
Source code in src/op_engine/thinning_ssa.py
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | |
ObservationDiagnostics
¶
Bases: NamedTuple
Describe evaluation coverage without inventing a numerical error estimate.
Accuracy inherits both the supplied trajectory and evaluator. No method has a qualified continuous extension through this interface yet. Spatial evaluation is owned by the callback; the compiler adapter selects declared nodes and applies declared measures without interpolation.
ObservationEvaluator
¶
Bases: Protocol
Evaluate one native output from an instantaneous state and parameters.
__call__(t, y, **params)
¶
Return one native output with the declared shape and state dtype.
Source code in src/op_engine/observations.py
22 23 24 | |
ObservationMeasure
¶
Bases: NamedTuple
Describe weights already applied by an evaluator, without applying them again.
ObservationMetadata
¶
Bases: NamedTuple
Static scientific output metadata, separate from solver state layout.
Attributes:
| Name | Type | Description |
|---|---|---|
output_shape |
tuple[int, ...]
|
Shape after evaluator reductions, excluding time. |
coordinates |
tuple[tuple[str, tuple[str, ...]], ...]
|
Ordered output axis names and coordinate labels. |
units |
str | None
|
Declared output units; no dimensional verification is implied. |
state_dependencies |
tuple[str, ...]
|
Direct state base dependencies. |
parameter_shapes |
tuple[tuple[str, tuple[int, ...]], ...]
|
Direct parameters and complete input shapes. |
measure_requirements |
tuple[tuple[str, ObservationMeasure], ...]
|
Named measures already applied by the evaluator. |
time_dependent |
bool
|
Whether the expression explicitly references time. |
description |
str | None
|
Optional scientific interpretation. |
ObservationResult
¶
Bases: NamedTuple
Static times, read-only named series mapping, and evaluation diagnostics.
ObservationSeries
¶
Bases: NamedTuple
Native (n_output_times, *output_shape) values with their specification.
ObservationSpec
¶
Bases: NamedTuple
A named evaluator and its immutable output description.
Custom evaluators receive each state in the trajectory's natural shape.
Use :func:observation_from_compiled to flatten each state for an op_system
compiled observable, preserving that compiler's state ordering.
ObservationSummary
¶
Bases: NamedTuple
A sampled window and bounded-size named reductions, without a trajectory.
The window is exactly the first/last supplied time. There is no off-grid clipping, extrapolation or qualified method-specific dense output. The diagnostics report callback count without an independent error estimate.
ObservationSummaryValue
¶
Bases: NamedTuple
Native summary arrays with the original scientific output specification.
Attributes:
| Name | Type | Description |
|---|---|---|
spec |
ObservationSpec
|
Instantaneous output shape, coordinates, units and interpretation. |
initial |
Array
|
Output at the first supplied sample. |
final |
Array
|
Output at the last supplied sample. |
change |
Array
|
Final minus initial; appropriate for a cumulative counter. |
integral |
Array
|
Composite-trapezoid time integral over the supplied samples. Its units are output units multiplied by the caller's time unit. |
OutputStateCheckConfig(nonnegative_indices=None, monotone_indices=(), negative_tolerance=0.0, monotone_tolerance=0.0)
dataclass
¶
Components and tolerances for checks at requested output times.
Attributes:
| Name | Type | Description |
|---|---|---|
nonnegative_indices |
tuple[int, ...] | None
|
State components expected to be nonnegative;
|
monotone_indices |
tuple[int, ...]
|
Components expected to be nondecreasing, such as cumulative counters. Empty disables increment checks. |
negative_tolerance |
float
|
A value below minus this absolute tolerance flags an output. This changes the diagnostic threshold, not the state. |
monotone_tolerance |
float
|
An increment below minus this absolute tolerance flags an output interval. It is not scaled by interval duration. |
__post_init__()
¶
Detach selectors and validate finite nonnegative tolerances.
Raises:
| Type | Description |
|---|---|
TypeError
|
If a selector or tolerance has the wrong type. |
ValueError
|
If a selector or tolerance is invalid. |
Source code in src/op_engine/state_diagnostics.py
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | |
OutputStateDiagnostics
¶
Bases: NamedTuple
Per-subgroup/field-cell checks over the requested output grid.
Arrays retain every state axis except the state-component axis. Counts count outputs or intervals with at least one flagged component, not the number of components. Values and flags stay in the input namespace.
Attributes:
| Name | Type | Description |
|---|---|---|
n_outputs |
int
|
Number of inspected outputs, including the initial state. |
complete |
bool
|
Whether every requested output was inspected. |
min_state |
Array
|
Minimum selected nonnegative-state value across outputs. NaNs propagate; inspect nonfinite counts too. |
n_negative_outputs |
Array
|
Outputs with any selected state below tolerance. |
n_nonfinite_outputs |
Array
|
Outputs with any nonfinite state component,
including components outside |
min_increment |
Array | None
|
Minimum increment of the selected monotone components,
or |
n_decreasing_intervals |
Array | None
|
Output intervals with any selected decreasing
component, or |
valid
property
¶
Return native flags for complete, finite, unflagged output records.
PoissonSampler
¶
Bases: Protocol
Backend-specific Poisson sampler injected into tau-leaping.
step_index is a stable, zero-based accepted-step index. Functional
PRNG ecosystems can derive a distinct key from it without mutable state.
__call__(mean, step_index)
¶
Draw independent Poisson counts with the shape of mean.
Source code in src/op_engine/stochastic_solver.py
64 65 | |
RateBoundFunction
¶
Bases: Protocol
Bound total propensity at a fixed state on [t, valid_until).
The callback must return t < valid_until <= limit. limit is the
next forcing change or solve endpoint, independent of observation times.
__call__(t, state, limit)
¶
Return a certified bound and its exclusive expiry time.
Source code in src/op_engine/thinning_ssa.py
93 94 | |
ReplicateReactionNetwork(stoichiometry, channel_names, channel_reactions, n_replicates, forcing_breakpoints, _batch_axis, _states, _reactions, _params, _time_axis, _time_coordinates, _table_axes, _axis_sizes)
dataclass
¶
One local stoichiometry plus a vectorized, independent propensity bank.
Local state/channel ordering follows the existing flat adapter after removing the declared replicate axis. Full input parameter arrays retain declared axis order. Parameters are read on every call; changing their values is allowed between runs and no interpolation result is cached.
flatten_history(history)
¶
Restore compiler flat cell order from a local bank history.
Returns:
| Type | Description |
|---|---|
FloatBank
|
History shaped (output time, full compiler state). |
Raises:
| Type | Description |
|---|---|
ValueError
|
The bank history has an incompatible layout. |
Source code in src/op_engine/replicate_network.py
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | |
pack_state(flat_state)
¶
Convert compiler flat state order into (local species, replicate).
Returns:
| Type | Description |
|---|---|
FloatBank
|
A local state bank preserving each template's declared axis order. |
Raises:
| Type | Description |
|---|---|
ValueError
|
The flat state has an incompatible size. |
Source code in src/op_engine/replicate_network.py
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | |
propensity(times, state)
¶
Evaluate one hazard bank with every table resolved at local clocks.
Returns:
| Type | Description |
|---|---|
FloatBank
|
NumPy propensities shaped (local channel, replicate). |
Raises:
| Type | Description |
|---|---|
ValueError
|
State, clocks, parameter tables or reaction outputs have incompatible shapes. |
Source code in src/op_engine/replicate_network.py
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | |
SSASample
¶
SSASampler
¶
Bases: Protocol
Backend-specific direct-SSA sampler.
draw_index is a stable zero-based index for each random draw. Functional
PRNG ecosystems can derive a distinct key from it without mutable state.
Probabilities have the full batched reaction shape; the returned event index
addresses their flattened representation.
__call__(total_rate, probabilities, draw_index)
¶
Draw an exponential wait and one categorical event index.
Source code in src/op_engine/stochastic_solver.py
90 91 92 93 94 95 96 97 | |
ScipyGmresSolver(restart=20)
dataclass
¶
Uncached eager GMRES with explicit left inverse preconditioning.
The requested iteration budget is inner iterations per RHS column.
iterations in the candidate/checked diagnostics is the maximum used by
any column, not the total across columns. Each column starts at zero.
There is no warm-start, basis, factorization or preconditioner cache.
SciPy minimizes a preconditioned residual; solve_linear independently gates
the original residual before stage adoption. No differentiation is supplied.
__call__(request)
¶
Solve independent columns without forming the represented matrix.
Returns:
| Type | Description |
|---|---|
LinearSolveCandidate
|
Candidate and solver termination evidence for original-residual checks. |
Source code in src/op_engine/scipy_operator.py
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | |
__post_init__()
¶
Validate the static restart length.
Raises:
| Type | Description |
|---|---|
ValueError
|
If restart is not a positive integer. |
Source code in src/op_engine/scipy_operator.py
234 235 236 237 238 239 240 241 242 243 244 245 246 | |
SensitivityInitial(state, parameter_derivatives)
dataclass
¶
Native state (N,) and its required parameter derivative (N,P).
Pass an explicit zero matrix for parameter-independent initial states. This avoids silently dropping initial-condition derivatives.
SensitivityOptions(solver=(lambda: RunConfig(method='rk4'))(), store_history=False, max_augmented_states=16384, max_output_bytes=64 * 1024 * 1024)
dataclass
¶
Bound fixed explicit integration and retained numerical output.
Only the final output is retained by default. History adds requested output times, not internal stages. Byte limits cover returned numeric arrays, not temporary work, AD graphs, compiler memory or the whole process.
__post_init__()
¶
Reject unsupported numerical paths instead of silently downshifting.
Raises:
| Type | Description |
|---|---|
ValueError
|
Solver mode or storage bounds are unsupported. |
TypeError
|
History is not boolean. |
Source code in src/op_engine/sensitivities.py
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
SensitivitySolution(source_model, state_names, parameter_names, observable_names, times, mesh, states, parameter_derivatives, observable_derivatives, augmented_dimension, options)
dataclass
¶
Native output states and parameter derivatives with static provenance.
Array shapes are (T,N), (T,N,P) and (T,M,P). Measurement sensitivities are
dg/dy @ S + dg/dtheta in the same parameter order. They do not include
observation noise, prior curvature or nuisance elimination. times
contains only retained outputs; mesh is the requested solver mesh.
SensitivitySystem(rhs, derivatives, initial_parameters=())
dataclass
¶
Bind one RHS to derivatives and explicitly named initial-only parameters.
rhs accepts every derivative-artifact parameter, including measurement-
only parameters. Initial-only names are appended to that ordered layout and
excluded from RHS/derivative calls; their effects enter through the required
initial derivative matrix. The caller is responsible for binding the same
RHS as the derivative producer and for declaring a smooth deterministic ODE.
parameter_names
property
¶
Return derivative parameters followed by initial-only parameters.
__post_init__()
¶
Reject ambiguous coordinate layouts before numerical work.
Raises:
| Type | Description |
|---|---|
ValueError
|
Names are empty, duplicate or overlap. |
TypeError
|
The RHS is not callable. |
Source code in src/op_engine/sensitivities.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | |
SparseAdapter(ecosystem_id, issparse, factorize=None, solve=None, cache_key=None, linear_solver=None, solve_options=LinearSolveOptions(), preconditioner=None, context=None, accepts_right=None)
dataclass
¶
Function bundle in the existing sparse/operator registry.
Sparse acceleration is optional: dense operators always fall back to the
input array's Array-API linalg.solve implementation. Adapters are
selected structurally with their own issparse predicate. Existing
factorize/solve/cache_key bundles retain their historical identity cache.
Alternatively, linear_solver opts into a checked, uncached eager NumPy
solve. The two routes are mutually exclusive. accepts_right optionally
recognizes mixed right operators; otherwise issparse must accept both.
New callbacks own preparation, context invalidation and preconditioner use.
__post_init__()
¶
Reject incomplete or conflicting dispatch routes.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the identifier or route configuration is invalid. |
TypeError
|
If a predicate or callback is not callable. |
Source code in src/op_engine/matrix_ops.py
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | |
StabilityJacobianSource
¶
Bases: StrEnum
Provenance of the dense full-state Jacobian.
StabilityTimescaleKind
¶
Bases: StrEnum
Interpretation of an e-folding timescale.
SteadyStateConfig(dt0=1.0, dt_max=1000000000000.0, min_growth=2.0, max_growth=10.0, max_iterations=100, residual_tol=1e-09, step_tol=1e-09, atol=1e-08, early_exit=True)
dataclass
¶
Controls for :func:steady_state.
Attributes:
| Name | Type | Description |
|---|---|---|
dt0 |
float
|
Initial pseudo-time step, in the RHS's time units. |
dt_max |
float
|
Largest pseudo-time step. |
min_growth |
float
|
Smallest factor by which |
max_growth |
float
|
Largest factor by which |
max_iterations |
int
|
Iteration budget; the loop is unrolled this many times
when |
residual_tol |
float
|
Bound on the RMS of |
step_tol |
float
|
Bound on the RMS of the Newton correction
|
atol |
float
|
Absolute floor of the per-state scale |
early_exit |
bool
|
With the default Python loop, stop as soon as the solve
converges. This converts the convergence flag to a host boolean,
so under |
__post_init__()
¶
Validate the controls.
Raises:
| Type | Description |
|---|---|
ValueError
|
If a control is outside its valid range. |
Source code in src/op_engine/steady_state.py
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | |
SteadyStateConvergenceError(result)
¶
Bases: RuntimeError
Raised at an eager boundary when a steady-state solve did not converge.
Store the failed result.
Source code in src/op_engine/steady_state.py
176 177 178 179 180 181 182 183 184 | |
SteadyStateResult(state, residual, converged, iterations, residual_norm, step_norm, dt, invariant_drift)
dataclass
¶
Candidate steady state and array-valued diagnostics.
Every diagnostic is a zero-dimensional array in the state's namespace, so
a traced solve returns them without a host conversion; check them
afterwards, or call :func:require_steady_state at an eager boundary.
Attributes:
| Name | Type | Description |
|---|---|---|
state |
Array
|
The candidate steady state, including fixed states. |
residual |
Array
|
|
converged |
Array
|
Whether both the residual and the Newton correction met their tolerances. |
iterations |
Array
|
PTC attempts performed before convergence, including rejected steps. |
residual_norm |
Array
|
Scaled residual RMS at |
step_norm |
Array
|
Scaled RMS of the last Newton correction. |
dt |
Array
|
Final pseudo-time step. |
invariant_drift |
Array
|
Largest |
SymbolicDerivativeArtifact
¶
Bases: Protocol
Structural surface consumed from op_system.SymbolicDerivatives.
evaluate(t, y, **parameters)
¶
Evaluate derivative matrices in the artifact's declared order.
Source code in src/op_engine/equilibrium_stability.py
88 89 90 | |
TauLeapingConfig(max_step=None, max_steps=1000000, forcing_breakpoints=())
dataclass
¶
Configuration for fixed-step explicit tau-leaping.
Attributes:
| Name | Type | Description |
|---|---|---|
max_step |
float | None
|
Maximum internal tau. |
max_steps |
int
|
Maximum number of internal leaps per output interval. |
forcing_breakpoints |
tuple[float, ...]
|
Strictly increasing finite forcing-change times. Leaps end at these boundaries and reevaluate right-continuous rates. |
__post_init__()
¶
Validate fixed tau controls.
Raises:
| Type | Description |
|---|---|
ValueError
|
If a control is outside its valid range. |
Source code in src/op_engine/stochastic_solver.py
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | |
TauLeapingSolver(core, stoichiometry, *, reaction_axis='state')
¶
Fixed-step explicit Poisson tau-leaping on a ModelCore state.
The stoichiometric matrix has shape (n_species, n_reactions). The
configured reaction axis identifies the species dimension in the state;
every other dimension is treated as an independent batch. A propensity
function returns the same batched shape with n_reactions replacing
n_species on that axis.
Initialize a reaction network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
core
|
ModelCore
|
Model state and output-time container. |
required |
stoichiometry
|
Array
|
Integer-valued matrix shaped
|
required |
reaction_axis
|
str | int
|
State axis changed by reaction firings. |
'state'
|
Source code in src/op_engine/stochastic_solver.py
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 | |
n_reactions
property
¶
Return the number of reaction channels.
run(propensity_func, poisson_sampler=None, *, config=None, rng=None)
¶
Advance the reaction network through the core output grid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
propensity_func
|
PropensityFunction
|
Reaction-channel propensity function. |
required |
poisson_sampler
|
PoissonSampler | None
|
Backend-specific Poisson sampler. |
None
|
config
|
TauLeapingConfig | None
|
Optional fixed-tau controls and forcing schedule. |
None
|
rng
|
RandomStream | None
|
Explicit NumPy stream; supply instead of poisson_sampler. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If a sampler/stream is absent or both are supplied. |
TypeError
|
If rng is unsupported or used with non-NumPy state. |
RuntimeError
|
If an interval exceeds its step limit or a leap produces a negative population. |
Source code in src/op_engine/stochastic_solver.py
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 | |
ThinningSSAConfig(max_candidates=1000000, forcing_breakpoints=())
dataclass
¶
Controls for exact bounded-thinning SSA.
Attributes:
| Name | Type | Description |
|---|---|---|
max_candidates |
int
|
Maximum candidate draws across the entire run, including rejected and expired candidates. |
forcing_breakpoints |
tuple[float, ...]
|
Strictly increasing finite forcing changes. Forcing and bound expiry take precedence over tied candidates. |
__post_init__()
¶
Validate the candidate guard and snapshot the forcing schedule.
Raises:
| Type | Description |
|---|---|
ValueError
|
If either control is invalid. |
Source code in src/op_engine/thinning_ssa.py
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | |
ThinningSSASolver(core, stoichiometry, *, reaction_axis='state')
¶
Exact thinning SSA with user-certified total-rate bounds.
Reaction and batch channels share one candidate clock. Rates may vary smoothly while the state is unchanged; a valid bound must cover their total over the entire declared interval. Observation times only observe the trajectory and never refresh bounds or discard candidates.
Initialize the shared validated reaction network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
core
|
ModelCore
|
Model state and observation-time container. |
required |
stoichiometry
|
Array
|
Integer-valued species-by-reaction matrix. |
required |
reaction_axis
|
str | int
|
State axis changed by reaction firings. |
'state'
|
Source code in src/op_engine/thinning_ssa.py
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | |
n_reactions
property
¶
Return the number of reaction channels.
run(propensity_func, thinning_sampler=None, *, rate_bound, config=None, rng=None)
¶
Advance an exact trajectory with bounded candidate thinning.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
propensity_func
|
PropensityFunction
|
Time-dependent batched reaction propensities. |
required |
thinning_sampler
|
ThinningSampler | None
|
Namespace-preserving candidate sampler. |
None
|
rate_bound
|
float | RateBoundFunction
|
Constant bound or callback returning a certified bound
on |
required |
config
|
ThinningSSAConfig | None
|
Candidate guard and forcing schedule. |
None
|
rng
|
RandomStream | None
|
Explicit NumPy stream; supply instead of thinning_sampler. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If a sampler/stream is absent or both are supplied. |
TypeError
|
If rng is unsupported or used with non-NumPy state. |
RuntimeError
|
If the candidate limit is exceeded, time cannot advance, or a reaction produces invalid populations. |
Source code in src/op_engine/thinning_ssa.py
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 | |
ThinningSample
¶
Bases: NamedTuple
Independent exponential wait and uniform in the active array namespace.
Both values are real floating scalar arrays. waiting_time is finite
and positive; uniform is finite and belongs to [0, 1).
ThinningSampler
¶
Bases: Protocol
Sample candidates with globally increasing zero-based draw indices.
__call__(bound_rate, draw_index)
¶
Draw a wait at bound_rate and an independent uniform.
Source code in src/op_engine/thinning_ssa.py
111 112 | |
TotalRateBound(rate, valid_until)
dataclass
¶
Upper bound on all reaction/batch rates until an exclusive endpoint.
Attributes:
| Name | Type | Description |
|---|---|---|
rate |
float
|
Finite non-negative total-rate bound at the unchanged state. |
valid_until |
float
|
Finite exclusive endpoint, checked against the current time and forcing/solve limit when the callback returns it. |
__post_init__()
¶
Normalize and validate the scalar controls.
Raises:
| Type | Description |
|---|---|
ValueError
|
If either control is invalid. |
Source code in src/op_engine/thinning_ssa.py
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | |
array_namespace(value)
¶
Return an Array-API-compatible namespace for value.
array-api-compat recognizes both arrays that implement
__array_namespace__ and native arrays such as torch.Tensor that
need a compatibility namespace. Optional backends are imported only when
one of their arrays is supplied.
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
Source code in src/op_engine/_array.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | |
build_advection_matrix(n, dx, velocity, *, bc='absorbing', reference=None)
¶
Build a dense first-order upwind finite-volume operator.
The returned matrix A acts on a column state as dy = A @ y.
Positive velocity transports values toward increasing coordinate indices;
negative velocity transports toward decreasing indices. The velocity may be
an Array-API scalar, so its value stays dynamic under transformations such
as JAX jit and grad.
Boundary modes are:
absorbing: zero inflow at the upstream boundary and free outflow at the downstream boundary;reflecting: zero flux through the downstream boundary;periodic: downstream outflow wraps to the upstream boundary.
The namespace comes from reference when provided, then from velocity;
plain numeric velocities use NumPy. Grid geometry and the boundary mode are
static structural inputs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
int
|
Number of uniformly spaced finite-volume cells. |
required |
dx
|
float
|
Positive cell width. |
required |
velocity
|
float | Array
|
Signed scalar transport velocity. |
required |
bc
|
str
|
Boundary mode: |
'absorbing'
|
reference
|
Array | None
|
Optional array whose namespace and floating dtype control the result. |
None
|
Returns:
| Type | Description |
|---|---|
Array
|
Dense |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the grid, velocity shape/value, or boundary mode is invalid. |
Source code in src/op_engine/matrix_ops.py
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 | |
build_crank_nicolson_operator(geom, cfg, dt)
¶
Build Crank-Nicolson operators with dense/sparse autodispatch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
geom
|
GridGeometry
|
Grid geometry. |
required |
cfg
|
DiffusionConfig
|
Diffusion configuration. |
required |
dt
|
float
|
Time step. |
required |
Returns:
| Type | Description |
|---|---|
tuple[Operator, Operator]
|
Tuple of (L, R) operators for Crank-Nicolson scheme. |
Source code in src/op_engine/matrix_ops.py
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 | |
build_diffusion_matrix(n, dx, coefficient, *, grid=None, bc='neumann', reference=None)
¶
Build a dense second-order 1D finite-volume diffusion operator.
The returned matrix A acts on a column state as dy = A @ y.
Supply either a uniform cell width with dx or strictly increasing
cell-center coordinates with grid. On a non-uniform grid, interior
flux differences are divided by the local Voronoi-cell width. Boundary
faces are inferred one half-spacing beyond the first and last centers.
The coefficient may be an Array-API scalar, so it stays dynamic under
transformations such as JAX jit and grad. Static geometry is
assembled with NumPy and transferred once to the namespace selected by
reference or coefficient.
Boundary modes are:
neumannorreflecting: zero flux at both boundaries;absorbing: zero-valued exterior ghost cells;periodic: the two grid ends are adjacent. A grid passed explicitly must be uniform because its coordinates do not determine wrap spacing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
int
|
Number of finite-volume cells. |
required |
dx
|
float | None
|
Positive uniform cell width, or |
required |
coefficient
|
float | Array
|
Non-negative scalar diffusion coefficient. |
required |
grid
|
ArrayLike | None
|
Optional strictly increasing cell-center coordinates of shape
|
None
|
bc
|
str
|
Boundary mode: neumann, reflecting, absorbing, or periodic. |
'neumann'
|
reference
|
Array | None
|
Optional array whose namespace and floating dtype control the result. |
None
|
Returns:
| Type | Description |
|---|---|
Array
|
Dense |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the geometry, coefficient, or boundary mode is invalid. |
Source code in src/op_engine/matrix_ops.py
480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 | |
build_laplacian_tridiag(n, dx, coeff, dtype=np.float64, bc='neumann', *, grid=None)
¶
Build a sparse 1D finite-volume Laplacian.
The resulting operator corresponds to coeff * Δ_h. Supply either a
uniform cell width with dx or strictly increasing cell-center
coordinates with grid. No time-step scaling is applied here.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
int
|
Number of finite-volume cells. |
required |
dx
|
float | None
|
Positive uniform cell width, or |
required |
coeff
|
float
|
Physical diffusion coefficient D (units length^2 / time). |
required |
dtype
|
DTypeLike
|
Floating dtype (e.g. np.float64). |
float64
|
bc
|
str
|
Boundary condition; either |
'neumann'
|
grid
|
ArrayLike | None
|
Optional strictly increasing cell-center coordinates of shape
|
None
|
Returns:
| Type | Description |
|---|---|
csr_matrix
|
Sparse CSR matrix representing the Laplacian operator. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the geometry or boundary condition is invalid. |
Source code in src/op_engine/matrix_ops.py
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 | |
build_predictor_corrector(base_matrix)
¶
Build predictor-corrector matrices with dense/sparse autodispatch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base_matrix
|
DenseOperator | csr_matrix
|
Base linear operator A. |
required |
Returns:
| Type | Description |
|---|---|
tuple[Operator, Operator, Operator]
|
Tuple of (predictor, L, R) operators for predictor-corrector scheme. |
Source code in src/op_engine/matrix_ops.py
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 | |
clear_implicit_solver_cache()
¶
Clear the internal implicit solver cache.
Source code in src/op_engine/matrix_ops.py
1064 1065 1066 | |
compile_reaction_network(reactions, *, template_shapes, axis_sizes, params, n_state=None, reaction_names=None)
¶
Compile op_system reaction artifacts into flat channels.
Each source-cell propensity becomes one channel. Consequently, a collapsed axis is represented by distinct columns that share one destination row; summing simultaneous firings is then exactly the stoichiometric matrix multiplication performed by the core stochastic solvers. An offset axis moves each channel to its shifted coordinate; when that leaves the axis, the column only removes the donor.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
reactions
|
Sequence[ReactionArtifact]
|
Typed reaction artifacts, such as |
required |
template_shapes
|
Mapping[str, Sequence[int]]
|
Shape of each state template, in the flat state's
order, such as |
required |
axis_sizes
|
Mapping[str, int]
|
Number of coordinates on each axis. |
required |
params
|
Mapping[str, object]
|
Parameter values passed to every propensity. |
required |
n_state
|
int | None
|
Number of cells in the flat state. Defaults to the total
that |
None
|
reaction_names
|
Sequence[str] | None
|
Optional parent reaction names to select for a hybrid
jump partition. |
None
|
Returns:
| Type | Description |
|---|---|
CompiledReactionNetwork
|
Validated flat reaction network. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If an argument or artifact field has the wrong type. |
ValueError
|
If the artifacts are inconsistent with each other or with the state layout. |
Source code in src/op_engine/reactions.py
659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 | |
conserved_quantities(stoichiometry, *, tol=1e-10)
¶
Return the structural conservation laws of a reaction network.
Rows w satisfy w @ stoichiometry = 0, so w @ y is unchanged by
every reaction, whatever the rates. Totals conserved only because rates
balance (births mu * N against deaths) are not structural; use
:func:linear_invariants for those.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
stoichiometry
|
object
|
|
required |
tol
|
float
|
Relative singular-value threshold. |
1e-10
|
Returns:
| Type | Description |
|---|---|
ndarray
|
|
Examples:
>>> import numpy as np
>>> transfers = np.array([[-1.0], [1.0]])
>>> laws = conserved_quantities(transfers)
>>> np.allclose(laws @ transfers, 0.0)
True
>>> laws.shape
(1, 2)
Source code in src/op_engine/steady_state.py
609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 | |
diagnose_trajectory(trajectory, config=None)
¶
Check an output trajectory without modifying it or extracting host scalars.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
trajectory
|
Array
|
Array shaped |
required |
config
|
OutputStateCheckConfig | None
|
Component selectors and absolute tolerances. |
None
|
Returns:
| Type | Description |
|---|---|
OutputStateDiagnostics
|
Diagnostics for the complete supplied trajectory. |
OutputStateDiagnostics
|
these recorded outputs, not intermediate-step positivity or accuracy. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If config has the wrong type. |
ValueError
|
If the trajectory shape or selectors are invalid. |
Examples:
>>> import numpy as np
>>> path = np.array([[[1.0, 1.0]], [[0.9, -1.0]], [[0.81, 1.0]]])
>>> result = diagnose_trajectory(path)
>>> result.n_negative_outputs.tolist()
[0, 1]
>>> result.valid.tolist()
[True, False]
Source code in src/op_engine/state_diagnostics.py
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | |
encode_groups(group_ids, n_groups, *, prefer_sparse=None, dtype=np.float64)
¶
Encode group IDs into a one-hot group membership matrix.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_ids
|
NDArray[integer]
|
1D array of integer group IDs for each item. |
required |
n_groups
|
int
|
Total number of groups. |
required |
prefer_sparse
|
bool | None
|
If True, always return a sparse matrix; if False, always return a dense array; if None, autodispatch based on n_groups. |
None
|
dtype
|
DTypeLike
|
Data type for the output matrix. |
float64
|
Returns:
| Type | Description |
|---|---|
csr_matrix | DenseOperator
|
A (n_groups, n_items) one-hot encoded group membership matrix. |
Source code in src/op_engine/matrix_ops.py
1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 | |
from_compiled_replicates(compiled, params, *, batch_axis)
¶
Build a local network from compiler-certified independent reactions.
Requires the independent-reaction contract from op_system 0.8.0+. Every evolving state must carry the batch axis. Operators, gaps, explicit-time hazards and nonconstant linear tables are rejected. Time-varying parameters must explicitly carry the batch axis to represent asynchronous current values.
Returns:
| Type | Description |
|---|---|
ReplicateReactionNetwork
|
Local network for BatchedDirectSSASolver. |
Raises:
| Type | Description |
|---|---|
ValueError
|
Independence, completeness or time assumptions are unmet. |
TypeError
|
Required compiler artifacts are unavailable. |
Source code in src/op_engine/replicate_network.py
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | |
from_compiled_rhs(compiled, params, *, reaction_names=None, allow_gaps=False)
¶
Compile the reaction network of a compiled op_system RHS.
The flat state follows compiled.template_shapes: each template's
cells in C order, templates in declaration order. That is also the
layout of compiled.eval_fn's state vector when the RHS is
vectorized, so network.mean_drift(t, y) should equal
compiled.eval_fn(t, y, **params) for every y. Check that
identity once for a new model: a mismatch means some dynamics have no
reaction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
compiled
|
CompiledRhsLike
|
A compiled RHS, such as |
required |
params
|
Mapping[str, object]
|
Parameter values passed to every propensity. |
required |
reaction_names
|
Sequence[str] | None
|
Optional reaction names to compile, for a hybrid
jump partition. |
None
|
allow_gaps
|
bool
|
Compile even when |
False
|
Returns:
| Type | Description |
|---|---|
CompiledReactionNetwork
|
Validated flat reaction network. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the RHS has no vectorized state layout. |
ValueError
|
If the RHS has reaction gaps and neither |
Source code in src/op_engine/reactions.py
894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 | |
generate_adaptive_grid(profile, domain, n_points, *, epsilon=0.001, sampling_points=4097, smoothing_window=None, minimum_spacing=None)
¶
Generate a curvature-weighted grid from a vectorized profile callable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
profile
|
Callable[[NDArray[float64]], ArrayLike]
|
Callable evaluated on a one-dimensional NumPy sample grid. It must return one finite value per sample. |
required |
domain
|
tuple[float, float]
|
Finite increasing |
required |
n_points
|
int
|
Number of output points, including both domain endpoints. |
required |
epsilon
|
float
|
Positive curvature-density floor. |
0.001
|
sampling_points
|
int
|
Number of uniform samples used to estimate curvature.
This must be at least |
4097
|
smoothing_window
|
int | None
|
Optional odd moving-average width for curvature. |
None
|
minimum_spacing
|
float | None
|
Optional positive lower bound on output spacing. |
None
|
Returns:
| Type | Description |
|---|---|
NDArray[float64]
|
Strictly increasing curvature-weighted coordinates with shape |
NDArray[float64]
|
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ValueError
|
If the domain, sampled profile, or controls are invalid. |
Source code in src/op_engine/spatial_grid.py
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | |
generate_adaptive_grid_from_data(coordinates, values, n_points, *, epsilon=0.001, smoothing_window=None, minimum_spacing=None)
¶
Equidistribute points according to sampled profile curvature.
The curvature monitor is
abs(f'') / (1 + f'**2)**(3/2) + epsilon. Its trapezoidal cumulative
integral defines a monotone distribution whose evenly spaced quantiles
are inverted with linear interpolation. The result contains exactly
n_points coordinates, including both input endpoints.
This is an eager geometry-preprocessing utility: it always returns a NumPy array. The resulting static coordinates can be passed to numerical operators running in any supported Array-API namespace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
coordinates
|
ArrayLike
|
Strictly increasing one-dimensional sample coordinates. |
required |
values
|
ArrayLike
|
Finite profile values at |
required |
n_points
|
int
|
Number of output points, including both endpoints. |
required |
epsilon
|
float
|
Positive curvature-density floor. |
0.001
|
smoothing_window
|
int | None
|
Optional odd moving-average width applied to the sampled curvature before integration. |
None
|
minimum_spacing
|
float | None
|
Optional positive lower bound on adjacent output spacing. It must be feasible within the sampled domain. |
None
|
Returns:
| Type | Description |
|---|---|
NDArray[float64]
|
Strictly increasing curvature-weighted coordinates with shape |
NDArray[float64]
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If samples or controls are invalid. |
Source code in src/op_engine/spatial_grid.py
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | |
grouped_count_ids(group_ids, n_groups)
¶
Perform grouped count using group IDs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_ids
|
NDArray[integer]
|
1D array of integer group IDs. |
required |
n_groups
|
int
|
Total number of groups. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
A 1D array of length n_groups where each element contains the count of |
NDArray[floating]
|
occurrences of the corresponding group ID. |
Source code in src/op_engine/matrix_ops.py
1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 | |
grouped_sum_ids(values, group_ids, n_groups)
¶
Perform grouped sum over 1D values array using group IDs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
NDArray[floating]
|
1D array of values. |
required |
group_ids
|
NDArray[integer]
|
1D array of integer group IDs. |
required |
n_groups
|
int
|
Total number of groups. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
A 1D array of length n_groups where each element contains the sum of values |
NDArray[floating]
|
for the corresponding group ID. |
Source code in src/op_engine/matrix_ops.py
1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 | |
grouped_sum_ids_2d(values, group_ids, n_groups)
¶
Perform grouped sum over 2D values array using group IDs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
NDArray[floating]
|
2D (N, K) array where N is num of items and K is num of features. |
required |
group_ids
|
NDArray[integer]
|
1D array of integer group IDs of length N. |
required |
n_groups
|
int
|
Total number of groups. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
A 2D array of shape (n_groups, K) where each row contains the sum of values |
NDArray[floating]
|
for the corresponding group ID. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If values is not 2D or if group_ids length does not match the number of items in values. |
Source code in src/op_engine/matrix_ops.py
1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 | |
implicit_solve(left_op, right_op, x)
¶
Perform an implicit solve with dense fallback and cached sparse dispatch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left_op
|
object
|
Left operator L in the equation L @ y = R @ x. |
required |
right_op
|
object
|
Right operator R in the equation L @ y = R @ x. |
required |
x
|
Array
|
1D or 2D array representing the input vector(s). |
required |
Returns:
| Type | Description |
|---|---|
Array
|
A 1D or 2D array containing the solution vector(s) y. |
Source code in src/op_engine/matrix_ops.py
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 | |
kron_prod(a, b)
¶
Compute the Kronecker product of two operators.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
a
|
Operator
|
First operator. |
required |
b
|
Operator
|
Second operator. |
required |
Returns:
| Type | Description |
|---|---|
Operator
|
The Kronecker product operator. |
Source code in src/op_engine/matrix_ops.py
986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 | |
kron_sum(ops)
¶
Compute a Kronecker sum of square operators.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ops
|
list[Operator]
|
List of 2D square operators. |
required |
Returns:
| Type | Description |
|---|---|
Operator
|
The Kronecker sum operator. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If ops is empty or if operators are not square or have incompatible shapes. |
Source code in src/op_engine/matrix_ops.py
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 | |
linear_invariants(rhs, states, *, t=0.0, jacobian=None, fixed=None, tol=1e-06)
¶
Find totals w @ y that the dynamics conserve at sampled states.
A row w is returned when w @ J(y) = 0 and w @ rhs(t, y) = 0 at
every sampled y, which includes rate-balanced totals that
:func:conserved_quantities misses. Sample a few varied states away from
special points such as the disease-free state.
The test is numerical. A mode decaying more slowly than tol times the
fastest rate looks conserved, and each row's accuracy is limited by the
Jacobian's error relative to the slowest real rate: a slow mode tilts the
rows toward itself. The default Jacobian uses central differences for
that reason; an exact one (jax.jacfwd, for example) is better still.
When you know an invariant, such as a row of ones over the living
compartments, pass that exact row to :func:steady_state and use this
function to confirm that nothing else is conserved.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rhs
|
SteadyStateRhs
|
|
required |
states
|
Sequence[Array]
|
Sample states, each a one-dimensional array. |
required |
t
|
float
|
Evaluation time. |
0.0
|
jacobian
|
SteadyStateJacobian | None
|
Dense Jacobian callback; central differences by default. |
None
|
fixed
|
Sequence[int] | Array | None
|
Indices, or a boolean mask, of states that
:func: |
None
|
tol
|
float
|
Singular-value threshold relative to the fastest rate. |
1e-06
|
Returns:
| Type | Description |
|---|---|
ndarray
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/op_engine/steady_state.py
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 | |
local_stability(rhs, candidate, *, config, t=0.0, coordinates=None, coordinate_system='supplied state', fixed=None, invariants=None, nonnegative=False, derivatives=None, parameters=None, jacobian=None, jacobian_reference=None, time_unit=None)
¶
Assess a candidate equilibrium through an eager NumPy linearization.
The classification applies only to an interior, residual-qualified point and, when constraints are declared, only to their tangent manifold. A boundary status deliberately suppresses an interior stability conclusion.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rhs
|
StabilityRhs
|
Dense NumPy right-hand side in the supplied coordinates. |
required |
candidate
|
NumpyArray | SteadyStateResult
|
NumPy state or NumPy-backed steady-state result. |
required |
config
|
LocalStabilityConfig
|
Explicit residual, spectral, boundary and difference controls. |
required |
t
|
float
|
Frozen evaluation time. A time-dependent RHS is only diagnosed there. |
0.0
|
coordinates
|
Sequence[str] | None
|
Ordered state labels. An op_system artifact supplies these. |
None
|
coordinate_system
|
str
|
Human-readable coordinate-system declaration. |
'supplied state'
|
fixed
|
Sequence[int] | NumpyArray | None
|
Coordinates held fixed, as indices or a boolean mask. |
None
|
invariants
|
ArrayLike | None
|
Declared invariant rows in the supplied coordinates. |
None
|
nonnegative
|
bool | Sequence[bool] | NumpyArray
|
Coordinates with a one-sided non-negative domain. |
False
|
derivatives
|
SymbolicDerivativeArtifact | None
|
Optional op_system symbolic derivative artifact. |
None
|
parameters
|
Mapping[str, object] | None
|
Exact runtime bindings for |
None
|
jacobian
|
StabilityJacobian | None
|
Optional dense full-state Jacobian callback. |
None
|
jacobian_reference
|
str | None
|
Required provenance label for |
None
|
time_unit
|
str | None
|
Unit attached to any reported e-folding timescale. |
None
|
Returns:
| Type | Description |
|---|---|
LocalStabilityResult
|
Partial or complete numerical evidence with an explicit status. |
Raises:
| Type | Description |
|---|---|
TypeError
|
The state, solver flag or configuration is not eager NumPy. |
ValueError
|
Input declarations, shapes, dtypes or controls conflict. |
Source code in src/op_engine/equilibrium_stability.py
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 | |
matrix_grouped_count(group_matrix)
¶
Perform grouped count using a group matrix.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_matrix
|
csr_matrix | DenseOperator
|
2D group matrix (csr_matrix or dense ndarray). |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
A 1D array containing the counts for each group. |
Source code in src/op_engine/matrix_ops.py
1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 | |
matrix_grouped_sum(group_matrix, values)
¶
Perform grouped sum using a group matrix.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_matrix
|
csr_matrix | DenseOperator
|
2D group matrix (csr_matrix or dense ndarray). |
required |
values
|
NDArray[floating]
|
1D array of values to be summed. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
A 1D array containing the grouped sums. |
Source code in src/op_engine/matrix_ops.py
1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 | |
matrix_masked_sum(mask_matrix, data)
¶
Perform masked sum using a mask matrix and data array.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mask_matrix
|
csr_matrix | DenseOperator
|
2D mask matrix (csr_matrix or dense ndarray). |
required |
data
|
NDArray[floating]
|
1D or 2D data array to be masked and summed. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
A 1D or 2D array containing the masked sums. |
Source code in src/op_engine/matrix_ops.py
1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 | |
observation_from_compiled(observable)
¶
Adapt a compiled observable structurally, without a runtime compiler dependency.
The input trajectory must retain the compiler's flattened state order. The adapter reshapes each state to a vector and delegates all spatial reductions and coordinate selection to the compiler, applying no additional weights.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
observable
|
CompiledObservableLike
|
Artifact exposing op_system's compiled-observable surface. |
required |
Returns:
| Type | Description |
|---|---|
ObservationSpec
|
Native evaluator and detached scientific metadata. |
Source code in src/op_engine/observations.py
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | |
observe_model(core, observations, *, params=None)
¶
Evaluate a completed ModelCore's stored history using its output grid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
core
|
ModelCore
|
Completed state manager configured to store its full trajectory. |
required |
observations
|
Sequence[ObservationSpec]
|
Named evaluators and their output metadata. |
required |
params
|
Mapping[str, object] | None
|
Optional observation parameters. |
None
|
Returns:
| Type | Description |
|---|---|
ObservationResult
|
Native named series at the model's stored output times. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If history is unavailable or the model has not completed. |
Source code in src/op_engine/observations.py
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | |
observe_solution(times, trajectory, observations, *, params=None)
¶
Evaluate native named outputs at every supplied stored output time.
Time is a static, finite, strictly increasing host grid. Each callback must return an array in the trajectory namespace and dtype with its declared shape. Native values are stacked without conversion or gradient detachment. Inputs and returned arrays should be treated as immutable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
times
|
Sequence[float] | ndarray
|
Stored output times, independent of internal solver step times. |
required |
trajectory
|
Array
|
Native state history with a leading output-time dimension. |
required |
observations
|
Sequence[ObservationSpec]
|
Unique named evaluators with static output metadata. |
required |
params
|
Mapping[str, object] | None
|
Parameters passed to each evaluator, including observation-only ones. |
None
|
Returns:
| Type | Description |
|---|---|
ObservationResult
|
Native series and evaluation coverage. No interpolation/error estimate. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If grids, trajectory shape, metadata or output shapes disagree. |
TypeError
|
If states/outputs violate the real floating native-array contract. |
Source code in src/op_engine/observations.py
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | |
reduce_observations(samples, observations, *, params=None)
¶
Reduce a finite native sample stream in one pass without storing a trajectory.
Samples define the exact window endpoints. Native initial/final values, changes and composite-trapezoid integrals preserve evaluator shapes and gradients. A single sample has zero duration, change and integral. Callback outputs are snapshotted so a producer may reuse its numerical state buffer.
The reducer retains a constant number of output arrays and one current state reference. Producer storage and reverse-mode computation graphs are separate: no constant-memory gradient guarantee is implied. There is no persistent checkpoint or partial-result recovery; an interrupted call must restart from a producer-owned replay/checkpoint. Callbacks must be pure.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
samples
|
Iterable[tuple[float, Array]]
|
Finite, nonempty iterable of static times and native states. Times must increase strictly; state shape, namespace and real floating dtype stay fixed. Only the supplied times define quadrature samples. |
required |
observations
|
Sequence[ObservationSpec]
|
Unique named evaluators and scientific output metadata. |
required |
params
|
Mapping[str, object] | None
|
Observation parameters passed to every callback. |
None
|
Returns:
| Type | Description |
|---|---|
ObservationSummary
|
Bounded-size native reductions with window, sample count and diagnostics. |
ObservationSummary
|
Integrals inherit trajectory and sampled-quadrature error; no dense-output |
ObservationSummary
|
order, event reconstruction or separate error estimate is asserted. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the stream is empty, intervals are invalid or shapes change. |
TypeError
|
If states or outputs violate the native namespace/dtype contract. |
Source code in src/op_engine/observation_reductions.py
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | |
register_sparse_adapter(adapter, *, replace=False)
¶
Register an operator adapter in the existing sparse dispatch registry.
Replacement clears that ecosystem's cached factors. Predicates must be pure; overlapping pair matches are rejected when dispatching a solve.
Raises:
| Type | Description |
|---|---|
ValueError
|
If an identifier already exists without explicit replacement. |
Source code in src/op_engine/matrix_ops.py
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 | |
require_converged(result)
¶
Return a converged result or raise at an eager host boundary.
This function intentionally converts the scalar convergence array to a
Python boolean. Do not call it from jax.jit or another traced region;
compiled integrations must return diagnostics and validate them afterward.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
result
|
NonlinearSolveResult
|
Result to validate. |
required |
Returns:
| Type | Description |
|---|---|
NonlinearSolveResult
|
The unchanged converged result. |
Raises:
| Type | Description |
|---|---|
NonlinearConvergenceError
|
If the result did not converge. |
Source code in src/op_engine/nonlinear_solver.py
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 | |
require_linear_converged(result)
¶
Return a successful eager solution or raise with per-column diagnostics.
Raises:
| Type | Description |
|---|---|
LinearSolveError
|
If any RHS column failed the checked solve. |
Source code in src/op_engine/linear_operator.py
343 344 345 346 347 348 349 350 351 | |
require_steady_state(result)
¶
Return a converged result or raise.
This converts the convergence flag to a Python boolean; do not call it
inside jax.jit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
result
|
SteadyStateResult
|
Result to check. |
required |
Returns:
| Type | Description |
|---|---|
SteadyStateResult
|
|
Raises:
| Type | Description |
|---|---|
SteadyStateConvergenceError
|
If the solve did not converge. |
Source code in src/op_engine/steady_state.py
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | |
scipy_banded_adapter(*, ecosystem_id='scipy-banded', options=None)
¶
Build an explicitly registered, uncached eager banded direct adapter.
Returns:
| Type | Description |
|---|---|
SparseAdapter
|
Existing-registry adapter recognizing a BandedOperator left operand. |
Source code in src/op_engine/scipy_operator.py
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
scipy_gmres_adapter(*, ecosystem_id='scipy-gmres', restart=20, options=None, preconditioner=None, context=None)
¶
Build an explicit eager matrix-free adapter in the existing registry.
Returns:
| Type | Description |
|---|---|
SparseAdapter
|
Adapter for ActionOperator left operands, with left inverse preconditioning. |
Source code in src/op_engine/scipy_operator.py
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 | |
sink_states(rhs, states, *, t=0.0, jacobian=None, tol=1e-09)
¶
Return a mask of states no derivative depends on.
Cumulative counters and absorbing compartments that feed nothing back have
a zero Jacobian column. They never reach a zero derivative while their
inflow is positive, so hold them fixed in :func:steady_state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rhs
|
SteadyStateRhs
|
|
required |
states
|
Sequence[Array]
|
Sample states. |
required |
t
|
float
|
Evaluation time. |
0.0
|
jacobian
|
SteadyStateJacobian | None
|
Dense Jacobian callback; central differences by default. |
None
|
tol
|
float
|
Largest column entry, relative to the largest Jacobian entry, still treated as zero. |
1e-09
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Boolean |
Source code in src/op_engine/steady_state.py
701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 | |
smooth(x, alpha=0.02, out=None)
¶
Apply simple smoothing along the last axis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
NDArray[floating]
|
Input array to smooth. |
required |
alpha
|
float
|
Smoothing factor between 0 and 1. |
0.02
|
out
|
NDArray[floating] | None
|
Optional output array to store the result. |
None
|
Returns:
| Type | Description |
|---|---|
NDArray[floating]
|
Smoothed array with the same shape as x. |
Source code in src/op_engine/matrix_ops.py
1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 | |
solve_linear(request, solver)
¶
Call an eager solver and verify every original, unpreconditioned residual.
Returns:
| Type | Description |
|---|---|
LinearSolveResult
|
Candidate solution and per-column diagnostics, including failures. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If namespace, dtype or callback metadata is invalid. |
ValueError
|
If operator/RHS/result dimensions or iteration counts disagree. |
Source code in src/op_engine/linear_operator.py
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | |
solve_sensitivities(system, parameters, initial, time_grid, *, options=None)
¶
Integrate S' = (df/dy) S + df/dtheta with existing explicit kernels.
The compiler is optional: any correctly ordered derivative artifact can satisfy the protocol. Callbacks/mesh are static under JIT; native scalar bindings and both initial arrays retain their graphs. Batch independent systems through native vmap. Forcing jumps, events, history dependence, stochastic paths and operator solvers need separately qualified methods.
Returns:
| Type | Description |
|---|---|
SensitivitySolution
|
Native retained outputs and measured sensitivities in physical coordinates. |
Raises:
| Type | Description |
|---|---|
ValueError
|
Layout, mesh or declared storage limits disagree. |
Source code in src/op_engine/sensitivities.py
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 | |
unregister_sparse_adapter(ecosystem_id)
¶
Remove an adapter and release all of its cached factors.
Raises:
| Type | Description |
|---|---|
KeyError
|
If the adapter is not registered. |
Source code in src/op_engine/matrix_ops.py
1091 1092 1093 1094 1095 1096 1097 1098 | |