CmdStanPHP

Other interfaces

Verification

Scope

Draws from identical CmdStan settings, and each interface's own summary: mean, standard deviation, 5% and 95% quantiles, R-hat, and bulk ESS for mu, tau, and theta.

References

Reference
cmdstanr 0.9.0 with posterior 1.7.0, and CmdStanPy 1.3.0 (summary at sig_figs 12), on CmdStan 2.40.0, R 4.6.2, Python 3.14.10, and PHP 8.5.12
Versions
CmdStan 2.40.0, CmdStanPHP v0.1.2-35-gccadda9, cmdstanr 0.9.0, posterior 1.7.0, cmdstanpy 1.3.0, R 4.6.2 (2026-10-29), Python 3.14.10, PHP 8.5.12

Data

Values
{"J":8,"y":[28,8,-3,7,-1,1,18,12],"sigma":[15,10,16,11,9,11,10,18]}
Arguments
chains 4; parallel chains 4; chain ids 1, 2, 3, 4; iter warmup 1000; iter sampling 1000; seed 20261101; init 2; other CmdStan's defaults for everything else, including NUTS with the diag_e metric, adapt_delta 0.8, max_treedepth 10, and the CSV output precision
Stan program
data {
  int<lower=0> J;
  array[J] real y;
  array[J] real<lower=0> sigma;
}
parameters {
  real mu;
  real<lower=0> tau;
  vector[J] theta_tilde;
}
transformed parameters {
  vector[J] theta = mu + tau * theta_tilde;
}
model {
  mu ~ normal(0, 5);
  tau ~ cauchy(0, 5);
  theta_tilde ~ normal(0, 1);
  y ~ normal(theta, sigma);
}

Method

The non-centered eight schools model (Rubin 1981) run through three CmdStan interfaces with the same CmdStan, data, seed, chain ids, and initialization. The draws are identical, and each interface summarizes them with its own code.

Check
Comparison with a reference implementation
Recorded
2026-11-01, PHP 8.5.12, Ubuntu 24.04.5 LTS (x86_64), commit ccadda9

Tolerances

|x − r| ≤ 1e-9 + 1e-9 × |r|

Applies to: Summary values

Larger error of cmdstanr and CmdStanPy

exact equality

Applies to: Draws

Every CSV column

x: package value; r: reference value. Absolute error: |x − r|. Max errors are over the values a row compares. cmdstanr, CmdStanPy: each implementation’s error against the same reference.

Results

61 comparisons in 11 cases: 61 pass, 0 fail, 0 skipped.

By case

Results by case
Case Comparisons Largest abs. error Status
mu 6 5.0e-10 pass
tau 6 1.7e-9 pass
theta[1] 6 1.7e-9 pass
theta[2] 6 2.7e-9 pass
theta[3] 6 1.2e-9 pass
theta[4] 6 4.2e-9 pass
theta[5] 6 1.6e-9 pass
theta[6] 6 4.2e-9 pass
theta[7] 6 4.2e-9 pass
theta[8] 6 1.4e-9 pass
draws 1 0 pass
All 61 comparisons
Every comparison
Case Quantity Criterion Values Max abs. error cmdstanr CmdStanPy Status
mu mean |x − r| ≤ 1e-9 + 1e-9 × |r| 2 2.6e-12 5.3e-15 2.6e-12 pass
sd |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.1e-12 2.7e-15 1.1e-12 pass
q5 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 0 0 0 pass
q95 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 0 0 0 pass
rhat |x − r| ≤ 1e-9 + 1e-9 × |r| 2 9.8e-13 3.3e-15 9.8e-13 pass
ess_bulk |x − r| ≤ 1e-9 + 1e-9 × |r| 2 5.0e-10 3.6e-12 5.0e-10 pass
tau mean |x − r| ≤ 1e-9 + 1e-9 × |r| 2 2.3e-12 4.9e-15 2.3e-12 pass
sd |x − r| ≤ 1e-9 + 1e-9 × |r| 2 7.6e-13 4.0e-15 7.6e-13 pass
q5 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 5.6e-17 5.6e-17 5.6e-17 pass
q95 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 3.6e-15 3.6e-15 3.6e-15 pass
rhat |x − r| ≤ 1e-9 + 1e-9 × |r| 2 3.6e-12 2.2e-16 3.6e-12 pass
ess_bulk |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.7e-9 2.3e-12 1.7e-9 pass
theta[1] mean |x − r| ≤ 1e-9 + 1e-9 × |r| 2 2.2e-12 0 2.2e-12 pass
sd |x − r| ≤ 1e-9 + 1e-9 × |r| 2 5.2e-13 4.4e-15 5.2e-13 pass
q5 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 2.2e-16 2.2e-16 2.2e-16 pass
q95 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 3.6e-15 3.6e-15 3.6e-15 pass
rhat |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.5e-12 3.1e-15 1.5e-12 pass
ess_bulk |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.7e-9 1.8e-12 1.7e-9 pass
theta[2] mean |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.9e-12 4.4e-15 1.9e-12 pass
sd |x − r| ≤ 1e-9 + 1e-9 × |r| 2 3.0e-12 2.7e-15 3.0e-12 pass
q5 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 0 0 0 pass
q95 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.8e-15 1.8e-15 1.8e-15 pass
rhat |x − r| ≤ 1e-9 + 1e-9 × |r| 2 3.9e-12 4.4e-15 3.9e-12 pass
ess_bulk |x − r| ≤ 1e-9 + 1e-9 × |r| 2 2.7e-9 6.4e-12 2.7e-9 pass
theta[3] mean |x − r| ≤ 1e-9 + 1e-9 × |r| 2 3.9e-12 0 3.9e-12 pass
sd |x − r| ≤ 1e-9 + 1e-9 × |r| 2 4.0e-12 4.4e-15 4.0e-12 pass
q5 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 8.9e-16 8.9e-16 8.9e-16 pass
q95 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.8e-15 1.8e-15 1.8e-15 pass
rhat |x − r| ≤ 1e-9 + 1e-9 × |r| 2 2.0e-12 3.6e-15 2.0e-12 pass
ess_bulk |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.2e-9 3.6e-12 1.2e-9 pass
theta[4] mean |x − r| ≤ 1e-9 + 1e-9 × |r| 2 3.5e-12 4.4e-15 3.5e-12 pass
sd |x − r| ≤ 1e-9 + 1e-9 × |r| 2 3.4e-12 2.7e-15 3.4e-12 pass
q5 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 8.9e-16 8.9e-16 8.9e-16 pass
q95 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 8.9e-15 8.9e-15 8.9e-15 pass
rhat |x − r| ≤ 1e-9 + 1e-9 × |r| 2 2.5e-12 2.2e-16 2.5e-12 pass
ess_bulk |x − r| ≤ 1e-9 + 1e-9 × |r| 2 4.2e-9 4.5e-12 4.2e-9 pass
theta[5] mean |x − r| ≤ 1e-9 + 1e-9 × |r| 2 7.0e-13 0 7.0e-13 pass
sd |x − r| ≤ 1e-9 + 1e-9 × |r| 2 4.4e-12 2.1e-14 4.4e-12 pass
q5 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 8.9e-16 8.9e-16 8.9e-16 pass
q95 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 7.1e-15 7.1e-15 7.1e-15 pass
rhat |x − r| ≤ 1e-9 + 1e-9 × |r| 2 4.4e-12 2.0e-15 4.4e-12 pass
ess_bulk |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.6e-9 2.7e-12 1.6e-9 pass
theta[6] mean |x − r| ≤ 1e-9 + 1e-9 × |r| 2 4.0e-13 4.4e-15 4.0e-13 pass
sd |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.3e-12 4.4e-15 1.3e-12 pass
q5 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 0 0 0 pass
q95 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.8e-15 1.8e-15 1.8e-15 pass
rhat |x − r| ≤ 1e-9 + 1e-9 × |r| 2 9.8e-13 0 9.8e-13 pass
ess_bulk |x − r| ≤ 1e-9 + 1e-9 × |r| 2 4.2e-9 2.3e-12 4.2e-9 pass
theta[7] mean |x − r| ≤ 1e-9 + 1e-9 × |r| 2 3.2e-12 0 3.2e-12 pass
sd |x − r| ≤ 1e-9 + 1e-9 × |r| 2 3.3e-12 1.8e-15 3.3e-12 pass
q5 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 0 0 0 pass
q95 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.8e-14 1.8e-14 1.8e-14 pass
rhat |x − r| ≤ 1e-9 + 1e-9 × |r| 2 3.3e-12 4.2e-15 3.3e-12 pass
ess_bulk |x − r| ≤ 1e-9 + 1e-9 × |r| 2 4.2e-9 2.7e-12 4.2e-9 pass
theta[8] mean |x − r| ≤ 1e-9 + 1e-9 × |r| 2 3.6e-12 4.4e-15 3.6e-12 pass
sd |x − r| ≤ 1e-9 + 1e-9 × |r| 2 2.8e-12 8.9e-16 2.8e-12 pass
q5 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 0 0 0 pass
q95 |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.2e-14 1.2e-14 1.2e-14 pass
rhat |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.5e-12 2.2e-16 1.5e-12 pass
ess_bulk |x − r| ≤ 1e-9 + 1e-9 × |r| 2 1.4e-9 2.7e-12 1.4e-9 pass
draws all CSV columns, 4 chains × 1,000 draws exact equality 100,000 0 0 0 pass

Posterior means by interface

  • CmdStanPHP: summary() with measures mean, sd, quantile2, rhat, and ess_bulk
  • cmdstanr: fit$summary() (posterior package): mean, sd, quantile 0.05 and 0.95, rhat, ess_bulk
  • CmdStanPy: fit.summary(percentiles=(5, 95)), which runs CmdStan's stansummary: Mean, StdDev, 5%, 95%, R_hat, ESS_bulk
Posterior means each interface reports, with the signed difference from CmdStanPHP
Variable CmdStanPHP cmdstanr CmdStanPy
mu 4.425178 4.425178 +5.3e-15 4.425180 +1.7e-6
tau 3.573274 3.573274 +4.9e-15 3.573270 −4.3e-6
theta[1] 6.126084 6.126084 0 6.126080 −3.8e-6
theta[2] 4.938544 4.938544 −4.4e-15 4.938540 −4.0e-6
theta[3] 4.021571 4.021571 0 4.021570 −1.1e-6
theta[4] 4.763724 4.763724 −4.4e-15 4.763720 −3.5e-6
theta[5] 3.656962 3.656962 0 3.656960 −1.9e-6
theta[6] 4.028958 4.028958 +4.4e-15 4.028960 +1.7e-6
theta[7] 6.386661 6.386661 0 6.386660 −9.4e-7
theta[8] 4.983219 4.983219 +4.4e-15 4.983220 +9.8e-7

Values to six decimal places; the signed number is the difference from CmdStanPHP's unrounded mean.

Draws

Largest difference between the draws of each pair of interfaces
InterfacesDrawsColumnsMax abs. difference
CmdStanPHP and cmdstanr 4,000 25 0
CmdStanPHP and CmdStanPy 4,000 25 0
cmdstanr and CmdStanPy 4,000 25 0

Summaries

Largest absolute difference between the summaries of each pair of interfaces, by measure
Interfaces meansdq5q95rhatess_bulk
CmdStanPHP and cmdstanr 5.3e-152.1e-148.9e-161.8e-144.4e-156.4e-12
CmdStanPHP and CmdStanPy 4.3e-63.9e-64.2e-64.8e-54.6e-65.0e-3
cmdstanr and CmdStanPy 4.3e-63.9e-64.2e-64.8e-54.6e-65.0e-3

CmdStanPHP's and cmdstanr's summaries agree to rounding error in double precision. CmdStanPy's summary() rounds stansummary's output to 6 significant figures by default, which accounts for its differences. With summary(sig_figs=12), its largest differences are those in summary_differences_cmdstanpy_sig_figs_12.

Limitations

Known differences

  • CmdStanPy's summary() rounds stansummary's output to 6 significant figures by default, so its summary is compared at sig_figs 12.

Reproduction

From the repository root
verification/interfaces/run.sh
Raw record
site/verifications/interfaces.json
Full results
verification/interfaces