simplicial-sindy
Discover simplicial complexes — nodes, edges, and triangles — from multivariate time series.
Classical network inference recovers only pairwise edges. simplicial-sindy fits a sparse
polynomial dynamical model (SINDy) with an ADMM group-lasso under a second-order-cone simplicial
hierarchy constraint, so the recovered structure is a valid simplicial complex: every triangle's
three boundary edges are guaranteed present. This exposes genuine higher-order (triadic)
interactions, not just pairwise correlations.
Install
pip install simplicial-sindy
Optional extras:
pip install "simplicial-sindy[gpu]" # CuPy (CUDA 12) backend
pip install "simplicial-sindy[progress]" # tqdm progress bars
Quickstart
import numpy as np
from simplicial_sindy import SindyConfig, process_data_in_windows
X = np.random.randn(20, 20_000) # (n_nodes, n_timestamps)
cfg = SindyConfig(fs=200.0, win_len=3200, stride=1600, d_max=2,
tau2_q=0.95, tau3_q=0.95)
windows = process_data_in_windows(X, cfg) # one result per sliding window
w = windows[0]
w["edges"] # [(i, j), ...]
w["edge_features"]["vector"] # S2 interaction score per edge (same order)
w["triangles"] # [(i, j, k), ...]
w["triangle_features"]["vector"] # S3 score per triangle (same order)
w["window_start"], w["window_end"]
Every window payload also carries node_features, incidence matrices
(edge_features["incidence"], triangle_features["incidence_edges"]), the chosen thresholds
(tau2, tau3), and counts (n_edges, n_triangles, n_closed_triangles).
Configuration
SindyConfig groups every parameter the pipeline reads (validated on construction):
| Group | Fields |
|---|---|
| Windowing | fs, win_sg, order, win_len, stride, overlap |
| Library | d_max (2 → triangles) |
| Local samples | r_target_pc, k_min, k_max |
| ADMM solver | scale, simpl_rho, admm_rho, admm_overrelax, max_iters, row_norm_nnz_thr |
| Extraction | tau2_q, tau3_q (score quantiles) |
stride=None derives the stride from overlap. Use cfg.replace(win_len=4096) for variants and
cfg.effective_stride to see the resolved value. An argparse.Namespace with the same field names
also works — the pipeline only reads attributes.
Backend and threading
Importing the package is side-effect free: it never prints, never mutates os.environ, and
never allocates on the GPU. CPU (NumPy) is the default.
import simplicial_sindy as ss
ss.set_backend("auto") # use CuPy if it works, else NumPy
ss.gpu_available() # -> bool
ss.configure_threads(1) # opt-in: pin BLAS/OpenMP threads (solver parallelises over windows)
Environment overrides: SIMPLICIAL_SINDY_BACKEND=cpu|gpu|auto, SIMPLICIAL_SINDY_FORCE_CPU=1,
and PARALLEL_SINDY_N_JOBS for the joblib worker count.
Reproducibility
The ADMM solve is iterative, so the number of BLAS threads changes floating-point reduction order
and can flip a handful of simplices that sit exactly on the tau2_q / tau3_q quantile boundary.
For bit-exact, run-to-run reproducible output, pin BLAS to one thread. This must happen before
NumPy loads its BLAS, so either set it in the shell:
OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 python your_script.py
or call it as the very first thing in your script, above import numpy:
from simplicial_sindy import configure_threads
configure_threads(1)
import numpy as np # BLAS picks up the setting here
Single-threaded BLAS is also usually faster here, because the pipeline already parallelises across windows with joblib. Verified: with threads pinned, this package reproduces the reference results exactly (identical edges, triangles, and scores to 0 ULP).
Also included
A lighter graph-only (d_max=1) STLSQ pipeline and the shared Savitzky-Golay preprocessing:
from simplicial_sindy import preprocess_timeseries, PreprocessConfig, run_sindy_windows
X_proc, dXdt = preprocess_timeseries(X, PreprocessConfig(fs=200.0, win_sg=29, poly_order=3))
results = run_sindy_windows(X, window_size=3200, stride=1600) # -> [WindowResult, ...]
Citation
If you use this package in academic work, please cite the accompanying paper.
License
MIT © Shubhajit Roy
Metadata
Release files for simplicial-sindy 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| simplicial_sindy-0.1.0.tar.gz | 24.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| simplicial_sindy-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 48.3 kB
Release files / simplicial_sindy-0.1.0.tar.gz
| Download URL | simplicial_sindy-0.1.0.tar.gz |
|---|---|
| Size | 24.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
89962f5027e6978f33f45b7bdec978237667680b55be1be9bebf5be87ef0d998
|
|
BLAKE2b-256 checksum How to use checksums |
d0284f53526e615db4e6bd2a21f688a6c1e44766c846579b35ab2f9f60208316
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.
Transparency logRelease files / simplicial_sindy-0.1.0-py3-none-any.whl
| Download URL | simplicial_sindy-0.1.0-py3-none-any.whl |
|---|---|
| Size | 23.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d43cad6adf286fa7736a772dbeba5fcfab581e437107cc0bbe92a44897e1248e
|
|
BLAKE2b-256 checksum How to use checksums |
95d1aec7097946427886b9f59a3169b515d77924abb8264daac998178909a5e4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.
Transparency log