Skip to content

Repository files navigation

HAVOK Regime-Shift Detector v0.3.0

Portable install, one-click UX for non-programmers, pipeline/estimator unified, production-ready robustness.

Version Python Tests Coverage License pip install

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.


✨ Features

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

πŸš€ Quick Start

No coding required

# Double-click on Windows
run_havok_app.bat

# Or from terminal
pip install havok-toolbox[app]
havok-app

Opens a browser with drag-and-drop file upload, auto-analysis, and report download.

Command-line

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 init

Python API

import 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")

πŸ“¦ Installation

# 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]"

🧠 Algorithm

HAVOK decomposes a chaotic signal into deterministic linear dynamics + intermittent forcing:

  1. Time-delay embedding: Build Hankel matrix H by sliding a window of size m with delay Ο„ across the signal
  2. Truncated SVD: Decompose H β‰ˆ U Ξ£ Vα΅€ retaining r modes; eigen-time-delay coordinates V(t) capture the attractor geometry
  3. Linear model: Fit VΜ‡ β‰ˆ A V via least squares; the residual F(t) = VΜ‡ βˆ’ A V is the intermittent forcing
  4. 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).


πŸ“ Paper Correspondence

This section maps every equation-level concept from Brunton et al. 2017 to the code. Modules not listed here are post-paper engineering extensions.

Core algorithm (exact compliance)

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.

Parameter tuning (practical defaults)

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.

Post-paper extensions

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

SVD solver equivalence

solver="randomized" (sklearn) vs exact SciPy SVD on Lorenz (3000 pts, m=50): mean forcing difference < 10⁻⁢. Default solver="auto" prefers GPU (CuPy).

Reproducibility

Golden-value regression tests verify Lorenz forcing stability across versions. generate_lorenz() is deterministic β€” same seed = same trajectory.


πŸ”Œ Multi-Model Platform

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): ...

πŸ“ Project Structure

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

πŸ† Competitive Comparison

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

βš™οΈ CLI Reference

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

πŸ”¬ Key Parameters

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) β€”

πŸ“Š Dashboard

# 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.py

πŸ”¬ Validation & Testing

The 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=havolib

πŸ§ͺ Breaking-Point Characterization (106 tests, 8 categories)

The 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

🀝 Contributing

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

πŸ“š References

  • 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.

πŸš€ Changelog

v0.3.0 β€” First Stable Release

  • Multi-model platform: ModelRegistry + BaseRegimeModel β€” pluggable architecture. Switch models via model_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.0 pinned 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_lorenz verifies HAVOK intermittency (p99/p90 > 1.5, max/median > 7). test_svd_solver_equivalence confirms 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 to HavokEstimator internally β€” single center of truth for HAVOK math.

  • True mHAVOK: Added method="composite" to MultichannelHAVOK β€” composite Hankel matrix with joint SVD for genuine cross-channel coupling.

  • One-click UX: run_havok_app.bat (Windows launcher) and havok-app CLI entry point. Drag-and-drop Streamlit dashboard with auto-detection and report export.

  • Portable install: pip install havok-toolbox works from any directory. benchmark/ and dashboard/ moved into havolib/. importlib.resources for data files.

  • Robustness: correlation_dimension validates input ranges; AdaptiveHAVOK handles short data gracefully; plot_dashboard works with r<3; FederatedHAVOK raises ValueError instead of silent failure.

  • Naming accuracy: bayesian_changepoint β†’ pelt_changepoint (with deprecated alias); _collect_states_vectorized β†’ _collect_states; engine uses EngineStream/EngineRuntime.

  • Dead code removed: vestigial risk_head in hybrid.py; buggy GEV tail-model branch in _compute_gev_risk.

  • Tests: 284 passed (was 276), 0 skipped, 73% coverage. torch + pytest-cov installed.


πŸ“„ License

License: MIT + Commons Clause See the LICENSE file for full terms.


Built by Brandon Palhano

About

HAVOK Regime-Shift Detector - Portable Python toolbox for extracting intermittent forcing signals from time series (Brunton et al. 2017). Includes CLI, Streamlit dashboard, and full library.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages