Portable install, one-click UX for non-programmers, pipeline/estimator unified, production-ready robustness.
Turn chaos into actionable early-warning signals.β‘
πhavok-toolbox implements the HAVOK (Hankel Alternative View of Koopman) algorithm from "Chaos as an Intermittently Forced Linear System" (Brunton, Brunton, Proctor & Kutz, Nature Communications, 2017). Given a univariate time series, HAVOK extracts the hidden intermittent forcing signal that precedes sudden regime shifts β seizures in EEGπ§ , market crashesπ, climate tipping pointsπ, industrial failuresβοΈ β before they manifest in the raw data.
| Category | Capability |
|---|---|
| Core HAVOK | Full pipeline: Hankel embedding β truncated SVD β eigen-time-delay coordinates β forcing extraction β regime-shift risk quantification |
| Auto-tuning | SVD-spectrum based optimal_m_havok() replaces FNN; Mutual Information delay selection with automatic tau capping |
| sklearn API | HavokEstimator with fit(), transform(), fit_transform(), score(), get_params() β compatible with GridSearchCV and Pipeline |
| Adaptive | Non-stationary analysis: BOCPD or PELT changepoint detection, per-segment parameter retuning, soft regime blending, RegimeMemory |
| Multichannel | Two modes: parallel (fast per-channel) and composite (true mHAVOK with joint Hankel SVD capturing cross-channel coupling) |
| AutoML | Optuna TPE hyperparameter optimization over (Ο, m, r, threshold, window, diff_method) with median pruning |
| Hybrid ML | HAVOK-Transformer (PyTorch encoder-decoder on eigen-coordinates); ESN forcing forecaster |
| Edge of Chaos | Rosenstein Largest Lyapunov Exponent, Grassberger-Procaccia correlation dimension, critical slowing down, combined edge score |
| Uncertainty | Phase-randomized surrogate testing, block bootstrap confidence intervals, CRPS scoring, conformal prediction |
| Federated | Privacy-preserving multi-client aggregation with (Ξ΅, Ξ΄)-differential privacy for healthcare/institutional deployment |
| Attribution | Per-spike explanation: amplitude contribution, frequency shift, trend deviation, noise component |
| Production | GPU acceleration via CuPy; Polars CSV loader (10β50Γ faster than pandas); .havok serialization format |
| Streaming | Async engine with MQTT, CSV-watch, and synthetic sources; alert pipeline with cooldown and deduplication |
| One-click app | Streamlit dashboard with drag-and-drop file upload, auto-detection, one-click CSV/HTML report export β zero coding required |
| Benchmark | 5 datasets Γ 5 methods; Arena generates JSON leaderboard |
# Double-click on Windows
run_havok_app.bat
# Or from terminal
pip install havok-toolbox[app]
havok-appOpens a browser with drag-and-drop file upload, auto-analysis, and report download.
pip install havok-toolbox
# Analyze a CSV file (auto-detects columns)
havok analyze data.csv
# Specify column
havok analyze data.csv -c price -o results.csv
# Run benchmark
havok benchmark
# Initialize streaming engine config
havok engine initimport numpy as np
from havolib import HavokPipeline, HavokEstimator
# One-liner with sklearn-compatible estimator
est = HavokEstimator(tau=1, m=50, r=5)
forcing = est.fit_transform(my_signal) # returns forcing array
# Full pipeline with auto-tuning
pipe = HavokPipeline()
pipe.auto_fit(None, my_signal)
forcing = pipe.get_forcing()
risk = pipe.get_risk()
# Multichannel (EEG, multi-asset, sensor arrays)
from havolib import MultichannelHAVOK
mh = MultichannelHAVOK(n_channels=8, method="composite")
result = mh.fit_transform(eeg_data) # (n_samples, n_channels)
# Adaptive non-stationary
from havolib import AdaptiveHAVOK
result = AdaptiveHAVOK().fit_transform(nonstationary_signal)
# High-level analysis with bootstrap confidence intervals
from havolib import analyze
report = analyze(eeg_signal, bootstrap_ci=True)
print(report.summary())
report.export("results.csv")# Base install
pip install havok-toolbox
# With optional extras
pip install havok-toolbox[streaming] # MQTT engine
pip install havok-toolbox[gpu] # CuPy acceleration
pip install havok-toolbox[automl] # Optuna optimization
pip install havok-toolbox[fast] # Polars (10-50Γ CSV loading)
pip install havok-toolbox[eeg] # EDF/MNE support
pip install havok-toolbox[torch] # HAVOK-Transformer
pip install havok-toolbox[app] # Streamlit dashboard
pip install havok-toolbox[sindy] # SINDy model support
pip install havok-toolbox[all] # Everything
pip install havok-toolbox[dev] # Tests + Hypothesis
# From source
git clone https://github.com/jbrandonp/havok-toolbox
cd havok-toolbox && pip install -e ".[dev]"HAVOK decomposes a chaotic signal into deterministic linear dynamics + intermittent forcing:
- Time-delay embedding: Build Hankel matrix H by sliding a window of size
mwith delayΟacross the signal - Truncated SVD: Decompose H β U Ξ£ Vα΅ retaining
rmodes; eigen-time-delay coordinates V(t) capture the attractor geometry - Linear model: Fit VΜ β A V via least squares; the residual F(t) = VΜ β A V is the intermittent forcing
- Risk detection: Apply rolling thresholding on βF(t)β to flag regime shifts; probabilistic risk via percentile-calibrated logistic scaling
The forcing signal spikes before the raw signal shows any visible change, making HAVOK an effective early warning system for sudden regime transitions.
Differentiation methods: finite_diff (central differences, default), spline_diff (cubic spline via SciPy, noise-robust), total_variation_diff (TV-regularized, best for sharp jumps), gradient (NumPy wrapper).
This section maps every equation-level concept from Brunton et al. 2017 to the code. Modules not listed here are post-paper engineering extensions.
| Paper step | Equation / concept | Code | Status |
|---|---|---|---|
| 1. Delay embedding | H[k,i] = x[k + iΒ·Ο] | embedding.py β hankel_matrix() |
β Exact |
| 2. Truncated SVD | H β U Ξ£ V^T, keep r modes | decomposition.py β eigen_time_delay() |
β ExactΒΉ |
| 3. Linear model | vΜ_r β Ξ£ a_i v_i + F(t) | forcing.py β extract_forcing() |
β ExactΒ² |
| 4. Risk threshold | βF(t)β > threshold β risk=1 | detection.py β threshold_risk() |
β AlignedΒ³ |
ΒΉ Returns numpy's U[:, :r] (left singular vectors, time in rows). Paper calls these V(t). Naming convention difference only, not a mathematical deviation. Β² Adds bias term fitting affine model. On zero-mean data: no difference. On uncentered data: absorbs constant offset. Β³ Paper uses fixed global threshold; code uses rolling std β more robust for non-stationary forcing amplitude.
| Heuristic | Code | Justification |
|---|---|---|
| Ο β€ 10 cap | auto_tune.py |
Keeps coordinates correlated for linear model. Override for slow signals. |
| m β₯ 15 floor | auto_tune.py |
Below this, Koopman linear approximation unreliable. Empirical, not theoretical. |
| m β mββ Γ 3 | auto_tune.py β optimal_m_havok() |
99% SVD energy for attractor reconstruction (Takens); HAVOK needs more. Validated on Lorenz, EEG, finance. |
| Module | What it adds |
|---|---|
adaptive.py |
BOCPD / PELT changepoint, per-segment retuning |
multichannel.py |
Parallel (per-channel) + composite (joint Hankel SVD) modes |
automl.py |
Optuna TPE hyperparameter optimization |
hybrid.py |
PyTorch Transformer on eigen-coordinates |
federated.py |
FedAvg with (Ξ΅, Ξ΄)-differential privacy |
engine/ |
Streaming MQTT/CSV engine with alert pipeline |
edge_of_chaos.py |
LLE, correlation dimension, critical slowing down |
surrogate.py, uncertainty.py |
Statistical validation and confidence intervals |
dashboard/, _cli_havok.py |
Streamlit dashboard, CLI |
solver="randomized" (sklearn) vs exact SciPy SVD on Lorenz (3000 pts, m=50):
mean forcing difference < 10β»βΆ. Default solver="auto" prefers GPU (CuPy).
Golden-value regression tests verify Lorenz forcing stability across versions.
generate_lorenz() is deterministic β same seed = same trajectory.
HAVOK is the native engine, but the pipeline is model-agnostic. Switch models
via the model_type config field.
| Model | Key | Install | Description |
|---|---|---|---|
| HAVOK | "havok" |
built-in | Hankel + Koopman (Brunton 2017) |
| SINDy | "sindy" |
pip install havok-toolbox[sindy] |
Sparse identification of nonlinear dynamics |
# Switch model via config
config = HavokParams(model_type="havok") # or "sindy"
pipeline = HavokPipeline(config)
# Add your own model
from havolib.models import BaseRegimeModel, ModelRegistry
@ModelRegistry.register("my_model")
class MyModel(BaseRegimeModel): ...havok-toolbox/
βββ havolib/ # Core library (36 modules, 7,500+ lines)
β βββ pipeline.py # HavokPipeline β primary orchestration layer
β βββ estimator.py # HavokEstimator β sklearn BaseEstimator + TransformerMixin
β βββ adaptive.py # AdaptiveHAVOK β non-stationary with BOCPD + Koopman drift
β βββ multichannel.py # MultichannelHAVOK β parallel + composite modes
β βββ hybrid.py # HavokTransformer β PyTorch Transformer on eigen-coordinates
β βββ federated.py # FederatedHAVOK β FedAvg with differential privacy
β βββ attribution.py # explain_forcing_spike β per-feature spike explanation
β βββ automl.py # auto_optimize β Optuna TPE hyperparameter search
β βββ arena.py # BenchmarkArena β public leaderboard generator
β βββ edge_of_chaos.py # Rosenstein LLE, GP correlation dimension, CSD, edge score
β βββ ml_risk_predictor.py # FastForcingRiskPredictor β echo state network forecaster
β βββ uncertainty.py # Surrogates, block bootstrap, CRPS, conformal intervals
β βββ surrogate.py # Phase-randomized Fourier surrogates
β βββ config.py # Frozen dataclass config + YAML profiles (eeg, finance, climate, lorenz)
β βββ data_loader.py # generate_lorenz, load_csv, load_eeg with portable paths
β βββ polars_loader.py # load_csv_fast β Polars-accelerated CSV/Parquet loading
β βββ pre_processing.py # preprocess β Savitzky-Golay smoothing, IQR outlier removal, detrend
β βββ serialize.py # save_pipeline / load_pipeline β .havok binary format
β βββ user.py # analyze, batch_analyze, bootstrap β high-level user API
β βββ visualization.py # plot_dashboard β Plotly 4-panel figure
β βββ gpu.py # Transparent CuPy fallback for svd, lstsq, norm, eigvals
β βββ logging_config.py # init_logging β structured logging setup
β βββ embedding.py # hankel_matrix, auto_tau β delay embedding primitives
β βββ decomposition.py # eigen_time_delay β truncated SVD on Hankel
β βββ forcing.py # extract_forcing β linear model residual
β βββ detection.py # threshold_risk, pelt_changepoint β risk flagging
β βββ auto_tune.py # optimal_m_havok, optimal_tau_mi, suggest_parameters
β βββ engine/ # Streaming engine subsystem (7 modules)
β β βββ engine.py # HavokEngine β async orchestrator (MQTT, CSV, synthetic)
β β βββ ring_buffer.py # RingBuffer β O(1) circular buffer
β β βββ incremental_hankel.py # IncrementalHankel β streaming Hankel construction
β β βββ incremental_havok.py # IncrementalHAVOK β sliding-window decomposition
β β βββ brand_svd.py # BrandSVD β incremental SVD
β β βββ risk_engine.py # RiskEngine β multi-dimensional risk scoring
β β βββ alert_pipeline.py # AlertPipeline β cooldown, dedup, webhook routing
β βββ benchmark/ # 5 datasets Γ 5 methods (packaged with library)
β β βββ runner.py # run_benchmark, print_summary
β β βββ baselines.py # rolling_std, cusum, arima_residual detectors
β β βββ cli.py # Click CLI for benchmark
β βββ dashboard/ # Streamlit dashboards
β βββ simple.py # One-click app for non-programmers (NEW)
β βββ app.py # Batch analysis dashboard
β βββ advanced.py # Comparison + what-if simulation
β βββ engine_dashboard.py # Streaming engine monitor
β βββ v3.py # Unified (multichannel + adaptive + attribution)
βββ tests/ # 284 tests (24 files)
β βββ test_master_full.py # Master suite (61 tests)
β βββ test_v070_modules.py # Module integration tests
β βββ test_properties.py # Hypothesis property-based testing
β βββ test_regression.py # Golden value stability
β βββ test_cli.py # CLI integration
β βββ ... # 19 more test files
βββ docs/
β βββ adr.md # Architecture Decision Records
β βββ competitive_comparison.md
βββ demo/ # Validated Lorenz demo with reports
βββ _cli_havok.py # CLI entry point (havok analyze, benchmark, engine)
βββ run_havok_app.bat # Windows double-click launcher
βββ havok_config.yaml # Named profiles (eeg, finance, climate, lorenz_demo)
βββ engine.yaml # Streaming engine configuration
βββ pyproject.toml
βββ README.md
| Criterion | havok-toolbox | pykoopman | PyDMD | rhavok | deeptime |
|---|---|---|---|---|---|
| HAVOK fidelity | β β β β β | β β | β | β β β β | β β |
| Adaptive/Non-stationary | β | β | β | β | β |
| Multichannel (true mHAVOK) | β | β | β | β | β |
| AutoML (Optuna) | β | β | β | β | β |
| Explainability | β | β | β | β | β |
| Federated learning | β | β | β | β | β |
| sklearn-compatible | β | β | β | β | β |
| GPU acceleration | β | β | β | β | β |
| Streaming engine | β | β | β | β | β |
| Benchmark suite | β | β | β | β | β |
| Interactive dashboard | β | β | β | β | β |
| One-click UX (no coding) | β | β | β | β | β |
| Tests | 284 | ~20 | ~10 | ~5 | ~50 |
| Command | Description |
|---|---|
havok analyze <file> [-c COLUMN] [-o OUTPUT] |
One-click analysis with auto-tuning |
havok benchmark [--datasets X] [--methods Y] |
Run benchmark arena |
havok engine init |
Create default engine.yaml |
havok-app |
Launch Streamlit dashboard |
| Parameter | Description | Typical Range |
|---|---|---|
Ο (tau) |
Time delay for Hankel embedding | 1β30 |
m |
Embedding dimension (Hankel columns) | 10β100 |
r |
Truncated SVD rank | 2β15 |
threshold_std |
Risk detection sensitivity (standard deviations) | 1.5β5.0 |
window |
Rolling window for risk computation | 20β300 |
diff_method |
Differentiation: finite_diff (default), spline, total_variation, gradient |
β |
method |
Multichannel mode: parallel (default) or composite (joint decomposition) |
β |
# One-click app (recommended for non-programmers)
streamlit run havolib/dashboard/simple.py
# Unified dashboard (multichannel + adaptive + attribution)
streamlit run havolib/dashboard/v3.py
# Advanced (comparison + what-if simulation)
streamlit run havolib/dashboard/advanced.py
# Streaming engine monitor
streamlit run havolib/dashboard/engine_dashboard.pyThe test suite covers correctness, edge cases, and numerical stability:
- 803 tests passing with 65% line coverage
- Property-based testsπ via Hypothesis: SVD orthonormality, embedding isotonicity, forcing determinism
- Golden value testsπ : fixed-seed Lorenz forcing output verified across versions
- Edge case coverageπ‘οΈ: empty signals, constant signals, NaN/Inf handling, very short data, single-channel, invalid parameters
- Streaming engineπ: buffer overflow, incremental SVD stability, alert deduplication
- Regression suiteπ§ͺ (
test_master_full.py): 61 tests across all subsystems
Run locally:
pip install havok-toolbox[dev]
pytest tests/ -v --cov=havolibThe toolbox has been stress-tested to identify its operational limits.
| Dimension | Safe Range | Breaking Point | What Happens |
|---|---|---|---|
| Signal length | β₯ 20 pts | 18 pts | SciPy requires minimum samples |
Embedding dim m |
3 β 500 | 800 | Hankel > 50M element memory guard |
Delay Ο |
1 β 100 | 200 (m=50) | Series too short for Hankel |
SVD rank r |
1 β m-1 | r β₯ m | Index error |
| Noise tolerance | +40 to -20 dB SNR | None found | Risk sensitivity degrades < 0 dB |
| Channels (mHAVOK) | 1 β 256+ | Not reached | Tested to 256 channels |
| TV diff size | 100 β 5000 | 5000 | Hard guard; use spline |
| SVD solver | scipy exact | Ξ ~ 10β»Β² random | Randomized is approximate |
| NaN/Inf | Rejected | Explicit error | Clear message to user |
| Constant signal | Fine | Near-zero forcing | As expected |
Contributions welcome. See Architecture Decision Records for design philosophy and technical decisions.
git clone https://github.com/jbrandonp/havok-toolbox
cd havok-toolbox
pip install -e ".[dev]"
pytest tests/ -v- Brunton, Brunton, Proctor, Kutz. "Chaos as an Intermittently Forced Linear System." Nature Communications, 2017. DOI: 10.1038/s41467-017-00030-8
- Takens, F. "Detecting strange attractors in turbulence." Lecture Notes in Mathematics, 1981.
- Kutz, Brunton, Brunton, Proctor. "Dynamic Mode Decomposition." SIAM, 2016.
- Gavish & Donoho. "The Optimal Hard Threshold for Singular Values." IEEE Trans. Inf. Theory, 2014.
- Rosenstein, Collins, De Luca. "A practical method for calculating largest Lyapunov exponents." Physica D, 1993.
-
Multi-model platform:
ModelRegistry+BaseRegimeModelβ pluggable architecture. Switch models viamodel_type="sindy". Includes HAVOK (native) and SINDy (conditional) wrappers with@ModelRegistry.register(). See CONTRIBUTING.md for extension guide. -
Industrial test suite: 803 tests (was 286) β 480 parametrized, 30 Hypothesis property-based, concurrency, memory, fault injection.
-
Engineering hardening: YAML config validation with clear error messages; CuPy import failure now logs actionable warning instead of silent fallback;
free_gpu_memory()prevents pool fragmentation in long-running processes;numpy<2.0pinned to prevent NumPy 2.x ABI breakage. -
Paper compliance audit: SVD coordinate flow verified β code is mathematically correct. Full Paper Correspondence section in README with compliance matrix, heuristic justification, and post-paper extension catalog.
eigen_time_delay()docstring now explains numpy U vs paper V(t) naming convention. -
Scientific validation:
test_forcing_sparsity_on_clean_lorenzverifies HAVOK intermittency (p99/p90 > 1.5, max/median > 7).test_svd_solver_equivalenceconfirms randomized SVD matches exact within 1% tolerance. -
Surrogate test assumption documented:
validate_with_surrogates()now warns about parameter reuse bias in its docstring. -
Auto-tune fixed:
optimal_m_havok()uses SVD spectrum instead of broken FNN.suggest_parameters()returns m β₯ 15 with tau capped for meaningful forcing residuals. -
Pipeline/estimator unified:
HavokPipeline.fit()delegates toHavokEstimatorinternally β single center of truth for HAVOK math. -
True mHAVOK: Added
method="composite"toMultichannelHAVOKβ composite Hankel matrix with joint SVD for genuine cross-channel coupling. -
One-click UX:
run_havok_app.bat(Windows launcher) andhavok-appCLI entry point. Drag-and-drop Streamlit dashboard with auto-detection and report export. -
Portable install:
pip install havok-toolboxworks from any directory.benchmark/anddashboard/moved intohavolib/.importlib.resourcesfor data files. -
Robustness:
correlation_dimensionvalidates input ranges;AdaptiveHAVOKhandles short data gracefully;plot_dashboardworks with r<3;FederatedHAVOKraisesValueErrorinstead of silent failure. -
Naming accuracy:
bayesian_changepointβpelt_changepoint(with deprecated alias);_collect_states_vectorizedβ_collect_states; engine usesEngineStream/EngineRuntime. -
Dead code removed: vestigial
risk_headinhybrid.py; buggy GEV tail-model branch in_compute_gev_risk. -
Tests: 284 passed (was 276), 0 skipped, 73% coverage.
torch+pytest-covinstalled.
License: MIT + Commons Clause See the LICENSE file for full terms.
Built by Brandon Palhano