NEWS.md

coresynth 0.5.0

New features

For type = "trend" it takes a named vector over "treated", "synthetic", and (with show_donors > 0) "donors", e.g. linetypes = c(synthetic = "solid"); series not mentioned keep their default. For type = "gap" it takes a single line type for the gap line, mirroring how colors takes a single color there. For plot.scm_placebo(type = "gaps") the keys are "treated" and "placebo". Values are ggplot2 line type names ("solid", "dashed", "dotted", ...) or the equivalent integer codes 0:6; an unknown key errors with the list of valid keys, as for colors and labels. Bar charts ("weights", "pred_weights") and the point chart ("ratios") ignore the argument.

All defaults reproduce the previous appearance exactly. The argument sits after labels in both signatures, so the arguments that follow it (vline, vline_offset, hline, ...) shift by one position for anyone passing them positionally rather than by name.

Changed

coresynth 0.4.1

Changed

New features

Use it when the predictor specification has fewer predictors than donors in the support. There the inner QP's optimal set is a face rather than a point, the default active-set solver breaks the tie on round-off (so its weights are not stable across arithmetic), and the weights it returns can spread over most of the donor pool -- 221 of 240 donors in one measured case -- which is neither interpretable nor reproducible. Where the QP is not degenerate the two solvers agree: on Proposition 99 an outcomes-only fit returns the same six donors and the same pre-treatment loss to 1e-15 under either.

Opt-in for now, since it changes reported weights for degenerate specs; it is intended to become the default in a future major release. Not available with v_selection = "oos", lambda_pen, v_optim = "bfgs", or staggered adoption, which solve their own QP outside the sharp inner solver; those combinations error rather than silently ignoring the argument. mspe_ratio_pval() mirrors the fit's choice so the permutation test stays symmetric.

Bug fixes

This moves reported weights for specifications whose inner QP is degenerate. Outcomes-only fits improve slightly (Proposition 99 pre-treatment loss 7.220088 -> 7.220081). Specifications where the treated unit's predictor vector lies strictly inside the donor hull -- so the predictor distance is zero for a continuum of weights, e.g. two or three aggregated predictor windows over a large donor pool -- can move substantially, because which zero-distance solution is returned is arbitrary and the outcome path attached to it is arbitrary with it. That is a property of such specifications, not of the solver; qp_solver = "wolfe" above makes it visible and stable.

Performance

Note on reproducibility: when the inner QP is rank deficient (fewer predictors than donors in the support) its solution set is a face, not a point, and the active set's entering-variable choice breaks ties on round-off. Weights from predictor-based fits can therefore differ from 0.4.0 while remaining exact optima of the same problem; the pre-treatment fit itself is unchanged to round-off for outcomes-only specs and moves by at most a few times 1e-5 for in-sample predictor specs under the default v_optim. Outcomes-only fits, staggered SCM, SDID, GSC, MC, TASC, SI, scm_design(), and conformal_inference() are bit-identical.

coresynth 0.4.0

Breaking changes

New features

Deprecated

Performance

Bug fixes

coresynth 0.3.0

New features

Improvements

Bug fixes

Internal

coresynth 0.2.4

Bug fixes

Input validation

Malformed panels previously produced confusing or misleading errors — for example, a 0-row data frame (from an upstream filtering bug) was misclassified as staggered adoption and failed with an unrelated "predictors not supported" error, and missing (id, time) cells surfaced as a raw eig_sym(): decomposition failed from the C++ layer. panel_to_matrices() (shared by all six estimators) and scm_design() now validate and error clearly on:

scm_fit() also now rejects non-numeric (factor/character) outcome or treatment columns and non-integer treatment values, instead of silently coercing them (as.integer(factor(...)) returns level codes, not the original values). "All cohort-level fits failed" errors (SCM/SDID/GSC/SI staggered paths) now point back to the preceding per-cohort warnings for diagnosis.

coresynth 0.2.3

Performance

coresynth 0.2.2

Bug fixes

coresynth 0.2.1

Bug fixes

New features

coresynth 0.2.0

New features

Minor improvements

coresynth 0.1.0

First public release.

Methods

Unified API

Performance

All core optimisations implemented in C++ via RcppArmadillo: 50–70x faster than the Synth package for typical panel sizes (N_co ≤ 30). src/inference.cpp placebo loops parallelised with OpenMP.



Try the coresynth package in your browser

Any scripts or data that you put into this service are public.

coresynth documentation built on Aug. 28, 2026, 1:06 a.m.