Benchmarks and verification
Probit regression verification record
The executed comparison fits identical observations in base R glm(), statsmodels GLM, and PHP fit_probit(). The saved report records versions, complete outputs, maximum differences from R, warnings and retained-row metadata.
Reference cases and conventions
Six saved R fixtures cover the simulated learning sample, a single predictor, multiple predictors, no intercept, intercept only, correlated full-rank columns and imbalanced outcomes (the main sample is the multiple-predictor case). The three-way comparison adds listwise deletion of two rows. All coefficients, covariance entries, standard errors, normal z tests and p-values, Wald confidence limits, full fitted probabilities and response residuals, likelihood, deviance, null deviance, AIC and residual df are checked. Numerical tolerance is 1e-9 + 1e-7 × abs(reference); sample accounting is exact.
R uses confint.default(fit), not profile-likelihood confint(fit). Its fitting tolerance is 1e-16 to make covariance evaluated at the preceding IRLS iterate negligible. Iteration counts can differ across implementations; they are not a reference equality requirement. Without a ones column the null baseline is probability 0.5; the Python runner computes this convention explicitly.
Failure and integration checks
Rust/PHP tests reject insufficient observations, invalid shapes, nonfinite or nonbinary outcomes, one-class samples, dependent columns, and selected complete and quasi-separated designs. They check scaled predictor units, stable arithmetic at extreme logits, iteration exhaustion, missing-row warnings and alignment. OLS integration tests also run after changes to the shared PHP conversion code. No penalties or Firth correction are supplied. The separation check is not an exhaustive LP detector, and Wald inference can be poor with sparse or near-separated samples. Linux and PHP-FPM deployment have not been exercised by these reports.
Reproduce
From the repository root with matching PHP development tools:
export PHP=/opt/homebrew/bin/php
export PHP_CONFIG=/opt/homebrew/bin/php-config
cargo test --workspace --locked
cargo build -p phit --locked
php -n -d "extension=$PWD/target/debug/libphit.dylib" tests/probit.php
.context/notebooks-venv/bin/python docs/verifications/compare_probit.py
QUARTO_PYTHON="$PWD/.context/notebooks-venv/bin/python" quarto render docs/notebooks/probit-verification.qmdUse .so on Linux. R fixture regeneration is an explicit development step: Rscript tests/generate-probit-poisson-fixtures.R. Ordinary Rust/PHP tests use saved fixtures without R or Python. See development for setup and large-sample benchmarks for additional evidence.
The covariance convention is inverse expected Fisher information; use statsmodels GLM Binomial(Probit), rather than discrete Probit observed-Hessian covariance.
From phpstats/phit@76b22f0.