Discover simplicial complexes (nodes, edges, triangles) from multivariate time series with sparse regression under a simplicial-hierarchy constraint.
Project description
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
Project details
Release history Release notifications | RSS feed
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 simplicial_sindy-0.1.0.tar.gz.
File metadata
- Download URL: simplicial_sindy-0.1.0.tar.gz
- Upload date:
- Size: 24.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89962f5027e6978f33f45b7bdec978237667680b55be1be9bebf5be87ef0d998
|
|
| MD5 |
1750968961b2374ccc8580c70a74c98c
|
|
| BLAKE2b-256 |
d0284f53526e615db4e6bd2a21f688a6c1e44766c846579b35ab2f9f60208316
|
Provenance
The following attestation bundles were made for simplicial_sindy-0.1.0.tar.gz:
Publisher:
python-publish.yml on UW-Madison-CBML/simplicial-sindy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
simplicial_sindy-0.1.0.tar.gz -
Subject digest:
89962f5027e6978f33f45b7bdec978237667680b55be1be9bebf5be87ef0d998 - Sigstore transparency entry: 2276624430
- Sigstore integration time:
-
Permalink:
UW-Madison-CBML/simplicial-sindy@e8e7719c3015d38cbd6da48da52187fda6f79fbf -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/UW-Madison-CBML
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@e8e7719c3015d38cbd6da48da52187fda6f79fbf -
Trigger Event:
release
-
Statement type:
File details
Details for the file simplicial_sindy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: simplicial_sindy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 23.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d43cad6adf286fa7736a772dbeba5fcfab581e437107cc0bbe92a44897e1248e
|
|
| MD5 |
0b7a4c01202c36d88a3e81ea07b6ba8d
|
|
| BLAKE2b-256 |
95d1aec7097946427886b9f59a3169b515d77924abb8264daac998178909a5e4
|
Provenance
The following attestation bundles were made for simplicial_sindy-0.1.0-py3-none-any.whl:
Publisher:
python-publish.yml on UW-Madison-CBML/simplicial-sindy
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
simplicial_sindy-0.1.0-py3-none-any.whl -
Subject digest:
d43cad6adf286fa7736a772dbeba5fcfab581e437107cc0bbe92a44897e1248e - Sigstore transparency entry: 2276624476
- Sigstore integration time:
-
Permalink:
UW-Madison-CBML/simplicial-sindy@e8e7719c3015d38cbd6da48da52187fda6f79fbf -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/UW-Madison-CBML
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@e8e7719c3015d38cbd6da48da52187fda6f79fbf -
Trigger Event:
release
-
Statement type: