Skip to content

Commit 1eabce5

Browse files
igerberclaude
andcommitted
Add Tutorial 22: Survey-Weighted HAD walkthrough
Demonstrates the now-fully-supported HeterogeneousAdoptionDiD + did_had_pretest_workflow workflow under SurveyDesign(weights, strata, psu, fpc) end-to-end on a BRFSS-shape state-rollout panel (5 strata x 6 PSUs/stratum x 2 states/PSU = 60 states; post- stratification raking weights with CV ~ 0.30; FPC = 30 PSUs/stratum; PSU x period interaction shocks injected so cluster correlation survives DiD first-differencing). Closes the Phase 5 wave 2 second slice tutorial gap that the survey-strata gate lift unblocked. Eight sections: motivation; panel + in-notebook helper for attaching survey columns to a HAD panel; naive vs survey-aware headline fit with side-by-side ATT/SE/CI table (~10% SE inflation, sign-only direction asserted); a dedicated discussion of why the SE inflation is modest for HAD specifically (WAS-d_lower IF concentration at the boundary vs full-panel regression coefficients); event-study with sup-t cband under the survey design; pretest workflow on both overall and event-study paths walking the Phase 4.5 C0 QUG-deferred verdict suffix and the now-supported stratified-clustered Stute multiplier bootstrap; communicating-to-leadership two-paragraph template; Extensions + Summary Checklist surfacing the still-deferred lonely_psu='adjust' + singleton-strata, replicate-weight designs, and the permanent QUG-under-survey C0 deferral. Companion drift-test file (25 tests across 5 groups) locks panel composition with deterministic exact pins, naive-vs-survey SE inflation direction (sign-only structural anchor; HAD's IF concentration caps inflation around 1.10x even at large PSU shock SD), design auto-detection to continuous_near_d_lower, event-study cband-vs-pointwise width ordering, _QUG_DEFERRED_SUFFIX substring on report.verdict for both overall and event-study paths, the distinct report.summary() QUG-skip note on the event-study path, deterministic Yatchew sigma2_* pins, and bootstrap p-value tolerance bands at >= 0.25 abs per feedback_strata_bootstrap_path_divergence. Cross-surface updates: T20 and T21 Extensions bullets gain forward-pointers to T22 (T20 also drops the deprecated weights= kwarg phrasing in favor of survey_design=); practitioner decision tree HAD universal-rollout and survey sections each gain a tip cross-link to T22 (adjacent to T20 / T17, not displacing); api/had.rst gains a Survey-aware fit cross-reference; survey-roadmap.md gains a Phase 4.5 C HAD Stute Survey Workflow section; bundled llms.txt and llms-practitioner.txt carry T22 inventory entries; doc-deps.yaml wires T22 as a dependent of both had.py and had_pretests.py; REGISTRY closers L2529 + L2577 flipped to shipped; TODO row L115 marked shipped; CHANGELOG carries the new Unreleased Added entry plus closer flips at the T21 (PR #409) and HAD handlers (PR #402) queued-tutorial closer lines. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 931feb2 commit 1eabce5

14 files changed

Lines changed: 1409 additions & 10 deletions

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Large diffs are not rendered by default.

TODO.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ Deferred items from PR reviews that were not addressed before merge.
112112
| `HeterogeneousAdoptionDiD` Phase 3 R-parity: Phase 3 ships coverage-rate validation on synthetic DGPs (not tight point parity against `chaisemartin::stute_test` / `yatchew_test`). Tight numerical parity requires aligning bootstrap seed semantics and `B` across numpy/R and is deferred. | `tests/test_had_pretests.py` | Phase 3 | Low |
113113
| `HeterogeneousAdoptionDiD` Phase 3 nprobust bandwidth for Stute: some Stute variants on continuous regressors use nprobust-style optimal bandwidth selection. Phase 3 uses OLS residuals from a 2-parameter linear fit (no bandwidth selection). nprobust integration is a future enhancement; not in paper scope. | `diff_diff/had_pretests.py::stute_test` | Phase 3 | Low |
114114
| `HeterogeneousAdoptionDiD` Phase 4: Pierce-Schott (2016) replication harness; reproduce paper Figure 2 values and Table 1 coverage rates. | `benchmarks/`, `tests/` | Phase 2a | Low |
115-
| `HeterogeneousAdoptionDiD` Phase 5 follow-up tutorial (T22 weighted/survey HAD tutorial). T21 HAD pretest workflow notebook landed in PR #409; `practitioner_next_steps()` HAD handlers + `llms-full.txt` HeterogeneousAdoptionDiD section + Choosing-an-Estimator row landed in Phase 5 wave 1 (PR #402). | `tutorials/`, `tests/test_t22_*_drift.py` | Phase 2a | Low |
115+
| `HeterogeneousAdoptionDiD` Phase 5 follow-up tutorial — SHIPPED. T22 (`docs/tutorials/22_had_survey_design.ipynb` + `tests/test_t22_had_survey_design_drift.py`) landed as the follow-up to PR #432; demonstrates the now-supported `SurveyDesign(strata=...)` path through HAD + `did_had_pretest_workflow` end-to-end on a BRFSS-shape household-panel design. T20 HAD brand-campaign (PR #394), T21 HAD pretest workflow (PR #409), and `practitioner_next_steps()` HAD handlers + `llms-full.txt` HeterogeneousAdoptionDiD section + Choosing-an-Estimator row (Phase 5 wave 1, PR #402) landed earlier. | `tutorials/`, `tests/test_t22_*_drift.py` | Phase 2a (shipped) | Done |
116116
| `HeterogeneousAdoptionDiD` time-varying dose on event study: Phase 2b REJECTS panels where `D_{g,t}` varies within a unit for `t >= F` (the aggregation uses `D_{g, F}` as the single regressor for all horizons, paper Appendix B.2 constant-dose convention). A follow-up PR could add a time-varying-dose estimator for these panels; current behavior is front-door rejection with a redirect to `ChaisemartinDHaultfoeuille`. | `diff_diff/had.py::_validate_had_panel_event_study` | Phase 2b | Low |
117117
| `HeterogeneousAdoptionDiD` repeated-cross-section support: paper Section 2 defines HAD on panel OR repeated cross-section, but Phase 2a is panel-only. RCS inputs (disjoint unit IDs between periods) are rejected by the balanced-panel validator with the generic "unit(s) do not appear in both periods" error. A follow-up PR will add an RCS identification path based on pre/post cell means (rather than unit-level first differences), with its own validator and a distinct `data_mode` / API surface. | `diff_diff/had.py::_validate_had_panel`, `diff_diff/had.py::_aggregate_first_difference` | Phase 2a | Medium |
118118
| SyntheticDiD: bootstrap cross-language parity anchor against R's default `synthdid::vcov(method="bootstrap")` (refit; rebinds `opts` per draw) or Julia `Synthdid.jl::src/vcov.jl::bootstrap_se` (refit by construction). Same-library validation (placebo-SE tracking, AER §6.3 MC truth) is in place; a cross-language anchor is desirable to bolster the methodology contract. Julia is the cleanest target — minimal wrapping work and refit-native vcov. Tolerance target: 1e-6 on Monte Carlo samples (different BLAS + RNG paths preclude 1e-10). The R-parity fixture from the previous release was deleted because it pinned the now-removed fixed-weight path. | `benchmarks/R/`, `benchmarks/julia/`, `tests/` | follow-up | Low |

diff_diff/guides/llms-practitioner.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,10 @@ see REGISTRY HeterogeneousAdoptionDiD edge cases):
193193
| filters to the last cohort + never-treated (Appendix B.2)
194194
| and the estimand becomes last-cohort-only WAS — use
195195
| ChaisemartinDHaultfoeuille if full multi-cohort staggered
196-
| support under continuous treatment is required.
196+
| support under continuous treatment is required. For the
197+
| survey-weighted HAD workflow on a stratified-PSU design
198+
| (BRFSS / CPS / NHANES shape), see Tutorial 22:
199+
| docs/tutorials/22_had_survey_design.ipynb.
197200
|
198201
Is treatment adoption staggered (multiple cohorts, different timing)?
199202
|-- YES: Do NOT use plain TWFE. Use one of:

diff_diff/guides/llms.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ Full practitioner guide: call `diff_diff.get_llm_guide("practitioner")`
9797
- [15 Efficient DiD](https://diff-diff.readthedocs.io/en/stable/tutorials/15_efficient_did.html): Chen, Sant'Anna & Xie (2025) efficient DiD — optimal weighting, PT-All vs PT-Post, efficiency gains
9898
- [16 Survey DiD](https://diff-diff.readthedocs.io/en/stable/tutorials/16_survey_did.html): Survey-weighted DiD — SurveyDesign, strata/PSU/FPC, replicate weights, subpopulation analysis, DEFF diagnostics
9999
- [16 Wooldridge ETWFE](https://diff-diff.readthedocs.io/en/stable/tutorials/16_wooldridge_etwfe.html): Wooldridge (2023, 2025) ETWFE — saturated OLS, logit/Poisson (ASF-based ATT), aggregation types
100+
- [22 HAD Survey-Weighted Workflow](https://diff-diff.readthedocs.io/en/stable/tutorials/22_had_survey_design.html): HeterogeneousAdoptionDiD + did_had_pretest_workflow under SurveyDesign(strata, psu, weights, fpc) — BRFSS-shape panel, modest SE inflation explanation, Phase 4.5 C0 QUG-deferred verdict
100101

101102
## Survey Support
102103

docs/api/had.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,15 @@ Unit Remains Untreated" (arXiv:2405.04465v6), which:
116116
weighted-CR1 per-horizon), or drop ``cluster=`` (keeps
117117
weighted-HC1 sup-t).
118118

119+
.. tip::
120+
121+
For an end-to-end walkthrough of the survey-aware HAD workflow on a
122+
BRFSS-shape stratified household-survey panel - including the now-
123+
supported ``SurveyDesign(strata=...)`` path through the Stute pretest
124+
family (lifted in PR #432, 2026-05) - see
125+
`Tutorial 22: Survey-Weighted HAD
126+
<../tutorials/22_had_survey_design.ipynb>`_.
127+
119128
HeterogeneousAdoptionDiD
120129
------------------------
121130

docs/doc-deps.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@ sources:
391391
- path: docs/tutorials/21_had_pretest_workflow.ipynb
392392
type: tutorial
393393
note: "Drift-locks `HAD(design=\"auto\")` resolution to `continuous_at_zero` on T21's panel via `tests/test_t21_had_pretest_workflow_drift.py::test_had_design_auto_lands_on_continuous_at_zero`; changes to `_detect_design()` heuristic should re-validate T21"
394+
- path: docs/tutorials/22_had_survey_design.ipynb
395+
type: tutorial
396+
note: "Survey-aware HAD walkthrough; drift-locked at `tests/test_t22_had_survey_design_drift.py`. Drift-locks `HAD(design=\"auto\")` resolution to `continuous_near_d_lower` on T22's panel and the `survey_design=` path's SE/CI behavior."
394397

395398
diff_diff/had_pretests.py:
396399
drift_risk: medium
@@ -410,6 +413,9 @@ sources:
410413
- path: docs/tutorials/21_had_pretest_workflow.ipynb
411414
type: tutorial
412415
note: "Composite pre-test workflow walkthrough; drift-locked at tests/test_t21_had_pretest_workflow_drift.py"
416+
- path: docs/tutorials/22_had_survey_design.ipynb
417+
type: tutorial
418+
note: "Survey-aware pretest workflow walkthrough (overall + event-study under SurveyDesign(strata=...)); drift-locks `_QUG_DEFERRED_SUFFIX`, the event-study summary QUG-skip note, and joint pretrends/homogeneity horizon labels under stratified-clustered Stute bootstrap (PR #432). Drift-locked at tests/test_t22_had_survey_design_drift.py"
413419

414420
diff_diff/local_linear.py:
415421
drift_risk: low

docs/methodology/REGISTRY.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2526,7 +2526,7 @@ Shipped in `diff_diff/had_pretests.py` as `stute_joint_pretest()` (residuals-in
25262526
- **Note:** Horizon labels in `StuteJointResult.horizon_labels` are `str(t)` verbatim and carry STRING IDENTITY ONLY — NOT a chronological ordering key. Callers who need chronological order must preserve the original period values alongside (e.g. from the `pre_periods` / `post_periods` argument).
25272527
- **Note:** NaN propagation is explicit: when any horizon has NaN in residuals, `cvm_stat_joint=NaN`, `p_value=NaN`, `reject=False`, AND `per_horizon_stats={label: np.nan for every horizon}` (full dict preserved with NaN values — not empty, not partial).
25282528

2529-
**Phase 3 follow-up delivery:** `stute_joint_pretest()`, `joint_pretrends_test()`, `joint_homogeneity_test()`, `StuteJointResult`, and `did_had_pretest_workflow(aggregate="event_study")` shipped together in PR #353 (2026-04). The `practitioner_next_steps()` HAD handlers landed in Phase 5 wave 1 (PR #402); the T21 HAD pretest workflow tutorial landed in PR #409 (Phase 5 wave 2 first slice). T22 weighted/survey HAD tutorial remains queued.
2529+
**Phase 3 follow-up delivery:** `stute_joint_pretest()`, `joint_pretrends_test()`, `joint_homogeneity_test()`, `StuteJointResult`, and `did_had_pretest_workflow(aggregate="event_study")` shipped together in PR #353 (2026-04). The `practitioner_next_steps()` HAD handlers landed in Phase 5 wave 1 (PR #402); the T21 HAD pretest workflow tutorial landed in PR #409 (Phase 5 wave 2 first slice). The T22 survey-weighted HAD tutorial (`docs/tutorials/22_had_survey_design.ipynb`) shipped as the follow-up to PR #432 (2026-05).
25302530

25312531
**Reference implementation(s):**
25322532
- R: `did_had` (de Chaisemartin, Ciccia, D'Haultfœuille, Knau 2024a); `stute_test` (2024c); `yatchew_test` (Online Appendix, Table 3).
@@ -2574,7 +2574,7 @@ Shipped in `diff_diff/had_pretests.py` as `stute_joint_pretest()` (residuals-in
25742574
- [x] Phase 5 (wave 1, PR #402): `llms-full.txt` HeterogeneousAdoptionDiD section + result-class blocks + `## HAD Pretests` index + Choosing-an-Estimator row landed; constructor / fit() parameter names are regression-locked against `inspect.signature(HeterogeneousAdoptionDiD.__init__)` and `HeterogeneousAdoptionDiD.fit` for parameter-name presence (parameter defaults and the non-return parameter type annotations remain unpinned; the `fit()` return-type union is locked BOTH at the source-code level AND at the test level by `TestFitReturnAnnotation`); result-class field tables enumerate every public dataclass field (regression-tested via `dataclasses.fields()`); `llms-practitioner.txt` Step 4 decision tree distinguishes ContinuousDiD (per-dose ATT(d), needs never-treated) from HeterogeneousAdoptionDiD (WAS, universal-rollout-compatible).
25752575
- [x] Phase 5 (partial): README catalog one-liner, bundled `llms.txt` `## Estimators` entry, `docs/api/had.rst` (autoclass for the three classes), and `docs/references.rst` citation landed in PR #372 docs refresh.
25762576
- [x] Phase 5 (wave 2 first slice, PR #409): T21 HAD pretest workflow tutorial (`docs/tutorials/21_had_pretest_workflow.ipynb`) — composite pre-test walkthrough for `did_had_pretest_workflow`. Uses a `Uniform[$0.01K, $50K]` dose-distribution variant of T20's brand-campaign panel (true support strictly positive but near-zero, chosen so QUG fails-to-reject `H0: d_lower = 0` in finite sample). Walks through `aggregate="overall"` (Steps 1 + 3 only, verdict explicitly flags Step 2 deferral) and upgrades to `aggregate="event_study"` (joint pre-trends Stute + joint homogeneity Stute close the gap). Side panel exercises both `yatchew_hr_test` null modes (`linearity` vs `mean_independence`). Companion drift-test file `tests/test_t21_had_pretest_workflow_drift.py` (16 tests pinning panel composition, both verdict pivots, structural anchors, deterministic stats, bootstrap p-value tolerance bands per backend, and `HAD(design="auto")` resolution to `continuous_at_zero` on this panel).
2577-
- [ ] Phase 5 (remaining): T22 weighted/survey HAD tutorial - tracked in `TODO.md`.
2577+
- [x] Phase 5 (wave 2 second slice): T22 weighted/survey HAD tutorial (`docs/tutorials/22_had_survey_design.ipynb`) - shipped as the follow-up to PR #432. End-to-end walkthrough of `HeterogeneousAdoptionDiD` + `did_had_pretest_workflow` under `SurveyDesign(weights, strata, psu, fpc)` on a BRFSS-shape state-rollout panel (5 strata x 6 PSUs/stratum x 2 states/PSU = 60 states; post-stratification raking weights with CV ~ 0.30; FPC = 30 PSUs/stratum). Companion drift-test file `tests/test_t22_had_survey_design_drift.py` (25 tests pinning panel composition, naive-vs-survey SE inflation direction, design auto-detection, event-study cband-vs-pointwise width ordering, `_QUG_DEFERRED_SUFFIX` substring on `report.verdict` for both overall and event-study paths, the distinct `report.summary()` QUG-skip note on the event-study path, deterministic Yatchew sigma2_*, and bootstrap p-value tolerance bands per `feedback_strata_bootstrap_path_divergence` (>= 0.25 abs)).
25782578
- [ ] Documentation of non-testability of Assumptions 5 and 6.
25792579
- [ ] Warnings for staggered treatment timing (redirect to `ChaisemartinDHaultfoeuille`).
25802580
- [ ] `NotImplementedError` phase pointer when `covariates=` is passed (Theorem 6 future work).

docs/practitioner_decision_tree.rst

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,13 @@ identification rests on stronger structural assumptions (Design 1).
315315
For a full walkthrough including data setup, the design auto-detection
316316
diagnostic, the multi-week event study, and a stakeholder communication
317317
template, see `Tutorial 20: HAD for National Brand Campaign with Regional
318-
Spend Intensity <tutorials/20_had_brand_campaign.ipynb>`_.
318+
Spend Intensity <tutorials/20_had_brand_campaign.ipynb>`_. For the
319+
composite pre-test diagnostic walkthrough on top of HAD, see
320+
`Tutorial 21: HAD Pre-test Workflow
321+
<tutorials/21_had_pretest_workflow.ipynb>`_. For the same workflow under
322+
stratified survey weights (BRFSS-shape design), see
323+
`Tutorial 22: Survey-Weighted HAD
324+
<tutorials/22_had_survey_design.ipynb>`_.
319325

320326

321327
.. _section-few-markets:
@@ -412,7 +418,10 @@ See :doc:`practitioner_getting_started` for an end-to-end example.
412418

413419
For a full walkthrough with brand funnel metrics and staggered rollouts, see
414420
`Tutorial 17: Brand Awareness Survey
415-
<tutorials/17_brand_awareness_survey.ipynb>`_.
421+
<tutorials/17_brand_awareness_survey.ipynb>`_. For the survey-design path
422+
through HAD (universal-rollout, continuous dose, stratified survey weights),
423+
see `Tutorial 22: Survey-Weighted HAD
424+
<tutorials/22_had_survey_design.ipynb>`_.
416425

417426

418427
At a Glance

docs/survey-roadmap.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,35 @@ Supports both TSL and replicate-weight variance.
140140
See `docs/api/prep.rst` for the API reference and `docs/methodology/REGISTRY.md`
141141
for the methodology entry.
142142

143+
### Phase 4.5 C: HAD Stute Survey Workflow ✅ Shipped
144+
145+
The HeterogeneousAdoptionDiD pretest family (`stute_test`,
146+
`stute_joint_pretest`, `joint_pretrends_test`, `joint_homogeneity_test`,
147+
and the composite `did_had_pretest_workflow`) gained end-to-end
148+
support for `SurveyDesign(strata=..., psu=..., weights=..., fpc=...)`
149+
in PR #432 (2026-05). The Stute CvM bootstrap on stratified survey
150+
designs uses a documented synthesis of clustered-wild-bootstrap
151+
ingredients (Cameron-Gelbach-Miller 2008 cluster-level multipliers;
152+
Davidson-Flachaire 2008 wild-bootstrap centering; Wu 1986 / Liu 1988
153+
Bessel small-sample correction; Djogbenou-MacKinnon-Nielsen 2019
154+
cluster-wild consistency for nonlinear functionals): within-stratum
155+
demean + `sqrt(n_h/(n_h-1))` rescale on the PSU multipliers BEFORE
156+
the per-obs broadcast in the wild-residual loop. The shared helper
157+
`bootstrap_utils.apply_stratum_centering` backs both the new Stute
158+
path and the existing HAD sup-t event-study cband bootstrap. The QUG
159+
step remains permanently deferred under survey/weights (Phase 4.5
160+
C0); the workflow surfaces this in `report.qug=None` plus the
161+
`_QUG_DEFERRED_SUFFIX` substring on `report.verdict`. Tutorial 22
162+
(`docs/tutorials/22_had_survey_design.ipynb`) walks the workflow
163+
end-to-end on a BRFSS-shape state-rollout panel.
164+
165+
Remaining HAD survey-path deferrals (separate follow-up PRs):
166+
`lonely_psu='adjust'` + singleton strata (pseudo-stratum centering
167+
transform not yet derived for the Stute functional — same gap as the
168+
HAD sup-t deviation at REGISTRY:2382); replicate-weight designs
169+
(BRR / Fay / JK1 / JKn / SDR — separate Rao-Wu / JKn bootstrap
170+
composition).
171+
143172
---
144173

145174
## Phase 10: Academic Grounding (History)

docs/tutorials/20_had_brand_campaign.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@
388388
"\n",
389389
"This tutorial covered HAD's headline workflow: the overall WAS_d_lower fit and the multi-week event study. The library also supports several extensions we did not demonstrate here.\n",
390390
"\n",
391-
"- **Population-weighted (survey-aware) inference**: when some markets or regions carry more weight than others - e.g., DMAs weighted by population - HAD accepts a `weights=` array or a `SurveyDesign` object on the same `fit()` interface.\n",
391+
"- **Population-weighted (survey-aware) inference**: when some markets or regions carry more weight than others - e.g., DMAs weighted by population - HAD accepts a `SurveyDesign` object on the same `fit()` interface (the deprecated `weights=` and `survey=` kwarg aliases will be removed in the next minor release; use `survey_design=` going forward). [Tutorial 22](22_had_survey_design.ipynb) walks the BRFSS-shape survey-design path end-to-end including the pretest workflow.\n",
392392
"- **Composite pretest workflow**: HAD ships a `did_had_pretest_workflow` that combines the QUG support-infimum test (`H0: d_lower = 0`, which adjudicates between the `continuous_at_zero` and `continuous_near_d_lower` design paths) with linearity tests (Stute and Yatchew-HR). On the two-period (`aggregate='overall'`) path this workflow checks QUG and linearity only; the parallel-trends step is closed by the multi-period (`aggregate='event_study'`) joint variants (`stute_joint_pretest`, `joint_pretrends_test`, `joint_homogeneity_test`). The visual placebo check we used in Section 4 is a parallel-trends sanity check, not a substitute for the formal joint pretests; see [Tutorial 21](21_had_pretest_workflow.ipynb) for an end-to-end pretest walkthrough.\n",
393393
"- **`continuous_at_zero` design path**: if the lightest-touch DMA had no regional add-on (spend exactly $0), HAD switches to the Design 1' identification path with target `WAS` instead of `WAS_d_lower`. The auto-detection picks it up.\n",
394394
"- **Mass-point design path**: if a meaningful chunk of DMAs sit at exactly the same minimum spend (rather than spread continuously near the boundary), HAD switches to a 2SLS estimator with matching identification logic. Auto-detected as well.\n",

0 commit comments

Comments
 (0)