Skip to main content

pybhatlib

PyPI Python Tests License: MIT

Open-source Python library for matrix-based econometric inference: multivariate normal CDF evaluation with analytic gradients, and maximum-likelihood estimation of discrete-choice models (MNP, MORP, MDCEV, MNL).

The numerical core follows the GAUSS BHATLIB library by Chandra Bhat and colleagues (UT Austin / Aptech Systems) and implements Bhat's (2018) analytic MVNCD approximation.

Installation

pip install pybhatlib                  # core (NumPy + SciPy + Numba)
pip install "pybhatlib[torch]"         # add PyTorch backend (optional GPU)

From source (for development, or to run the bundled examples and tutorials):

git clone https://github.com/UMN-Choi-Lab/pybhatlib.git
cd pybhatlib
pip install -e .                  # core (NumPy + SciPy + Numba)
pip install -e ".[torch]"         # add PyTorch backend (optional GPU)
pip install -e ".[dev]"           # add pytest, ruff, mypy
pip install -e ".[all]"           # everything (torch + dev)

Quick Start — Multinomial Probit (MNP)

Sample data: examples/data/TRAVELMODE.csv (3 modes — DA / SR / TR, 1125 observations).

from pybhatlib.models.mnp import MNPModel, MNPControl

model = MNPModel(
    data="examples/data/TRAVELMODE.csv",
    alternatives=["Alt1_ch", "Alt2_ch", "Alt3_ch"],
    availability="none",
    spec={
        "CON_SR": {"Alt1_ch": "sero", "Alt2_ch": "uno",     "Alt3_ch": "sero"},
        "CON_TR": {"Alt1_ch": "sero", "Alt2_ch": "sero",    "Alt3_ch": "uno"},
        "IVTT":   {"Alt1_ch": "IVTT_DA", "Alt2_ch": "IVTT_SR", "Alt3_ch": "IVTT_TR"},
        "OVTT":   {"Alt1_ch": "OVTT_DA", "Alt2_ch": "OVTT_SR", "Alt3_ch": "OVTT_TR"},
        "COST":   {"Alt1_ch": "COST_DA", "Alt2_ch": "COST_SR", "Alt3_ch": "COST_TR"},
    },
    control=MNPControl(iid=True),
)
results = model.fit()
results.summary()

Quick Start — Multivariate Ordered Response Probit (MORP)

from pybhatlib.models.morp import MORPModel, MORPControl

model = MORPModel(
    data=df,                                     # DataFrame or CSV path
    dep_vars=["satisfaction", "recommendation"], # ordinal outcome columns
    spec={
        "income":    {"satisfaction": "income",    "recommendation": "income"},
        "age":       {"satisfaction": "age",       "recommendation": "age"},
        "education": {"satisfaction": "education", "recommendation": "education"},
    },
    n_categories=[3, 3],
    control=MORPControl(iid=True, seed=42),
)
results = model.fit()
results.summary()

A runnable end-to-end example (with morp_ate, morp_predict, morp_predict_category) is at examples/tutorials/t05b_morp_ate_predict.ipynb.

Features

Models

  • Multinomial Probit (MNP) — IID, flexible covariance, heteroscedastic-only, random coefficients, mixture-of-normals
  • Multivariate Ordered Response Probit (MORP) — multiple ordinal outcomes with shared covariance; per-outcome spec mapping
  • Multiple Discrete-Continuous Extreme Value (MDCEV) — traditional (Bhat 2008) and linear outside-good utility specifications, selected via MDCEVControl.utility
  • Multinomial Logit (MNL)
  • Linear regression (LR) — single continuous outcome, closed-form OLS with classical / White-robust / BHHH standard errors
  • Mixed / simulation-based models — MixMNLModel, MNPKerCPModel, MORPFlexModel, MDCEVMixedModel on a shared maximum-simulated-likelihood engine (Halton draws, panel data, normal / log-normal / Yeo-Johnson coefficient transforms). New and under active refinement.

Numerical core

  • vecup — vecdup, matdupfull, LDLT decomposition, truncated MVN moments
  • matgradient — gradcovcor, gomegxomegax, spherical / Cholesky parameterizations
  • gradmvn — Bhat (2018) MVNCD analytic approximation with analytic gradients

Estimation

  • Multiple SE estimators (se_method="bhhh" | "hessian" | "sandwich"); BHHH is the default to match GAUSS BHATLIB's _max_CovPar=2. All three are computed at fit time and exposed as se_bhhh / se_hessian / se_sandwich; results.summary() prints a side-by-side diagnostic block (a large Hessian/BHHH divergence is a misspecification signal).
  • MNPControl.active_mask to freeze a subset of parameters at their starting values without recoding the model.
  • verbose levels: 0 silent, 1 summary, 2 per-iteration NLL, 3 per-iteration parameter / gradient / relative-gradient table.

Backend

  • NumPy by default; optional PyTorch backend with GPU support (install with [torch]). All numerical functions take an optional xp kwarg.

Post-estimation

  • Average Treatment Effects (ATE) with scenario-matrix support, forecasting, per-category MORP probability prediction.
  • MORP ATEs from supplied coefficients without re-fitting: MORPResults.from_estimates(beta, thresholds, correlation) rebuilds a results object from natural-space estimates, and morp_ate_from_params / morp_joint_probs (mean joint category-combination probabilities, the GAUSS ate1.csv equivalent) compute effects directly from them.

Verification

pybhatlib reproduces Table 1 of the BHATLIB GAUSS reference implementation using the TRAVELMODE dataset (3 modes — DA, SR, TR; 1125 observations):

Model Specification Target LL Achieved LL Status
(a)(i) IID errors -670.956 -670.956 exact match
(a)(ii) Flexible covariance -661.111 -661.111 exact match
(b) + AGE45 demographics -659.285 -659.284 exact match
(c) + Random coeff. OVTT -635.871 -635.871 exact match
(d) 2-segment mixture -634.975 -632.912 close (multi-modal)

Models (a)–(c) reproduce the GAUSS estimates and BHHH standard errors to ≤0.001 on every parameter (verified end-to-end against GAUSS 26.1.1 + MaxLik 5.0.9). Model (d) is multi-modal — the Python optimum is a slightly better local mode than the GAUSS one.

For MORP, iid=False now uses GAUSS BHATLIB's unit-variance identification by default (MORPControl.fix_scales=True): the latent-utility variances are fixed at 1 and only correlations are estimated. The full-covariance MORP_DINING / MORP_WALK models reproduce the GAUSS mean log-likelihoods (−4.6598 / −3.7591) and correlation matrices. summary() reports the actual threshold cut-points (with delta-method standard errors) and a gradient column, matching GAUSS's output. See docs/plans/MORP_BHATLIB_PARITY.md.

The driving notebooks are t04h_bhatlib_table1.ipynb and t04i_bhat2018_table2.ipynb.

Tutorials

A complete tutorial series lives under examples/tutorials/ as Jupyter notebooks (each with a matching .py script under python_scripts/):

Track Notebooks
Foundations t00_quickstart, t01a_vectorization, t01b_ldlt, t01c_truncated_mvn
Matrix gradients t02a_gradcovcor, t02b_spherical, t02c_chain_rules
MVNCD t03a_mvncd_methods, t03b_mvncd_gradients, t03c_mvncd_rect, t03d_univariate_cdfs, t03e_bhat2018_table1
MNP t04a_mnp_iid … t04g_mnp_forecasting, t04h_bhatlib_table1, t04i_bhat2018_table2
MORP t05b_morp_ate_predict
MDCEV t07a_mdcev_trad, t07b_mdcev_lin
MNL t08a_mnl
LR t09a_lr
Backends & verification t06a_backend_switching, t06b_custom_specs, t06c_gradient_verification

Contributing

See CONTRIBUTING.md for development setup, the PR-test workflow, and CODEOWNERS conventions. Key tests:

pytest tests/                 # full suite
pytest tests/ -m "not slow"   # skip integration tests
pytest tests/ -m torch        # PyTorch backend tests only

References

  1. Bhat, C. R. (2018). New Matrix-Based Methods for the Analytic Evaluation of the Multivariate Cumulative Normal Distribution Function. Transportation Research Part B, 109: 238–256.
  2. Bhat, C. R. (2008). The Multiple Discrete-Continuous Extreme Value (MDCEV) Model: Role of Utility Function Parameters, Identification Considerations, and Model Extensions. Transportation Research Part B, 42(3): 274–303.

License

MIT

Metadata

Release files for pybhatlib 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pybhatlib 0.4.0
File Size Uploaded
pybhatlib-0.4.0.tar.gz 3.3 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for pybhatlib 0.4.0
File Interpreter ABI Platform
pybhatlib-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 3.7 MB

Release files / pybhatlib-0.4.0.tar.gz

Download URL pybhatlib-0.4.0.tar.gz
Size 3.3 MB
Tags Source
SHA-256 checksum
How to use checksums
21a4b6e1e168f59e25a83053cce9a7aa3b2d1d7c1a43737c0c6672308f79b311
BLAKE2b-256 checksum
How to use checksums
9db18338669f8784df21d05c6cbbd0ef0bdd8595a06495b43816e8299db3c9bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.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 Sep 16, 2026.

Transparency log

Release files / pybhatlib-0.4.0-py3-none-any.whl

Download URL pybhatlib-0.4.0-py3-none-any.whl
Size 472.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6bdc0a59dfeb4fda216343337951977169f3b34c4366bd90e45dfa820c664af3
BLAKE2b-256 checksum
How to use checksums
1a40aaa9a21717b78b49820595a4493c156f32b5c3f1c905d2e21e27b46ccacb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.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 Sep 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page