LINF / L1LINF — L-infinity-norm SC (Wang, Xing & Ye 2025)

LINF / L1LINF — L-infinity-norm SC (Wang, Xing & Ye 2025)#

Estimator:

Relaxed / Penalized Synthetic Control (RESCM)mlsynth.RESCM (penalized branch: LINF / L1LINF)

Source:

Wang, Le, Xin Xing, and Youhui Ye (2025), “A L-infinity Norm Counterfactual and Synthetic Control Approach,” arXiv:2510.26053 [LinfSC].

Replication type:

Path A — the paper’s California Proposition 99 application — Path B — the paper’s Section 5 Monte Carlo — and cross-validation — mlsynth’s L-infinity engine matched cell-by-cell against the authors’ LinfinitySC code.

Status:

Verified — engine cross-validated; empirical and simulation reproduced directionally.

Method#

The L-infinity SC replaces the classic synthetic-control simplex with an intercept-shifted, unconstrained penalized regression (Wang–Xing–Ye, Eqs. 4–5): minimize \(\tfrac{1}{2}\lVert y-\mu-Y_0\omega\rVert^2 + \lambda\lVert\omega\rVert_\infty\) (LINF), or with the mixed penalty \(\lambda(\alpha\lVert\omega\rVert_1+(1-\alpha)\lVert\omega\rVert_\infty)\) (L1LINF). Dropping the simplex and capping the largest weight yields a dense weighting that spreads mass across the donor pool — the opposite of SC’s sparse handful — and nests equal-weights/DiD as \(\lambda\) grows.

mlsynth realises this in the RESCM penalized branch with constraint_type="unconstrained", fit_intercept=True and standardize=False (the L-infinity penalty is scale-sensitive, so the series are fit raw with the level carried by the intercept).

Validation strategy#

Cross-validation (durable: ``linf_crossval_ref``). The authors ship LinfinitySC (BioAlgs/LinfinitySC), whose our(method="inf" | "l1-inf") solves the same program with cvxopt (open source — no commercial solver). mlsynth’s engine and the reference minimize the same objective up to a loss-normalization constant, so a reference \(\lambda_{\text{ref}}\) corresponds to mlsynth \(\lambda = 2T_0\lambda_{\text{ref}}\). In the over-determined regime \(T_0>J\) the penalized minimizer is unique and the two independent solvers agree to solver precision — mlsynth matches both LINF and L1LINF cell-by-cell (weight \(\ell_1\) difference \(\approx 0.0019\)). (At \(J>T_0\) the L-infinity interpolant is non-unique, so the Prop 99 case validates that regime qualitatively instead.)

Path A — Proposition 99 (durable: ``linf_prop99``). On the Abadie–Diamond–Hainmueller California tobacco panel (treated 1989, 38 donors, 1970–2000) the paper’s headline is graphical (Figure 4/5): classic SC concentrates on ~6 donor states, while the L-infinity method spreads weight densely, and SC “appears to overestimate the effect.” mlsynth reproduces this: SC keeps 6 donors; LINF activates all 38 (with ~15 negative weights, off the simplex); SC’s ATT is the more negative. The paper reports no numeric ATT or weight table, so the case pins these qualitative facts.

Path B — Monte Carlo (durable: ``linf_sim``). Under the paper’s two-factor DGP (Section 5; \(T_0=100\), \(J=30\), \(\delta=3\)), the dense L-infinity SC beats sparse classic SC at estimating the ATT when the true donor weights are dense (DGP 2/3), while the mixed L1LINF wins when the truth is sparse (DGP 4). mlsynth reproduces this ordering. The case uses \(B=50\) replications and a fixed penalty for a CI-affordable guard (asserting the ordering, not the paper’s 4-decimal \(B=2000\) Table-4 cells). The penalized solve runs through the OSQP / Gram fast path (mlsynth.utils.laxscm_helpers.fast_solve), so a larger \(B\) is affordable for a manual durable run; the full \(B=2000\) cells remain a manual target.

Reproduce#

python benchmarks/run_benchmarks.py --case linf_crossval_ref --with-reference
python benchmarks/run_benchmarks.py --case linf_prop99
python benchmarks/run_benchmarks.py --case linf_sim

Note on fidelity#

Before this replication, mlsynth’s LINF inherited the SC-family simplex default and a penalty short-circuit that applied a squared-\(\ell_2\) (ridge) term for alpha == 0, so it silently collapsed to classic SC rather than the dense Wang–Xing–Ye estimator. The benchmark surfaced both gaps; the penalized engine now applies the true L-infinity penalty under the unconstrained, intercept-shifted program, guarded by test_laxscm regression tests.