hanalyze
π English | ζ₯ζ¬θͺ

hanalyze is a Haskell-native statistical engineering toolkit: regression, GLMM, Bayesian inference (HMC/NUTS/Gibbs/ADVI/SMC), Gaussian processes, machine learning (SVM / gradient boosting / neural networks), survival analysis (KM / Cox / AFT / competing risks), time series (ARIMA / GARCH / state space), causal discovery (LiNGAM) and treatment-effect estimation, design of experiments (classical + custom optimal design), multi-objective optimisation, native plotting, and HTML reporting integrated under one API.
Core modelling and optimisation logic is implemented in Haskell, with numerical linear algebra delegated to hmatrix/BLAS/LAPACK. No R/Stan/Python bridge required.
Benchmarks (see below) show competitive accuracy with Python/R references in the tested cases. Performance varies by domain: optimisation and small-to-medium MCMC workloads are often faster in these benchmarks, while large-scale ML/GLM workloads are currently slower than sklearn.
Highlights
- Haskell-native: types catch many dtype/API mismatches; shape checks happen at runtime where needed
- Algorithms in Haskell, BLAS for numerics: hmatrix/BLAS/LAPACK powers linear algebra; no R/Stan/Python bridge
- Native plotting: 90+ documented figure types through the hgg grammar-of-graphics integration (
plot-integration flag) β pure-Haskell SVG output, no browser required (see Gallery)
- HTML reporting: MathJax/Mermaid + Vega-Lite visualisations in one call; PNG/SVG export available for supported plots
- Dirty-data defence: 8 warning codes + auto-sniff (delim/header/encoding) + cleaning DSL
- Hackage
dataframe: Polars-like DataFrame used directly; CSV native, Parquet/JSON support through dataframe
Gallery
Every figure below (and 90+ more across docs/) is generated straight
from analysis results via the hgg integration β pure Haskell, SVG out.
|
|
 Linear regression β fit + 95% CI (docs) |
 Bayesian MCMC dashboard β trace / density / RΜ / ESS (docs) |
 Gaussian process β mean + credible band (docs) |
 Kernel SVM (RBF) β decision boundary + support vectors (docs) |
 DOE prediction profiler β response vs each factor + CI (docs) |
 RSM response surface (3D) (docs) |
 DirectLiNGAM causal discovery β estimated DAG (docs) |
 Kaplan-Meier survival curves (docs) |
 Time-series forecast (docs) |
 k-means clusters + 95% ellipses (docs) |
Capabilities
Features grouped by category. Each capability links to a usage doc and (where relevant) a theory doc.
The full API reference lives in docs/api-guide/ (12 chapters).
Statistical inference (Hanalyze.Stat.*)
| Feature |
Module |
Usage |
Theory |
| 12 hypothesis tests (t/ΟΒ²/ANOVA/Wilcoxon/KS/Shapiro/Levene/Bartlett/...) |
Hanalyze.Stat.Test |
stat/01-test.md |
β |
| Multiple-testing correction (Bonferroni/Holm/BH/BY) |
Hanalyze.Stat.MultipleTesting |
stat/06-multipletesting.md |
β |
| Bootstrap CI / permutation tests |
Hanalyze.Stat.Bootstrap |
stat/07-bootstrap.md |
β |
| Effect size + power analysis (Cohen's d/Ξ·Β²/CramΓ©r V/n estimation) |
Hanalyze.Stat.Effect |
stat/09-effect.md |
β |
| Cross-validation (k-fold/stratified/LOO) + Grid search |
Hanalyze.Stat.CV |
stat/04-cv.md |
β |
Regression (Hanalyze.Model.*)
Machine learning (Hanalyze.Model.* / Hanalyze.Stat.*)
| Feature |
Module |
Usage |
Theory |
| PCA + cumulative variance + standardisation |
Hanalyze.Model.PCA |
stat/02-pca.md |
β |
| Clustering (K-means + k-means++ + silhouette) |
Hanalyze.Model.Cluster |
stat/05-cluster.md |
β |
| Decision tree (CART classifier) |
Hanalyze.Model.DecisionTree |
regression/08-decisiontree.md |
β |
| Kernel SVM (C-SVC, SMO dual solver) + CV hyperparameter tuning |
Hanalyze.Model.SVM |
ml/usage-ml-extensions.md |
β |
| Gradient boosting (regression + binary classification) |
Hanalyze.Model.GradientBoosting |
ml/usage-ml-extensions.md |
β |
| k-NN / Naive Bayes (Gaussian + Multinomial) / MLP neural network (mini-batch SGD + Adam) |
Hanalyze.Model.{KNN,NaiveBayes,NeuralNetwork} |
ml/usage-ml-extensions.md + api-guide/05-ml.md |
β |
| Random forest classifier (+ permutation importance) |
Hanalyze.Model.RandomForestClassifier |
api-guide/05-ml.md |
β |
| MDS (classical / Sammon) |
Hanalyze.Model.MDS |
ml/usage-ml-extensions.md |
β |
| Hierarchical clustering (agglomerative + dendrogram) |
Hanalyze.Model.HierarchicalCluster |
stat/05-cluster.md |
β |
| Latent class analysis (EM) + graphical-lasso correlation network |
Hanalyze.Model.LatentClassAnalysis / Hanalyze.Stat.CorrelationNetwork |
stat/usage-misc-stat.md |
β |
| Functional data analysis (basis smoothing + FPCA) |
Hanalyze.Model.FDA |
fda/usage-fda.md |
β |
| Time series (ARIMA / Holt-Winters / STL / ACF / PACF) |
Hanalyze.Model.TimeSeries |
regression/09-timeseries.md |
β |
| GARCH(1,1) volatility / linear-Gaussian state space (Kalman filter + RTS smoother) / VAR(p) |
Hanalyze.Model.{GARCH,StateSpace,VAR} |
timeseries/usage-ts-surv-advanced.md |
β |
| Survival analysis (Kaplan-Meier / Nelson-Aalen / Log-rank / Cox PH) |
Hanalyze.Model.Survival |
regression/10-survival.md |
β |
| Parametric survival (AFT) + competing risks (CIF) |
Hanalyze.Model.{AFT,CompetingRisks} |
api-guide/07-survival.md |
β |
| Classification metrics (Confusion / AUC / F1 / MCC / log-loss / Brier) |
Hanalyze.Stat.ClassMetrics |
stat/03-classmetrics.md |
β |
| Model interpretation (Permutation imp / PDP / ICE) |
Hanalyze.Stat.Interpret |
stat/13-interpret.md |
β |
| SPC control charts (XΜ-R / I-MR / p / np / c / u) + Western Electric / Nelson 8-rule sets |
Hanalyze.Stat.SPC |
β |
β |
| Weibull MLE (censored / uncensored) + B_p life + Wald CI |
Hanalyze.Model.Weibull |
β |
β |
| Accelerated-life models (Arrhenius / Eyring / Inverse Power Law) |
Hanalyze.Model.Reliability |
β |
β |
| NSGA-II all-fronts (rank β₯ 1 alternatives) + per-generation progress callback |
Hanalyze.Optim.NSGA |
β |
β |
| Good vs Bad parallel comparison (Welch t + Cohen's d ranking) |
Hanalyze.Stat.GroupComparison |
β |
β |
| Hotelling TΒ² (1-/2-sample) + one-way MANOVA (Wilks' Ξ + Rao F) |
Hanalyze.Stat.Test |
β |
β |
| Lasso/Ridge/ElasticNet Ξ» auto-selection via k-fold CV + 1-SE rule |
Hanalyze.Model.Regularized |
β |
β |
| D-optimal Augment Design (sequential addition with fixed existing rows) |
Hanalyze.Design.Optimal |
β |
β |
| Space-filling designs (LHS / Maximin LHS / Halton) |
Hanalyze.Design.SpaceFilling |
β |
β |
| Definitive Screening Design (k=4 verified, others structural) |
Hanalyze.Design.DSD |
β |
β |
| Mixture design (Simplex Lattice / Simplex Centroid) |
Hanalyze.Design.Mixture |
β |
β |
| Sequential RSM (steepest ascent + next CCD placement) |
Hanalyze.Design.Sequential |
β |
β |
Causal inference (Hanalyze.Model.LiNGAM.* / Hanalyze.Stat.Causal.*)
| Feature |
Module |
Usage |
Theory |
| LiNGAM causal discovery (DirectLiNGAM / ICA-LiNGAM / Pairwise / VAR-LiNGAM / MultiGroup / ParceLiNGAM + bootstrap edge confidence) |
Hanalyze.Model.LiNGAM.* |
api-guide/08-causal.md |
β |
| Treatment effects (propensity score / IPW / doubly robust AIPW / CATE S-T-X meta-learners) |
Hanalyze.Stat.Causal.* |
causal/usage-causal.md |
β |
Bayesian (Hanalyze.MCMC.* / Hanalyze.Stat.* / Hanalyze.Model.HBM)
| Feature |
Module |
Usage |
Theory |
| 27 probability distributions (Truncated/Censored/MvNormal/LKJ/Multinomial/...) |
Hanalyze.Stat.Distribution |
bayesian/01-distributions.md |
bayesian/theory-distributions.md |
Probabilistic model DSL (HBM polymorphic free monad, incl. deterministic / dataNamed) |
Hanalyze.Model.HBM |
bayesian/02-probabilistic-model.md |
principles/hbm.md |
| MCMC samplers (MH / HMC / NUTS / Slice / tempered SMC) |
Hanalyze.MCMC.{MH,HMC,NUTS,Slice,SMC} |
bayesian/03-mcmc-samplers.md |
bayesian/theory-mcmc.md / theory-hmc-nuts.md |
Sampling progress display (aggregate one-liner; IO verb df |->! spec, bit-identical to the pure verb) |
Hanalyze.MCMC.Progress |
io/04-fit-api.md |
β |
| Gibbs sampling (auto-conjugate detection + hybrid) |
Hanalyze.MCMC.Gibbs |
bayesian/04-gibbs.md |
bayesian/theory-mcmc.md |
| Variational inference (ADVI mean-field Adam) |
Hanalyze.Stat.VI |
bayesian/05-vi.md |
bayesian/theory-advanced.md |
| Model comparison (WAIC / PSIS-LOO / Pseudo-BMA) |
Hanalyze.Stat.ModelSelect |
bayesian/06-model-comparison.md |
bayesian/theory-bayesian-basics.md |
| Posterior predictive checks; selected PyMC-style modelling features |
Hanalyze.Stat.PosteriorPredictive |
02-pymc-comparison.md |
β |
| Marginal likelihood (bridge sampling) / Bayes factors / Bayesian model averaging |
Hanalyze.Stat.{BridgeSampling,BayesFactor,BayesianModelAveraging} |
β |
β |
| Bayesian A/B test (mean difference via NUTS + ROPE/HDI decision) |
Hanalyze.MCMC.BayesianTest |
β |
β |
Chain diagnostics (RΜ, ESS incl. arviz-compatible essBulk, HDI, BFMI, rank histogram, KDE, autocorrelation) |
Hanalyze.Stat.MCMC |
bayesian/viz-diagnostics.md |
β |
Optimisation (Hanalyze.Optim.*)
Design of experiments (Hanalyze.Design.*)
| Feature |
Module |
Usage |
Theory |
| DoE (Factorial / Block / Mixed / RSM / Optimal / Power / Quality) |
Hanalyze.Design.{Factorial,Block,Mixed,RSM,Optimal,Power,Quality,MultiRSM,Anova} |
doe/01-doe.md |
doe/theory-doe.md |
| Orthogonal arrays (L4/L8/L9/L12/L16/L18) + Taguchi (S/N + inner/outer) + process capability (Cp/Cpk) |
Hanalyze.Design.{Orthogonal,Taguchi,Quality} |
doe/02-orthogonal-taguchi.md |
doe/theory-doe.md |
| Custom optimal design (coordinate exchange + modified Fedorov: D/A/G/I criteria, Bayesian D, linear constraints, split-plot, augment menus, design comparison via efficiency/FDS/alias) |
Hanalyze.Design.Custom.* |
doe/usage-custom-design.md + manual |
β |
DOE workflow layer (R-style interactive Design object over the low-level design functions) |
Hanalyze.Design.Workflow |
api-guide/09-doe.md |
β |
Visualisation (Hanalyze.Viz.*)
| Feature |
Module |
Usage |
| Scatter / bar / histograms / MCMC diagnostics / GP plot / Pareto plot |
Hanalyze.Viz.{Scatter,Bar,Histogram,MCMC,GP,Pareto,ModelGraph,Taguchi} |
visualization/01-visualization.md |
| Integrated HTML report (MathJax + Mermaid + interactive) |
Hanalyze.Viz.ReportBuilder |
visualization/02-report-builder.md |
Unified fit-and-plot operator df |-> spec (one entry point across LM/GLM/GAM/GP/HBM/... specs) + plot-free coefficient diagnostics |
Hanalyze.Fit / Hanalyze.Diagnostics |
io/04-fit-api.md |
hgg integration (experimental): toPlot/Plottable overlays a fitted model (LM line+CI / GP mean+credible band) on the layer grammar; module Hanalyze quickstart entry. Flag-gated (plot-integration, default off). |
Hanalyze.Plot + module Hanalyze |
visualization/03-plot-integration.md |
| HBM ModelGraph (3 routes): Mermaid HTML / Graphviz DOT / direct SVG via hgg |
Hanalyze.Viz.{ModelGraph,ModelGraphDot} + Hgg.Plot.Bridge.Analyze |
see "ModelGraph β 3 routes" below |
ModelGraph β 3 routes
There are three ways to visualise the DAG of an HBM model; pick by use case:
| Route |
Module |
Output / Deps |
When to use |
| Mermaid HTML |
Hanalyze.Viz.ModelGraph.renderModelGraph |
.html + Mermaid CDN script |
GitHub / GitLab READMEs, notebook attachments β auto-rendered on GitHub |
| Graphviz DOT |
Hanalyze.Viz.ModelGraphDot.renderModelGraphDot |
.dot text + dot CLI (install required) |
graphviz ecosystem interop (xdot / gephi / dot -Tpng), fine-grained directives (rank=same / constraint=false etc) |
| hgg direct |
Hgg.Plot.Bridge.Analyze.renderModelGraphSVG (hgg-analyze-bridge) |
.svg (zero deps, pure Haskell) |
production app embedding, offline batch, fast rendering of large DAGs |
All three routes take the same Hanalyze.Model.HBM.ModelGraph as input. Layout
quality vs dependency trade-off:
- Mermaid: lightweight, but no offline rendering
- Graphviz DOT: best layout quality, but requires the
dot CLI
- hgg: intermediate quality (roughly 70-80% of graphviz dot, pure Haskell); the only option when zero dependencies are required
Code example (with hgg-analyze-bridge added as a dependency):
import qualified Hanalyze.Viz.ModelGraph as Mermaid
import qualified Hanalyze.Viz.ModelGraphDot as Dot
import qualified Data.Text.IO as TIO
import Hgg.Plot.Bridge.Analyze (renderModelGraphSVG)
import Hanalyze.Model.HBM (buildModelGraph)
main = do
let mg = buildModelGraph myHBM
Mermaid.renderModelGraph "out/dag.html" "My HBM" mg -- Route 1
TIO.writeFile "out/dag.dot" (Dot.renderModelGraphDot mg) -- Route 2
renderModelGraphSVG "out/dag.svg" "My HBM" mg -- Route 3
Note: for standard plots, hgg also ships native PNG (Rasterific) and PDF
backends. For the ModelGraph SVG route, convert via rsvg-convert / inkscape
when PNG / PDF is needed.
Data I/O (Hanalyze.DataIO.*)
| Feature |
Module |
Usage |
CSV/TSV/SSV (cassava) + Parquet/JSON (Hackage dataframe) |
Hanalyze.DataIO.{CSV,External,Convert} |
io/01-dirty-data.md |
| Dirty-data defence (W001-W008 warnings + auto-sniff + clean DSL) |
Hanalyze.DataIO.{Health,Sniff,Clean,Log} |
io/01-dirty-data.md |
| Reshape (pivot_wider / one-hot / lag-lead / rolling window) |
Hanalyze.DataIO.Reshape |
io/02-reshape.md |
| Preprocessing (impute / groupBy / derived columns / melt) |
Hanalyze.DataIO.Preprocess |
io/01-dirty-data.md |
Long-form regrid (regridLong) |
Hanalyze.DataIO.Preprocess + Hanalyze.Stat.Interpolate |
io/03-regrid.md |
Quick start
30 seconds via CLI
git clone https://github.com/frenzieddoll/hanalyze
cd hanalyze
cabal build all
# Regress sales on price + promo, write an HTML report.
hanalyze regress data/readme/sales.csv "price promo" sales --report sales.html
# Ξ²β=185.05 Ξ²(price)=-4.37 Ξ²(promo)=+32.29 RΒ²=0.995
data/readme/sales.csv is a 20-row demo CSV shipped with the repository
(price, promo, sales). The generated sales.html includes coefficients,
fit diagnostics, and an interactive prediction widget β straight from one
command.
30 seconds via Haskell API
import qualified Hanalyze.Stat.Test as ST
import qualified Numeric.LinearAlgebra as LA
main = do
let xs = LA.fromList [12, 14, 13, 15, 17, 11]
ys = LA.fromList [18, 22, 20, 19, 25, 17]
result = ST.tTestWelch xs ys ST.TwoSided
print (ST.trPValue result, ST.trEffect result)
-- (0.012, Just ("Cohen's d", -1.85))
A single import Hanalyze re-exports the core entry points (linear / GLM models,
descriptive stats, tests, effect sizes, distributions, plotting helpers and CSV
I/O) for quick exploration; reach for the individual Hanalyze.Model.* /
Hanalyze.Stat.* modules when you need their full surface.
See docs/01-quickstart.md for a fuller introduction.
CLI
hanalyze help list subcommands
hanalyze regress <file> <x> <y> LM/GLM/GP/HBM regression + HTML report
hanalyze info <file> per-column type/statistics
hanalyze hist <file> <col> histogram with theoretical PDF overlay
hanalyze ridge <file> ... regularised regression (Ridge/Lasso/EN)
hanalyze kernel <file> ... kernel regression (NW/KR/RFF), multi-D inputs
hanalyze spline <file> ... spline regression
hanalyze multireg <file> ... multi-output regression + interactive HTML
hanalyze melt <file> ... long-form transform
hanalyze regrid <file> ... time-axis grid alignment
hanalyze doe ortho <NAME> -f ... orthogonal-array generation
hanalyze taguchi sn / analyze Taguchi method
hanalyze clean <file> --rule ... dirty-data cleaning
For per-command flags, run hanalyze <cmd> --help or see docs/01-quickstart.md.
Examples / demos
demo/ contains many demos (76 as of this release). Highlights:
| Demo |
Summary |
demo/regression/HBMRegressionDemo.hs |
HBM Bayesian linear regression with NUTS + HTML |
demo/regression/RFFDemo.hs |
Large-scale GP via Random Fourier Features |
demo/regression/RobustGPDemo.hs |
Robust GP with Student-t observation likelihood |
demo/doe-optim/NSGADemo.hs |
NSGA-II + Pareto on the ZDT suite |
demo/doe-optim/BayesOptDemo.hs |
BO on Branin / Hartmann6 |
demo/bayesian/HBMComparisonDemo.hs |
Compare HBMs with WAIC / LOO |
demo/bayesian/SimpsonParadoxDemo.hs |
Disentangle Simpson's paradox via hierarchical model |
demo/io/DirtyDataDemo.hs |
Auto-defend against 19 dirty CSV variants |
Run: dist-newstyle/build/x86_64-linux/ghc-9.6.7/hanalyze-0.2.0.0/x/<demo-name>/build/<demo-name>/<demo-name>.
Where hanalyze fits
Rather than a complete Python/R replacement, hanalyze targets specific
workflows where Haskell integration, single-binary CLI, and tight reporting
add value.
Strong fit
- Haskell-native pipelines that need stats/Bayes/optim without calling out to Python
- Single-binary CLI distribution (one
hanalyze binary, no Python venv)
- Dirty-CSV defence + cleaning + analysis in one workflow
- DoE / Taguchi / orthogonal arrays for manufacturing and process tuning
- HTML reports straight from the analysis (no separate templating step)
- Type-safe analysis pipelines that catch dtype/API mismatches early
Not a goal β keep using existing tools for
- Large-scale DataFrame work (pandas / polars / data.table)
- GPU deep learning (PyTorch / JAX)
- The full breadth of scikit-learn's mature model zoo
- The full Stan / PyMC MCMC diagnostics ecosystem
- The full expressive range of ggplot2
Comparison vs Python
R is included in the feature map only β no numerical bench against R has been run.
Numbers below come from bench/results/{haskell,python}/*.csv; see
bench/results/SUMMARY.md for the full table and
benchmark conditions (OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1,
single-thread, deterministic seeds).
| Domain |
Result in these benchmarks |
| Single-objective optim (DE/CMAES/L-BFGS/NM) |
Often faster than scipy in tested cases (Rosenbrock_2D/DE 134Γ, Ackley/CMAES 49Γ, Griewank/CMAES 54Γ). On Sphere_30D/L-BFGS the reported objective value is 8.1e-40 vs scipy 2.6e-11 in this run. |
| Multi-objective optim (NSGA-II) |
Comparable or favourable in the ZDT/DTLZ suite (DTLZ2_3 1.43Γ faster, ZDT1/2/3 within Β±5% of pymoo). HV/IGD figures match or slightly improve on pymoo in these runs. |
| Bayesian optim (BO) |
Comparable on Branin (1.15Γ); on Hartmann6 the best objective in this run was -3.07 vs skopt -2.77. |
| Simulated annealing (Tsallis SA) |
Comparable; Rastrigin_10D reaches 0.0 in this run (scipy dual_annealing reports 7.8e-14). |
| Classical regression (LM/Ridge/Lasso/GLMM) |
Comparable in tested cases; LME 30Γ faster than statsmodels in our LME run. |
| Large-scale GLM/Lasso (n β₯ 10k) |
Currently slower than sklearn (3-5Γ in tested cases) β sklearn's Cython inner loops dominate. |
| Kernel/GP |
Currently slower than sklearn (2.5-4.7Γ in tested cases). |
| Bayesian MCMC (NUTS/HMC) |
NUTS with ESS comparable to blackjax (mu: 839 vs 810) on the 8-schools benchmark; 7.4Γ faster than PyMC; 2.8Γ slower than blackjax (JAX-JIT advantage). |
| HBM (probabilistic programming) |
Polymorphic DSL with selected PyMC-style modelling features and selected distributions (Truncated/Censored/MvNormal/LKJ/...). |
| VI / WAIC / LOO |
ADVI 3.0Γ faster than numpyro SVI on a small logistic posterior; LOO 2.9Γ faster than arviz on (S=1000, N=200) log-lik matrix. |
| Hypothesis tests / bootstrap / k-fold |
Welch t-test 39Γ faster, KS 11Γ, k-fold split 2.2Γ faster than scipy/sklearn in tested cases. |
| Time series / Spline / GAM |
ARIMA 128Γ faster than statsmodels; Spline PCHIP comparable to scipy; GAM ~1.6Γ slower than pygam in tested cases. |
| Survival analysis (KM/Cox PH) |
Comparable to lifelines in tested cases (KM/CoxPH). |
| Multi-output regression / Regrid |
MultiLM 2.3Γ faster than sklearn; regridLong 20Γ faster than a hand-written pandas+scipy synthesis. |
| Visualisation |
Vega-Lite specs via hvega (grammar-of-graphics-style); HTML reports built-in. |
See docs/comparison/python-r.md for the feature map, and bench/results/SUMMARY.md for numbers.
Benchmark highlights
Selected results from bench/results/SUMMARY.md. Each entry is a single
benchmark configuration; absolute objective values depend on iteration
counts, seeds, and tolerances β see the SUMMARY for full conditions.
NUTS is additionally validated against posteriordb reference posteriors
(see bench/posteriordb/).
- NUTS 8-schools (warmup 500, samples 1000): hanalyze 1492 ms with ESS(mu) 839 vs blackjax 530 ms / ESS 810 in this run
- Holt-Winters seasonal n=500 p=12: hanalyze 0.19 ms vs statsmodels MLE 96 ms in this run (note: hanalyze uses fixed Ξ±=0.3 closed-form; statsmodels does MLE)
- Sphere_30D/DE: hanalyze 1.0e-26 vs scipy 2.8e-5 on this benchmark
- Sphere_30D/L-BFGS: hanalyze 8.1e-40 vs scipy 2.6e-11 on this benchmark
- Rastrigin_10D/SA: hanalyze 0.0 vs scipy
dual_annealing 7.8e-14 in this run
- Hartmann6/BO: hanalyze -3.07 vs skopt -2.77 in this run
- DTLZ2_3/NSGA-II: hanalyze 528 ms vs pymoo 758 ms (1.43Γ faster in this run)
- DE Rosenbrock_2D: hanalyze 1.2 ms vs scipy 164 ms (134Γ faster in this run)
- Constrained Quad2D (eq): hanalyze 0.062 ms vs scipy SLSQP 0.69 ms in this run
- regridLong on jagged long-form: hanalyze 0.99 ms vs pandas+scipy synthesis 19.4 ms in this run
Reproduce: OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 cabal run bench-{regression,kernel,optim,mo,bo,mcmc-b7,mcmc-extras,ts-extras,optim-plus,stat-util,multi-output,regrid}, then bench/python/bench_*.py (see bench/README.md).
Architecture
graph TD
IO[DataIO.* CSV/Parquet/JSON]
IO --> DF[Hackage dataframe]
DF --> Models[Model.* regression/ML/Bayesian/TS/Survival]
DF --> Stat[Stat.* tests/CV/effect/interpret]
Models --> Optim[Optim.* optimisation]
Models --> MCMC[MCMC.* samplers]
Models --> Viz[Viz.* HTML/PNG/SVG]
Stat --> Viz
MCMC --> Viz
Optim --> Design[Design.* DoE/Taguchi]
All modules talk to Hackage dataframe directly. The internal DataFrame.Core was retired.
Roadmap & API stability
- Stable (API expected to remain backward-compatible within minor versions):
Hanalyze.DataIO.*, Hanalyze.Stat.{Test, Bootstrap, MultipleTesting, ClassMetrics, CV, Effect, Distribution}, Hanalyze.Model.{LM, GLM, Spline, Regularized, RandomForest, DecisionTree, TimeSeries, Survival, GAM}, Hanalyze.Optim.{NelderMead, LBFGS, DifferentialEvolution, CMAES, NSGA, BayesOpt, SimulatedAnnealing, ParticleSwarm}, Hanalyze.Design.*, Hanalyze.Viz.{Scatter, Bar, Histogram}.
- Experimental (API may evolve):
Hanalyze.Model.HBM DSL, Hanalyze.MCMC.NUTS (mass-matrix adaptation is opt-in), Hanalyze.Stat.VI (ADVI), Hanalyze.Model.{GP, RFF, GPRobust, GLMM}, Hanalyze.Model.{SVM, GradientBoosting, NeuralNetwork}, Hanalyze.Model.LiNGAM.*, Hanalyze.Design.Custom.*, the df |-> spec fit operator (Hanalyze.Fit), the hgg integration (plot-integration flag), Hanalyze.Viz.ReportBuilder. Behaviour is benchmarked but type signatures may shift.
- Future direction: a backend-abstraction typeclass for swapping hmatrix/Massiv/Accelerate is under consideration but not on a fixed schedule. (The unified top-level re-export layer and the fit-operator API planned earlier landed in 0.2.0.0 as
module Hanalyze and Hanalyze.Fit.)
Module layout
src/
DataIO/ β CSV/JSON/Parquet IO + health checks + sniff + clean DSL + reshape (9 mods)
Stat/ β tests/distributions/effect/CV/bootstrap/interpret/causal/MCMC diagnostics (33 mods)
Model/ β LM/GLM/GLMM/GP/HBM/SVM/GBM/NN/Cluster/TS/Survival/LiNGAM/FDA etc. (75 mods)
Optim/ β single-obj (NM/LBFGS/DE/CMAES/SA/PSO) + multi-obj (NSGA/BO/Pareto) (18 mods)
Design/ β Factorial/Block/RSM/Orthogonal/Taguchi + Custom optimal design (30 mods)
Viz/ β Vega-Lite-based visualisation + ReportBuilder (19 mods)
MCMC/ β MH/HMC/NUTS/Gibbs/Slice/SMC + progress (9 mods)
Math/ Data/ Plot/ + Fit/Diagnostics β numeric kernels, data helpers, hgg integration, fit operator
As of this release: 212 modules, ~1,390 test examples.
Build
cabal build all # library + all executables (76 demos)
cabal test # hspec test suite
cabal repl # interactive REPL
Major dependencies: hmatrix (BLAS/LAPACK), hvega (Vega-Lite), statistics, mwc-random, dataframe (Hackage Polars-like), massiv (parallel arrays), ad (auto-diff), async.
Tested on GHC 9.6.7 + cabal 3.14.2.
Running benchmarks
# 1. Generate shared test data (fixed-seed, deterministic)
cabal run bench-data-gen
# 2. Haskell side
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 \
cabal run bench-regression bench-kernel bench-optim bench-mo bench-bo
# 3. Python side (need bench/venv from bench/requirements.txt)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 \
bench/venv/bin/python bench/python/bench_regression.py
# (similarly for kernel, optim, mo, bo)
# 4. Aggregate (Markdown table)
bench/venv/bin/python bench/aggregate.py > bench/results/SUMMARY.md
Development
- Issues / PRs: github.com/frenzieddoll/hanalyze
- Adding tests: append hspec specs in
test/Spec.hs
- Adding benchmarks: place
bench/haskell/Bench*.hs and matching Python script
- Coding rules: see
CONTRIBUTING.md (no list-passing on hot paths, minimise unsafe*, ...)
License
BSD-3-Clause License β see LICENSE.
Author
Toshiaki Honda frenzieddoll@gmail.com