Validation dashboard#
Every estimator in mlsynth is checked against the original authors’ code on real data. This page is generated from the pinned reference bundles the test suite asserts against, so the numbers here cannot drift from what CI enforces. Each row links to the reference implementation, the dataset (with checksum), and the mlsynth case that runs the check.
Coverage: 85 cross-validation checks against original implementations across 44 estimators – 32 reproduce the reference to display precision, 29 to within two percent. A further 4 are captured on the next daily run (see Pending capture). Per-estimator paper replications (Path A / Path B) are catalogued in Replications.
Legend: exact (agreement to display precision), tight (worst relative deviation \(\le 2\%\)), close (\(\le 10\%\)), and documented (looser, with a stated reason on the estimator’s replication page – typically an intrinsically extrapolated or weakly-identified quantity).
Summary#
Estimator |
Checks |
Agreement |
Worst max |Δ| |
|---|---|---|---|
2 |
1 tight · 1 documented |
9e+03 |
|
1 |
1 tight |
0.15 |
|
1 |
1 close |
1 |
|
1 |
1 tight |
0.00041 |
|
5 |
4 exact · 1 tight |
0.036 |
|
2 |
1 exact · 1 tight |
0.047 |
|
1 |
1 tight |
0.014 |
|
1 |
1 exact |
0 |
|
1 |
1 exact |
0 |
|
1 |
1 tight |
0.01 |
|
1 |
1 exact |
0.00032 |
|
1 |
1 close |
0.71 |
|
2 |
1 tight · 1 close |
0.39 |
|
1 |
1 tight |
0.016 |
|
1 |
1 exact |
4.6e-05 |
|
1 |
1 tight |
0.81 |
|
1 |
1 exact |
1e-06 |
|
1 |
1 close |
0.03 |
|
1 |
1 tight |
20 |
|
2 |
1 tight · 1 documented |
1e+02 |
|
1 |
1 close |
1.9 |
|
2 |
1 exact · 1 close |
0.037 |
|
5 |
4 exact · 1 close |
0.056 |
|
2 |
1 tight · 1 documented |
3 |
|
1 |
1 exact |
0 |
|
3 |
1 exact · 2 tight |
41 |
|
2 |
2 tight |
0.0013 |
|
1 |
1 exact |
0 |
|
1 |
1 exact |
0 |
|
2 |
1 close · 1 documented |
1e+06 |
|
1 |
1 exact |
0 |
|
1 |
1 tight |
0.011 |
|
1 |
1 tight |
0.14 |
|
1 |
1 tight |
0.0016 |
|
1 |
1 exact |
0 |
|
1 |
1 exact |
0 |
|
4 |
1 exact · 1 close · 2 documented |
3.7e+02 |
|
2 |
2 exact |
0.0007 |
|
1 |
1 tight |
0.001 |
|
2 |
1 exact · 1 close |
0.094 |
|
1 |
1 documented |
25 |
|
1 |
1 tight |
0.0004 |
|
19 |
5 exact · 7 tight · 6 close · 1 documented |
4.1 |
|
1 |
1 exact |
0 |
?#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
— |
14 |
0.028 |
tight |
||
R package tidysynth 0.2.0 (live run); the authors’ published numbers come from tidysynth <= 0.1.0 and are recorded in docs/replications/lamba_tigers.rst rather than pinned |
|
9 |
9e+03 |
documented — see notes |
BEAST#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
jeremylhour/alternative-synthetic-control-sparsity R (CalibrationLasso/OrthogonalityReg/ImmunizedATT) |
|
13 |
0.15 |
tight |
BFSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
author appendix Stan (via Rscript + rstan) |
— |
3 |
1 |
close |
BVSS#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
authors’ two-coordinate Gibbs (example2_fspda_2.R primitives), live run, captured |
|
6 |
0.00041 |
tight |
CLUSTERSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
SucreRouge/synth_control learn(method=’bayesian’) (live run, captured), num_sv=3 |
|
8 |
0 |
exact — matches to display precision |
|
Bayani RPCA-SC – the author’s own code, vendored verbatim (vendor/bayani_rpca_synth: FPCA.R + RPCA_2.py) |
— |
9 |
0 |
exact — matches to display precision |
|
jehangiramjad/tslib RobustSyntheticControl (live run, captured), modelType=’svd’, kSingularValuesToKeep=3 |
|
8 |
0.036 |
tight |
|
deshen24/panel-data-regressions var.var_est (homoskedastic + jackknife) |
— |
6 |
0 |
exact — matches to display precision |
|
scpi_pkg scest(w_constr={‘name’:’ridge’}) + df_EST |
|
3 |
0 |
exact — matches to display precision |
COMPSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
Boussim (2026) published tables (no replication package released) |
— |
34 |
0.047 |
tight |
|
Boussim (2026) csc_replication.R (quadprog::solve.QP on the stacked ALR log-odds), run live on basedata/pa_aeps_generation.csv |
|
23 |
0 |
exact — matches to display precision |
CSCM#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
Bonander CSCM_helper_functions.R (OSF osf.io/uvt5p, live run, captured) |
— |
4 |
0.014 |
tight |
DPSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
srho1/dpsc PrivateSC (differentially private SC) |
— |
4 |
0 |
exact — matches to display precision |
DROSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
authors’ helpers.R sc() + DRoSC() (limSolve::lsei, live via Rscript) |
— |
10 |
0 |
exact — matches to display precision |
DSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
Davidvandijcke/DiSCos DiSCo(), mean of 40 seeds at M = 10,000 (the package’s runif quadrature makes a single run a Monte Carlo draw) |
|
66 |
0.01 |
tight |
FDID#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
Kathleen T. Li’s Fun_FDID.R (MKSC replication, live run, captured) |
|
7 |
0.00032 |
exact — matches to display precision |
GEOX#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
mlsynth SDID (the engine GEOX wraps) |
— |
3 |
0.71 |
close |
LINF#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
LinfinitySC our(method=’inf’|’l1-inf’) (Wang, Xing & Ye 2025), BioAlgs/LinfinitySC |
— |
40 |
0.00041 |
tight |
|
LinfinitySC our(method=’inf’) (Wang, Xing & Ye 2025), BioAlgs/LinfinitySC, lambda via param_selector(method=’inf’, n_folds=10) |
|
43 |
0.39 |
close |
MAREX#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
jinglongzhao2/SCDesign (cardinality-K design, open quadprog, live run) |
|
7 |
0.016 |
tight |
MASC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
maxkllgg/masc masc(…, nogurobi=TRUE) (LowRankQP), live run, captured |
|
8 |
4.6e-05 |
exact — matches to display precision |
MCNNM#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
|
13 |
0.81 |
tight |
MLSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
leabottmer/multi-level-sc-estimator (mlSC_estimator, cvxpy+SCS) |
— |
4 |
1e-06 |
exact — matches to display precision |
MTGP#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
replication-package Stan (via Rscript + rstan) |
— |
3 |
0.03 |
close |
MVBBSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
R package bsynth (bayesianSynth, predictor_match=FALSE, live run) |
|
4 |
20 |
tight |
MicroSynth#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
R microsynth (config A: match.out=trajectory) |
— |
56 |
1e+02 |
documented — see notes |
|
R package microsynth (via Rscript) |
— |
6 |
0.097 |
tight |
NSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
Tian (2023) NSC.R (vendored, live run, captured), a*=0.3, b*=0.7 |
|
23 |
1.9 |
close |
ORTHSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
Fry GMM-SCE.R GMMSC() (R, live run, captured) |
|
15 |
0.037 |
close |
|
Fry OrthogonalizedSyntheticControl (R, live run, captured) |
|
5 |
0 |
exact — matches to display precision |
PDA#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
Authors’ Fun/L2relax.R (ishwang1/L2relax-PDA), per UK firm, reproduced via cvxpy/ECOS, live run captured |
|
4 |
1e-06 |
exact — matches to display precision |
|
R package pampe (pampe(), live run, captured) |
|
6 |
3.6e-05 |
exact — matches to display precision |
|
Authors’ Fun/L2relax.R (ishwang1/L2relax-PDA) reproduced via cvxpy/ECOS, live run captured |
|
24 |
0 |
exact — matches to display precision |
|
Shi & Huang fsPDA application script (zhentaoshi/fsPDA, live run, captured) |
|
4 |
0.056 |
close |
|
Authors’ Fun/L2relax.R (ishwang1/L2relax-PDA) reproduced via cvxpy/ECOS, live run captured |
|
64 |
1e-06 |
exact — matches to display precision |
PPSCM#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
R augsynth::multisynth (live run, captured) |
|
49 |
0.0022 |
tight |
|
Ronczewski (2026) replication package, Results/csv/ |
— |
14 |
3 |
documented — see notes |
PROPSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
R package propsdid (via Rscript) |
— |
6 |
0 |
exact — matches to display precision |
PROXIMAL#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
R gmm (authors’ analysis.Rmd, commit 3bcb5ec, reltol=1e-13) |
— |
4 |
41 |
tight |
|
KenLi93/proximal_sc_manuscript NC_nocov + NC_nocov_gmm (over-identified, Newey-West q=10), live run, captured |
|
11 |
1e-06 |
exact — matches to display precision |
|
authors’ proximal code (freshtaste/proximal, cloned) |
— |
3 |
0.014 |
tight |
RESCM#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
scmrelax L2RelaxationCV (Liao-Shi-Zheng; github.com/metricshilab/scmrelax = github.com/YapengZheng/Relaxed_SC; MOSEK->CLARABEL; live run, captured) |
|
6 |
0.0013 |
tight |
|
scmrelax L2RelaxationCV (Liao-Shi-Zheng; github.com/metricshilab/scmrelax = github.com/YapengZheng/Relaxed_SC; MOSEK->CLARABEL; live run, captured) |
— |
10 |
0.00036 |
tight |
ROLLDID#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
lwdid.lwdid (Lee & Wooldridge DiD, live run, captured): prop99 common-timing (d, post, vce=None); castle staggered (gvar, control_group=’never_treated’, aggregate=’overall’, vce=None/hc3) |
|
9 |
0 |
exact — matches to display precision |
RRSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
reference R implementation of both RRSC regimes (fa.em + Huber-IRLS; stats::factanal + robustbase::ltsReg + Donoho-Johnstone selection), run LIVE via Rscript |
— |
8 |
0 |
exact — matches to display precision |
SBC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
authors’ Germany.R (lsq detrend + trend_predict + Synth::synth ipop), live run, captured |
|
15 |
3.3e+04 |
documented — see notes |
|
authors’ SBC_HK.R (lsq detrend + trend_predict + Synth::synth ipop), live run, captured |
|
11 |
1e+06 |
close |
Notes (sbc_germany): The deviation is the reference solver’s, and it is in one place: the cyclical weight solve. The detrending and trend-forecast rows agree to 1.7e-14 of each series’ scale (R’s lm QR against numpy’s lstsq). On the weight solve the program is strictly convex with a unique optimum, mlsynth attains it – certified to 1.4e-6 by the convexity of the objective, and a cyclical sum of squares 2.6% lower than the authors’ Synth::synth ipop reaches at any tolerance – so the ATT and weight rows differ because the reference does not converge to the optimum. See docs/replications/sbc.rst.
Notes (sbc_hongkong): Same shape as the German panel. The detrending rows agree to 2.6e-14 of each series’ scale; the ATT, objective and weight rows differ because the authors’ Synth::synth ipop converges to a point about 6% worse in cyclical SSE on the identical strictly-convex program, where mlsynth attains the optimum (certified to 9.8e-8). See docs/replications/sbc.rst.
SCD#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
base-R SCD (point estimator + corrected RC variance + in_C projection QP), reproduced on public CPS microdata |
|
5 |
0 |
exact — matches to display precision |
SCMO#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
Tian-Lee-Panchenko Germany.R (fn_W solve.QP, live run, captured) |
|
6 |
0.011 |
tight |
SCUL#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
authors’ SCUL() (R, via Rscript + glmnet) |
— |
3 |
0.14 |
tight |
SDID#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
|
1 |
0.0016 |
tight |
SI#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
authors’ SI code (INFORMS opre.2025.1590.cd), vendored benchmarks/reference/synth_iv_OR25 |
— |
20 |
0 |
exact — matches to display precision |
SNN#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
deshen24/syntheticNN (live run, captured), SyntheticNearestNeighbors(n_neighbors=1) |
|
14 |
0 |
exact — matches to display precision |
SPILLSYNTH#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
Melnychuk-Andrii/Spillover-SCM inclusive SCM (scm_weights / runInclusiveSCM). The first four rows solve the same program to the simplex; the rows marked ‘reference as shipped’ are the authors’ ipop output, whose weights sum to 0.9666 and 1.1933 |
— |
10 |
3.7e+02 |
documented — see notes |
|
jcao0/synthetic-control-spillover MATLAB spillover.csv (CA row) |
— |
13 |
5.7e-05 |
exact — matches to display precision |
|
Mendez tutorial Rcpp sc_spillover (cmg777) |
|
4 |
3.4 |
documented — see notes |
|
Sakaguchi-Tagawa RcppArmadillo sc_spillover (method=sar, live run on the nonproprietary panel, captured) |
|
5 |
0.41 |
close |
SPSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
— |
4 |
0 |
exact — matches to display precision |
||
— |
31 |
0.0007 |
exact — matches to display precision |
SSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
jcao0/staggered_synthetic_control (committed results_ssc.csv / Table1_eigenvalue.csv) |
— |
364 |
0.001 |
tight |
SpSyDiD#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
authors’ functions_ssdid fit_unit_weights / fit_time_weights under the canonical SDID convention (1/T_post post weights, 1/N_sp affected weights) |
— |
2 |
0 |
exact — matches to display precision |
|
authors’ SDID weight functions (serenini/spatial_SDID functions_ssdid) + the notebook’s spatial WLS, via benchmarks.reference.spsydid_ref |
— |
20 |
0.094 |
close |
TASC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
srho1/tasc TimeAwareSC (live run, captured; em_pre, naive init, set_seed(1)) |
|
15 |
25 |
documented — see notes |
TSSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
authors’ _aux.R :: synth_control_est_demean (quadprog QP, live via Rscript) |
|
6 |
0.0004 |
tight |
Notes (ferman_demeaned_basque): MSCa (TSSC’s simplex+intercept variant) IS Ferman-Pinto’s demeaned SC. Treatment 1975 is the identified regime (20 pre-periods > 16 donors); at 1970 (C>n) the demeaned-SC weights are non-unique and the two implementations legitimately diverge – see docs.
VanillaSC#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
R package augsynth (live run, Kansas study) |
|
8 |
0.0091 |
tight |
|
R package scinference (conformal, live run, captured), cross-checked against the JASA supplement’s own functions |
|
17 |
0.0002 |
tight |
|
R package scinference (conformal) driven by the authors’ own simulation design |
— |
14 |
0.02 |
tight |
|
|
3 |
0 |
exact — matches to display precision |
||
R package scinference (ttest) driven by the authors’ own calibrated simulation design |
|
21 |
0.073 |
close |
|
Ferman (2021) JASA Table 1 (SC columns 1-4, OLS se col 5-8) |
— |
12 |
0.24 |
close |
|
authors’ _aux.R synth_control_est + synth_control_est_demean (quadprog QPs, live via Rscript) |
— |
12 |
0.0003 |
tight |
|
mharoruiz/ibex R replication (01_functions/sc.R: limSolve::lsei simplex SC; scinference) |
|
6 |
0 |
exact — matches to display precision |
|
Malo et al. scm.corner (SCM-Debug, live run, captured) |
|
3 |
0.00048 |
tight |
|
Malo et al. scm.corner (SCM-Debug, live run, captured) |
|
6 |
0.0048 |
tight |
|
R package MSCMT (live run, captured) |
|
4 |
4e-05 |
exact — matches to display precision |
|
authors’ wsoll1 (R, via Rscript + LowRankQP) |
— |
3 |
0.00098 |
exact — matches to display precision |
|
scpi_pkg scdata(cointegrated_data=True)+scpi CI_all_gaussian |
|
13 |
0.11 |
close |
|
— |
15 |
4.3e-05 |
exact — matches to display precision |
||
authors’ replication: SyntheticControlMethods (Synth, pen=’auto’ + covariates) |
|
4 |
4.1 |
documented — see notes |
|
R Synth (j-hai/Synth, synth + synth_inference) |
— |
9 |
0.26 |
close |
|
|
8 |
0.02 |
tight |
||
Andersson (2019) AEJ:EP 11(4), Section III reported values |
|
4 |
0.028 |
close |
|
Synth (uniform custom.v) + tidysynth (ADH spec) |
— |
7 |
3.6 |
close |
mlsynth.utils.inferutils.rae#
Reference |
Dataset |
# |
max |Δ| |
Verdict |
Case |
|---|---|---|---|---|---|
the authors’ RAE.R (JPE replication package), live run |
— |
12 |
0 |
exact — matches to display precision |
Pending capture#
These cross-validation cases are wired up but their reference had not been captured when this page was last generated; the daily action records them once its toolchain provisions.
Case |
Reference |
|---|---|
— |
|
independent reproduction of tsudijon/LeaveTwoOutSCI LTO pair loop (outcome-only SC via LowRankQP), all three empirical applications |
|
jinglongzhao2/SCDesign (live run: Section 5 generation block + Synthetic_Experiment_Cardinality_Constraint on the open quadprog backend) |
|
— |