Repository navigation
Mass-action reaction-network datasets under
koopman_graph.datasets.reaction, with exact oracle references
(equilibria, conservation laws, Jacobian spectra and timescales) for
checking whether a learned latent operator recovers kinetic timescales
and respects conservation. ReactionNetworkBenchmark is the only new
name in koopman_graph.datasets; the root __all__, homogeneous
scientific defaults, and the linear latent operator contract are
unchanged (koopman=None still selects "pernode"). SciPy and Cantera
stay optional behind the new [reaction] / [cantera] extras.
FORMAT_VERSION stays 1.
Added
-
koopman_graph.datasets.reactionsubpackage (pure PyTorch unless an
optional extra is used) with the modules below and packaged FAIR cards
underreaction/data/. Its names are exported from the subpackage;
onlyReactionNetworkBenchmarkis added tokoopman_graph.datasets,
and the root__all__is unchanged. -
koopman_graph.datasets.reaction.system: frozenReactionSystem
(reactant / product stoichiometry, mass-action rates and right-hand side,
stoichiometric matrix, linearity check, optional element matrix and
per-reactionArrheniusParams,at_temperature, dict round trip) and
check_element_balance, which reports per-reaction element residuals
(open-system source / sink reactions show up as unbalanced). Stored
tensors are owned copies but not write-protected; treat them as
read-only. -
koopman_graph.datasets.reaction.transform:LogConcentrationTransform
(flooredlog c, its inverse, a below-floor mask, and a serializable
record of the floor) andelement_balance_violationfor element-total
drift from a reference state. -
koopman_graph.datasets.reaction.graphs:species_influence_graph
(directed species graph matching the mass-action Jacobian's sparsity,
weighted by linking-reaction count),reaction_hyperedge_index(one
hyperedge per reaction),reaction_directed_hyperedges(reactant tail /
product head incidences), andspecies_reaction_bipartite(PyG
HeteroDatawith stoichiometric edge weights). -
koopman_graph.datasets.reaction.integrate: exact augmented
matrix-exponential propagation for linear systems (integrate_expm,
linear_rate_equations), batched and differentiable torch RK4
(integrate_rk4), SciPy BDF / Radau / LSODA with an exact mass-action
Jacobian behind a lazyrequire_scipy()guard (integrate_stiff;
[reaction]extra), theintegrate_reaction_systemdispatcher
(method="auto"), andmass_action_jacobian. -
koopman_graph.datasets.reaction.catalog: reference systems with frozen
default parameters (first_order_chain,reversible_dimerization,
michaelis_menten,brusselator,lotka_volterra). Closed systems carry
an element matrix. -
koopman_graph.datasets.reaction.oracles:conservation_laws(orthonormal
left nullspace ofN),stoichiometric_rank,equilibrium(exact for
linear systems, damped non-negative Newton within the compatibility
class otherwise), andoracle_spectrum/oracle_timescales/
OracleSpectrum. These give the Jacobian, dynamic eigenvalues with the
conservation zero modes removed, timescales-1/Re(λ), and flow-map
eigenvaluesexp(λ Δt)to compare with a learned discrete operator. -
koopman_graph.datasets.reaction.random_network:sample_random_network
builds seeded, element-balanced mass-action networks. Species
compositions are sampled first, so every candidate reaction conserves
elements; reaction order is capped at 2 (max_order=1gives linear
dissociation networks); rates are log-uniform. The returned
SampledReactionNetworkrecords the seed and every sampler parameter. -
koopman_graph.datasets.reaction.cstr:van_de_vusse_cstr/
VanDeVusseCSTR, a Van de Vusse CSTR with Klatt & Engell (1998)
Arrhenius kinetics. Reactor temperature and dilution rate are inputs,
either constant or piecewise-constant schedules. It provides the
controlled right-hand side, RK4 simulation, and a Newton steady state; the
nominal point (114.2 °C,F/V = 14.19 1/h) givesc_A ≈ 2.14,
c_B ≈ 1.09. -
koopman_graph.datasets.reaction.gillespie: seeded Gillespie direct-method
SSA (gillespie_ssa,SSATrajectory) with mass-action propensities
(falling factorials, volume scaling) that match the ODE rates, plus
last-value-hold binning onto a grid (bin_to_grid). -
koopman_graph.datasets.reaction.cantera_io(lazy[cantera]boundary):load_cantera_mechanismconverts a Cantera gas mechanism (default the
bundledh2o2.yaml, read from the installed package) to a mass-action
ReactionSystemat a reference(T, P, X). Reversible reactions are
split into forward and reverse. Elementary and mass-action three-body
reactions convert exactly:[M]is expanded into one reaction per
collider with ratek ε_s.- Falloff and other state-dependent rates are frozen at the reference
state, skipped, or rejected (state_dependent=); frozen rates with a
mass-action third body keep the per-collider[M]expansion.
Reactions with non-mass-actionordersare skipped or rejected
(orders equal to the stoichiometry convert normally). Rate constants
are read with Cantera's legacy rate-constant mode off, whatever the
process setting. Duplicate reactions get unique names. Every frozen or
skipped reaction is listed inCanteraProvenance, which also records
the Cantera version, mechanism path and SHA-256, the reference state,
the "illustration only" caveat, and the Cantera citation DOI. simulate_cantera_reactorruns constant-pressure or constant-volume
ideal-gas reactors, adiabatic or isothermal.- Also:
require_cantera,resolve_mechanism_path(bare names prefer
Cantera's bundled data over the working directory), and
mechanism_sha256.
-
[reaction]extra (scipy>=1.11.0) for stiff reaction-network solvers
and[cantera]extra (cantera>=3.2,<3.3) for Cantera mechanisms. -
canterapytest marker; marked tests are skipped automatically when the
[cantera]extra is not installed. -
CI test jobs and the release verify job install
[reaction]and
[cantera], socantera-marked tests run there. -
tests/test_import_hygiene.py:import koopman_graphmust not load
SciPy, Cantera, or torchdiffeq. -
ReactionNetworkBenchmark(exported fromkoopman_graph.datasetsand
koopman_graph.datasets.reaction): card-defined, seeded reaction-network
datasets.- Six packaged FAIR JSON cards under
reaction/data/:
reaction_chain_v1,reaction_michaelis_menten_v1,
reaction_brusselator_v1,reaction_random_network_v1,
reaction_van_de_vusse_v1(piecewise-constant temperature /
dilution-rate controls), andreaction_cantera_h2o2_v1([cantera]).
Each card records the generator, simulator, time grid, seed,
initial-condition ranges, log floor, graph encoding, oracle references
(equilibrium, dynamic eigenvalues, timescales, conservation laws),
units, license, limitations, and Cantera provenance. generatereturns aReactionDataset(rawfloat64concentrations,
optional controls, per-trajectoryGraphSnapshotSequencewith species
nodes,timestamps, and globalcontrol_inputs), with an optional
Gillespiesimulator="ssa". Also: deterministic trajectorysplit, and
versionedsave/loadpayloads (weights_onlyloading).compute_card_oracleandscripts/build_reaction_cards.py(with
--check) regenerate the oracle sections; tests recompute them to catch
drift.
- Six packaged FAIR JSON cards under
-
Example
55_reaction_network_oracles.ipynbcompares estimators against the
ReactionNetworkBenchmarkoracles:- exact DMD recovers the chain's
exp(λ Δt)(errors ~1e-7) and conserves
mass in rollouts; - DMD on the card's log features misses by up to ~0.13;
- a short
koopman="graph"fit is approximate, and
element_balance_violationflags its rollout drift; - a late-window DMD recovers the Michaelis-Menten slow mode against each
trajectory's own equilibrium linearization.
Registered in the PR notebook smoke set and the full
27-55shard. - exact DMD recovers the chain's
-
ReactionDataset.sequence(..., graph_encoding=)overrides the card's
encoding (e.g. drophyperedge_indexforDMDBaseline). -
eigenvalue_timescales:-1/Re(λ)with numerical zeros mapped toinf
(an optional absolutezero_tolerance, else eigensolver round-off
100 · eps · max|λ|);OracleSpectrum.timescalesuses it with its own
zero_tolerance.ReactionNetworkBenchmark.generaterefuses a Cantera
card whose recorded mechanism SHA-256 differs from the installed file.
Changed
STGODEBaselinenow importstorchdiffeqon first fit / predict instead
of at module import, soimport koopman_graphwith[baselines-ode]
installed no longer loads SciPy. A missingtorchdiffeqis no longer
cached: installing the extra mid-session takes effect on the next call.uv.lockrelocked; it was missing extras already declared in
pyproject.toml(export,control-lmi, ...).
Fixed
-
conservation_lawsreturns a canonical basis (Gram-Schmidt in species
order on the basis-independent projector) instead of whatever an SVD
returns. With two or more conservation laws the SVD basis differed
between LAPACK builds, so the Michaelis-Menten, random-network, and
Cantera cards did not reproduce on Linux CI. Card oracle values change
only at rounding level (<= 3e-14) apart from the rotated laws. -
equilibriumno longer returns a clamped Newton stall that is not
stationary. It now requires|dc_s/dt| <= 1e-6 · gross turnover_s + 1e-12 · (peak initial turnover)and otherwise raisesRuntimeError.
Previously the converted Canterah2o2system could report a
near-boundary point with one-way flux as its equilibrium.