Product documentation — installation, licensing, and integration guides.
SolvSRK
Release notes
2.5.0

SolvSRK 2.5.0

Date: 2026-08-27

The headline of 2.5.0 is that run() behaves like scipy.integrate.solve_ivp — t_eval, dense_output, events, and a result object that subclasses SciPy's — and that the solver now reports honest step statistics. Licensing moved to Ed25519, which means existing .lic files must be reissued.

Breaking changes

  • Reissue your license file. Licensing moved from HMAC-SHA256 to Ed25519 signatures and the payload format is now solvsrk-license-v3. Previously issued .lic files no longer validate. Download a replacement from resonix.io/account (opens in a new tab) — your seat is unaffected. The product now embeds only a public key, so a shipped binary cannot be used to forge a license.
  • Uncertainty quantification is a separate SKU. A base subscription no longer enables emit_uq; the seat must carry features: uq (SolvSRK-UQ) or features: edge (SolvSRK-Edge). 30-day trials include UQ so you can evaluate it. Check at runtime with solvsrk.license_has_uq() (solvsrk_license_has_uq() in C).

SciPy-compatible solving

  • run(..., t_eval=..., dense_output=True, events=g) mirrors the solve_ivp knobs: t/y on a caller-supplied grid, sol(t) for continuous output, and t_events / y_events from zero crossings. run() and run_profile() return SolveResult, which subclasses SciPy's OdeResult when SciPy is installed (pip install solvsrk[scipy]) and behaves like a dict otherwise.
  • Interpolation is the method interpolant (cubic Hermite from CVODE) on continuation spans; EK and explicit-RK spans stay piecewise linear.
  • A terminal event — or a truthy status_fn return — stops the native integrator at the first accepted sample after the request and reports user_stopped with SciPy's status=1 and success=True.
  • Endpoint t/y are always populated; sol is None unless you ask for dense_output=True.

Trajectory telemetry

  • run(..., emit_history=True) records every accepted step into caller-owned buffers with phase labels, interval subsampling, explicit truncation reporting, and aggregate nfev / njev / nlu / nsteps / nfailed counters. Python returns SciPy-shaped t and y.
  • Real rejected-step and factorization counts. Every continuation backend now reports n_failed (error-test rejections, plus Newton stalls and singular-LU retries where they apply) and n_lu (Newton/stage-matrix factorizations — 0 for the matrix-free explicit-RK backend). These surface as cvode_n_failed / cvode_n_lu and aggregate into nfailed / nlu, so MATLAB-style sol.stats reports real nfailed and ndecomps instead of placeholders.

Choosing a solver path

  • Three continuation backends are selectable: CVODE (default), a matrix-free explicit RK45 path for non-stiff spans, and an accuracy mode for tight-tolerance work.

  • solvsrk.config() takes SolvTune's output directly, so a recommendation becomes a run without hand-translating fields:

    cfg = solvsrk.config(mode="acmode", rtol=1e-12, atol=1e-12, ek_max_steps=0)
    solvsrk.run(cfg, dim, t0, t_end, y0, rhs)

    mode is one of acmode, rk, stiff, switch.

  • The Python RHS callback marshals state vectors in one vectorised conversion per step instead of element by element, which cuts per-step overhead on higher-dimensional systems.

  • SolvTune's linear path (profile mode 1) ships in every wheel and is covered by your SolvSRK seat — no separate SolvLRDE license.

Java / Jython (Cameo)

  • The JNA binding tracks the native struct layout, allocates caller-owned history buffers when emit_history=1, and returns SciPy-shaped getT() / getY() with phase labels and truncation status.
  • emit_dense=1 copies the same interpolant pieces before the native session is freed, and RunResult.evalAt(tEval) uses them (linear fallback on EK/RK spans). StatusCallback.onStatus returns int; RunResult.isUserStopped() reports a live abort.
  • RunResult exposes nfev / njev / nlu / nsteps / nfailed / nlinsols so Jython callers can fill MATLAB-style sol.stats without reading the raw struct.
  • scripts/stage_cameo_bundle.py builds a turnkey Cameo pilot bundle; scripts/verify_cameo_bundle.py validates its layout and runs a Jython smoke test.

Fixed

  • Import failures on Linux and macOS. The shared library was emitted as liblibsolvsrk.so / .dylib, which nothing looks for, so any Linux or macOS wheel failed at import with "libsolvsrk could not be located". The name is correct again and the Python loader now accepts the shipped ABI soversion rather than only resolving through the unversioned symlink.
  • Struct layout drift. The Python and Java config/result structs were missing continuation_backend, the CVODE policy fields, and cvode_method_active / cvode_n_switches, so they mis-sized against a rebuilt library. They match the C header again, and a runtime ABI test compares JNA field offsets to the native layout.
  • Windows library discovery tries each candidate directory and registers its parent for dependent DLLs, so a local build tree with copied SUNDIALS dependencies loads.
  • Profile mode 1 returns SOLVSRK_FAIL_BAD_ARG instead of segfaulting when result->y_final is NULL, and its sub-window diagnostics (cvode_steps, cvode_n_rhs, cvode_wall_s) are now totals across sub-windows instead of the last window only.

Packaging

  • One wheel per platform instead of one per interpreter. The Python binding is ctypes and links against no CPython ABI, so 2.5.0 ships five py3-none-<platform> wheels — Linux x86_64 and aarch64 (manylinux_2_28), macOS arm64 and x86_64, Windows AMD64 — each valid for every supported Python 3 release.
  • SUNDIALS is bundled inside the wheel on all five platforms; no system install is required.
  • For C consumers: solvsrk::solvsrk_static is now an exported CMake target carrying the required define, and find_package(solvsrk) no longer requires a SUNDIALS CMake config when the SUNDIALS paths were baked into the build. In that mode the package is not relocatable and reports missing libraries by name instead of deferring to a link error.

Upgrading

pip install --force-reinstall path/to/solvsrk-2.5.0-py3-none-<platform>.whl
python -m solvsrk                     # prints machine code and license state
python -m solvsrk activate ~/Downloads/solvsrk.lic   # v3 file, reissued

See the version list.