Automatic high-precision surrogate modeling for parameterized ODE systems.
Project description
AdaSurroG
AdaSurroG trains fast, differentiable surrogate models for parameterized ordinary differential equation systems. It is designed for repeated-query scientific workflows such as parameter studies, uncertainty quantification, optimization, and systems-biology simulation.
The default high-precision pipeline uses a fixed high-fidelity dataset and combines:
- automatic state transforms for multiscale variables;
- adaptive fixed output-time selection from pilot trajectories;
- proper orthogonal decomposition (POD) trajectory compression;
- a Chebyshev polynomial coefficient backbone;
- a residual PyTorch network;
- time/accuracy-bounded AdamW training;
- deterministic CPU float64 full-batch L-BFGS refinement;
- resumable atomic checkpoints and explicit accuracy diagnostics.
AdaSurroG trains one surrogate per mechanistic ODE model. The pipeline is generic: users provide the ODE definition, parameter bounds, initial conditions, and time interval rather than manually designing a new neural architecture for each model.
Installation
Install the universal ODE pipeline:
python -m pip install "adasurrog[universal]"
Install plotting utilities and all runtime extras:
python -m pip install "adasurrog[all]"
For development from a source checkout:
python -m pip install -e ".[dev]"
Python 3.10–3.13 is supported. PyTorch is a required dependency. SciPy is required for generating ODE reference trajectories, and PyYAML is required for YAML-based training configurations.
Quick start: built-in benchmark
List the included benchmark models:
adasurrog-benchmark --list
Train a surrogate for the SEIR benchmark:
adasurrog-benchmark \
--problem seir \
--train 192 \
--validation 48 \
--test 48 \
--target-rmse 0.002 \
--training-seconds 900 \
--lbfgs-seconds 300
The pipeline writes its dataset, checkpoints, pilot diagnostics, and final certification report under the selected run directory.
YAML training
problem:
factory: benchmark:seir
sampling:
pilot_trajectories: 24
train_trajectories: 192
validation_trajectories: 48
test_trajectories: 48
time_points: 128
seed: 17
accuracy:
target_rmse: 0.002
target_p99: 0.01
pod_floor_fraction: 0.30
budget:
training_seconds: 900
lbfgs_seconds: 300
surrogate:
weighted_pod: auto
rank_candidates: [4, 8, 12, 16, 24, 32, 48, 64]
polynomial_degrees: [1, 2, 3, 4]
runtime:
run_directory: runs/universal_seir
device: mps
lbfgs_device: cpu
resume: auto
Run it with:
adasurrog-train examples/universal/seir.yaml
On Apple Silicon, AdamW may run on MPS while float64 L-BFGS runs on CPU.
Define a custom ODE problem
import numpy as np
from adasurrog import ODEProblem
def create_problem() -> ODEProblem:
def rhs(time, state, parameters):
del time
production, degradation = parameters
return np.array([production - degradation * state[0]])
def jacobian_state(time, state, parameters):
del time, state
return np.array([[-parameters[1]]])
return ODEProblem(
name="production_degradation",
state_names=("concentration",),
parameter_names=("production", "degradation"),
parameter_lower=np.array([0.1, 0.05]),
parameter_upper=np.array([10.0, 2.0]),
time_span=(0.0, 20.0),
rhs_function=rhs,
initial_condition_function=lambda parameters: np.array([0.0]),
jacobian_state_function=jacobian_state,
)
Reference the factory from YAML:
problem:
factory: my_models.production_degradation:create_problem
Parameters currently require strictly positive lower bounds because the default pipeline uses a normalized log-parameter box.
Python API
from pathlib import Path
from adasurrog import (
AccuracyConfig,
AutoPipelineConfig,
BudgetConfig,
SamplingConfig,
UniversalODEPipeline,
)
from my_models.production_degradation import create_problem
config = AutoPipelineConfig(
sampling=SamplingConfig(
pilot_trajectories=16,
train_trajectories=128,
validation_trajectories=32,
test_trajectories=32,
time_points=96,
),
accuracy=AccuracyConfig(target_rmse=1e-3),
budget=BudgetConfig(training_seconds=600, lbfgs_seconds=180),
run_directory=Path("runs/production_degradation"),
)
surrogate, report = UniversalODEPipeline(create_problem(), config).fit()
print(report.status, report.validation_rmse, report.test_rmse)
Load and query a trained surrogate
import numpy as np
from adasurrog import AdaSurrogate
surrogate = AdaSurrogate.load(
"runs/production_degradation/checkpoints/universal_best.pt",
device="cpu",
)
trajectory = surrogate.predict(
parameters=np.array([2.0, 0.4]),
)
selected_times = surrogate.predict(
parameters=np.array([2.0, 0.4]),
time=np.linspace(0.0, 20.0, 50),
)
check = surrogate.check_domain(np.array([2.0, 0.4]))
print(check.inside)
Physical query times are accepted directly. A checkpoint contains the POD representation, coefficient model, state transforms, parameter domain, time grid, and training report; the original training dataset is not required for inference.
Stopping and checkpoint behavior
Training is controlled by a validation target and a cumulative wall-clock budget instead of a fixed epoch count. Checkpoints preserve model, optimizer, scheduler, AMP scaler, training state, and random-number-generator state.
Typical outputs include:
runs/<problem>/
├── data/fixed_dataset.npz
├── pilot_diagnostics.json
├── universal_diagnostics.json
└── checkpoints/
├── best.pt
├── latest.pt
├── lbfgs_best.pt
├── lbfgs_latest.pt
└── universal_best.pt
Use resume: auto to continue from the most recent compatible checkpoint.
Inspect a checkpoint:
adasurrog checkpoint-info runs/my_model/checkpoints/universal_best.pt
Inspect the installed environment:
adasurrog info
Accuracy diagnostics
The final report classifies a run as one of:
certified;representation_limited;regression_limited;data_limited;optimization_limited;tail_error_limited.
The report includes the validation and test errors, POD representation floor, selected POD rank, selected polynomial model, and regression amplification over the POD floor. A failure to reach a target is therefore reported diagnostically rather than hidden behind a final loss value.
Included benchmark models
- Robertson kinetics: severe stiffness, conservation, and scale separation;
- Lotka–Volterra: nonlinear oscillation and phase sensitivity;
- Brusselator: limit-cycle dynamics and nearby bifurcation behavior;
- SEIR: nonnegative compartment dynamics, conservation, and a transient peak.
Legacy and experimental commands
The distribution retains the gene-feedback examples and the earlier pool-based active-learning
prototype for reproducibility. The recommended production path is adasurrog-train or the
UniversalODEPipeline; active learning is not part of the default automatic pipeline.
Current scope
Version 0.5.1 supports continuous parameterized ODE initial-value problems with strictly positive parameter bounds and fixed simulation horizons. Global unweighted or metric-weighted POD is used for trajectory representation. Event resets, discontinuous controls, automatic state/time-blocked POD, nonlinear latent representations, and derivative-supervised training are not yet automatic.
Reproducibility and citation
See CITATION.cff for citation metadata. Release history is recorded in CHANGELOG.md.
License
AdaSurroG is distributed under the MIT License.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file adasurrog-0.5.1.tar.gz.
File metadata
- Download URL: adasurrog-0.5.1.tar.gz
- Upload date:
- Size: 68.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2b88ef5ba5e3e96270807dfa56881398b378bcabe0260f72dde65bd3427bce3
|
|
| MD5 |
e668039b6bb9ede952976c8782791705
|
|
| BLAKE2b-256 |
7a3480662df4d53499740b0def6f8098212eadd327ae5de40f30d6f614da86c5
|
File details
Details for the file adasurrog-0.5.1-py3-none-any.whl.
File metadata
- Download URL: adasurrog-0.5.1-py3-none-any.whl
- Upload date:
- Size: 75.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bbc22989ac3d734473d03224a9274a332f02733fa8bcf3fe8c389df053f69bf9
|
|
| MD5 |
ac24fdbaabb41e305ea66f0de6ded4d9
|
|
| BLAKE2b-256 |
6a35ef51b43a03702732334ad9c98610e72f14fd04ad59ef79aad766e3e45aaa
|