Journey 06 — Limits
When SolvSRK is the right tool, how it compares to SciPy RK45 on stiff problems, linear Talbot routing via profile tokens, and survived=False refusals.
Prerequisites: Journey 05 complete. Scenario: What SolvSRK is for — and what it will not do for you
Key APIs
solvsrk.run_profile()solvsrk.profile_to_config()result['survived']result['failure_mode']
Concepts to internalize
- vs RK45 — explicit methods on Robertson use far more RHS evals or fail outright.
- Linear routing — SolvScout may encode profile mode 1 (Talbot) inside the token for constant affine systems.
- One IVP per call — parameter studies belong in your orchestration layer (or SolvJump for ground studies).
- Refuse rather than lie — blowup returns survived=False, not a plausible wrong number.
Important code
The guided tour script wraps this pattern. Copy the production shape into your pipeline:
# One IVP per call — orchestrate sweeps yourself:
for params in grid:
result = solvsrk.run(cfg, ndim, t0, t_end, y0, make_rhs(params))
# Blow-up refusal (branch on failure_mode):
blow = solvsrk.run(cfg, 1, 0, 10, (1,), lambda t,y: y*y)
assert not blow['survived'] and blow['failure_mode'] == 'blowup'Act-by-act walkthrough
Act 1 — What SolvSRK is for
One stiff, possibly nonlinear, initial-value ODE integrated forward in time to a final state — reactors, kinetics, thermal transients, control plants. You give it rhs(t, y); it gives you y(t_end) with a receipt.
Act 2 — Robertson vs explicit RK45
Same stiff Robertson problem, same rtol/atol on both sides. SciPy's RK45 is excellent on non-stiff problems; here we compare finished_ok, wall time, RHS evaluations, and y_final — apples to apples. Install SciPy with pip install solvsrk[scipy] if you want the comparison locally.
- rtol=1e-08, atol=1e-12
SolvSRK (SolvScout tuned (solvsrk, high))
| Field | Value | Notes |
|---|---|---|
finished_ok | True | |
failure_mode | ok | |
wall_s | 0.002527 | |
nfev | 795 | |
y_final | [0.715827, 9.18553e-06, 0.284164] |
SciPy RK45
| Field | Value | Notes |
|---|---|---|
finished_ok | True | |
failure_mode | ok | |
wall_s | 1.34 | |
nfev | 238148 | |
y_final | [0.715827, 9.18553e-06, 0.284164] | RK45 used 300× more RHS evaluations (238,148 vs 795) and 530× more wall time (1.34s vs 0.002527s) to reach the same endpoint. |
Act 3 — Linear systems ride the same token path
Constant affine IVPs (y' = A y + b with fixed A) are not a separate product limit. SolvScout compares mode 0 (time stepping) vs mode 1 (Talbot contour) and encodes the winner in the profile token. run_profile(token, ...) dispatches mode 1 to the bundled Talbot solver inside libsolvsrk — same wheel, same SolvSRK seat. The standalone solvlrde package is only for when you already hold the matrix A and want solvlrde.solve(A, y0, T) without an rhs callback.
| Field | Value | Notes |
|---|---|---|
solvscout_solver | solvsrk | |
profile_mode | 0 | |
confidence | high |
Linear IVP via run_profile — time stepping (mode 0)
| Field | Value | Notes |
|---|---|---|
finished_ok | True | |
failure_mode | ok | |
wall_s | 0.001704 | |
nfev | 795 | |
y_final | [-4.97331e-29, 0.368248] |
Act 4 — Limit 1 - one IVP per call
SolvSRK integrates ONE problem per run() call. Parameter studies, Monte Carlo sweeps, and design-of-experiments loops belong in your orchestration layer — call run() in a for-loop (or your job scheduler) and aggregate the receipts yourself.
Act 5 — Limit 2 - it will refuse rather than lie
Ask for something impossible — here, integrate a system that blows up — and SolvSRK returns survived=False with a failure_mode string instead of a plausible-looking wrong number. A refusal you can branch on beats a silent bad answer every time.
| Field | Value | Notes |
|---|---|---|
survived | False | |
failure_mode | blowup | |
t_reached | 1.03 | |
failure_msg | ek blowup |
Act 6 — The stack
SolvScout classifies your rhs and emits one profile token. SolvSRK run_profile integrates it — mode 0 for stiff nonlinear stepping, mode 1 for bundled Talbot on constant affine linear plants. Use the standalone solvlrde package only when you already have matrix A and want a direct solve API.
Guided tour output
Verified console capture from 06_limits.py:
What SolvSRK is for — and what it will not do for you
-- Act 1 - What SolvSRK is for --
-> One stiff, possibly nonlinear, initial-value ODE integrated forward in time to a final state — reactors, kinetics, thermal transients, control plants. You give it rhs(t, y); it gives you y(t_end) with a receipt.
-- Act 2 - Robertson vs explicit RK45 --
-> Same stiff Robertson problem, same rtol/atol on both sides. SciPy's RK45 is excellent on non-stiff problems; here we compare finished_ok, wall time, RHS evaluations, and y_final — apples to apples. Install SciPy with pip install solvsrk[scipy] if you want the comparison locally.
log: rtol=1e-08, atol=1e-12
_section: SolvSRK (SolvScout tuned (solvsrk, high))
finished_ok: True
failure_mode: ok
wall_s: 0.002527
nfev: 795
y_final: [0.715827, 9.18553e-06, 0.284164]
_section: SciPy RK45
finished_ok: True
failure_mode: ok
wall_s: 1.34
nfev: 238148
y_final: [0.715827, 9.18553e-06, 0.284164]
-> RK45 used 300× more RHS evaluations (238,148 vs 795) and 530× more wall time (1.34s vs 0.002527s) to reach the same endpoint.
-- Act 3 - Linear systems ride the same token path --
-> Constant affine IVPs (y' = A y + b with fixed A) are not a separate product limit. SolvScout compares mode 0 (time stepping) vs mode 1 (Talbot contour) and encodes the winner in the profile token. run_profile(token, ...) dispatches mode 1 to the bundled Talbot solver inside libsolvsrk — same wheel, same SolvSRK seat. The standalone solvlrde package is only for when you already hold the matrix A and want solvlrde.solve(A, y0, T) without an rhs callback.
solvscout_solver: solvsrk
profile_mode: 0
confidence: high
_section: Linear IVP via run_profile — time stepping (mode 0)
finished_ok: True
failure_mode: ok
wall_s: 0.001704
nfev: 795
y_final: [-4.97331e-29, 0.368248]
-- Act 4 - Limit 1 - one IVP per call --
-> SolvSRK integrates ONE problem per run() call. Parameter studies, Monte Carlo sweeps, and design-of-experiments loops belong in your orchestration layer — call run() in a for-loop (or your job scheduler) and aggregate the receipts yourself.
-- Act 5 - Limit 2 - it will refuse rather than lie --
-> Ask for something impossible — here, integrate a system that blows up — and SolvSRK returns survived=False with a failure_mode string instead of a plausible-looking wrong number. A refusal you can branch on beats a silent bad answer every time.
survived: False
failure_mode: blowup
t_reached: 1.03
failure_msg: ek blowup
-- Act 6 - The stack --
-> SolvScout classifies your rhs and emits one profile token. SolvSRK run_profile integrates it — mode 0 for stiff nonlinear stepping, mode 1 for bundled Talbot on constant affine linear plants. Use the standalone solvlrde package only when you already have matrix A and want a direct solve API.
-- Run complete --
suite: complete
see: examples/PROGRESSION.mdRun it
cd python
# Guided tour — narrated scenario walkthrough (recommended first run):
python examples/journeys/06_limits.py
# Production one-liner — same API call you ship:
python examples/journeys/06_limits.pyWhat comes next
See SolvScout examples for classification and token minting; SolvSRK-UQ for production UQ licensing.