panelkit 0.2.6__tar.gz → 0.2.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {panelkit-0.2.6 → panelkit-0.2.8}/Cargo.lock +5 -5
- {panelkit-0.2.6 → panelkit-0.2.8}/Cargo.toml +1 -1
- {panelkit-0.2.6 → panelkit-0.2.8}/PKG-INFO +1 -1
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/inference/src/bootstrap.rs +2 -3
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/inference/tests/inference.rs +2 -2
- {panelkit-0.2.6 → panelkit-0.2.8}/pyproject.toml +1 -1
- {panelkit-0.2.6 → panelkit-0.2.8}/python/panelkit/design.py +22 -13
- {panelkit-0.2.6 → panelkit-0.2.8}/BENCHMARKS.md +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/GUIDE.md +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/LICENSE-APACHE +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/LICENSE-MIT +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/README.md +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/Cargo.toml +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/benches/estimators.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/did/bacon.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/did/callaway.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/did/mod.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/did/sunab.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/did/twfe.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/fe/mod.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/fe/within.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/lib.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/mcnnm/mod.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/mcnnm/softimpute.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/panel.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/result.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/sc/augmented.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/sc/cpasc.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/sc/mod.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/sc/sdid.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/src/sc/synthetic.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/tests/cpasc.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/tests/did.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/tests/sc.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/estimators/tests/sc_family.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/geo/Cargo.toml +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/geo/src/diagnostics.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/geo/src/lib.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/geo/src/power.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/geo/src/selection.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/geo/src/types.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/geo/tests/geo.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/inference/Cargo.toml +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/inference/src/batch.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/inference/src/ci.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/inference/src/lib.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/inference/src/parallel.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/inference/src/placebo.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/Cargo.toml +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/error.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/factor/cholesky.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/factor/eig_sym.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/factor/mod.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/factor/qr.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/factor/randomized.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/factor/svd.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/factor/svd_gram.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/lib.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/matrix.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/ops/matmul.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/ops/mod.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/ops/norms.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/ops/transform.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/opt/mod.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/opt/simplex.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/opt/softthresh.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/rng.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/solve/lstsq.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/solve/mod.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/src/solve/spd.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/linalg/tests/numerics.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/pypanelkit/Cargo.toml +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/pypanelkit/src/api_did.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/pypanelkit/src/api_geo.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/pypanelkit/src/api_sc.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/pypanelkit/src/convert.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/pypanelkit/src/lib.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/crates/pypanelkit/src/results.rs +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/python/panelkit/__init__.py +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/python/panelkit/_panelkit.pyi +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/python/panelkit/estimators.py +0 -0
- {panelkit-0.2.6 → panelkit-0.2.8}/python/panelkit/py.typed +0 -0
|
@@ -462,7 +462,7 @@ checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
|
|
|
462
462
|
|
|
463
463
|
[[package]]
|
|
464
464
|
name = "panelkit-estimators"
|
|
465
|
-
version = "0.2.
|
|
465
|
+
version = "0.2.8"
|
|
466
466
|
dependencies = [
|
|
467
467
|
"criterion",
|
|
468
468
|
"panelkit-linalg",
|
|
@@ -471,7 +471,7 @@ dependencies = [
|
|
|
471
471
|
|
|
472
472
|
[[package]]
|
|
473
473
|
name = "panelkit-geo"
|
|
474
|
-
version = "0.2.
|
|
474
|
+
version = "0.2.8"
|
|
475
475
|
dependencies = [
|
|
476
476
|
"panelkit-estimators",
|
|
477
477
|
"panelkit-inference",
|
|
@@ -482,7 +482,7 @@ dependencies = [
|
|
|
482
482
|
|
|
483
483
|
[[package]]
|
|
484
484
|
name = "panelkit-inference"
|
|
485
|
-
version = "0.2.
|
|
485
|
+
version = "0.2.8"
|
|
486
486
|
dependencies = [
|
|
487
487
|
"panelkit-estimators",
|
|
488
488
|
"panelkit-linalg",
|
|
@@ -491,7 +491,7 @@ dependencies = [
|
|
|
491
491
|
|
|
492
492
|
[[package]]
|
|
493
493
|
name = "panelkit-linalg"
|
|
494
|
-
version = "0.2.
|
|
494
|
+
version = "0.2.8"
|
|
495
495
|
dependencies = [
|
|
496
496
|
"proptest",
|
|
497
497
|
"rayon",
|
|
@@ -623,7 +623,7 @@ dependencies = [
|
|
|
623
623
|
|
|
624
624
|
[[package]]
|
|
625
625
|
name = "pypanelkit"
|
|
626
|
-
version = "0.2.
|
|
626
|
+
version = "0.2.8"
|
|
627
627
|
dependencies = [
|
|
628
628
|
"numpy",
|
|
629
629
|
"panelkit-estimators",
|
|
@@ -53,14 +53,13 @@ pub fn multiplier_bootstrap(
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/// Jackknife (leave-one-out) standard error from a set of leave-one-out
|
|
56
|
-
/// estimates
|
|
57
|
-
pub fn jackknife_se(loo_estimates: &[f64]
|
|
56
|
+
/// estimates: `sqrt((n-1)/n · Σ(θ_i − θ̄)²)`, centered on the LOO mean.
|
|
57
|
+
pub fn jackknife_se(loo_estimates: &[f64]) -> f64 {
|
|
58
58
|
let n = loo_estimates.len();
|
|
59
59
|
if n < 2 {
|
|
60
60
|
return 0.0;
|
|
61
61
|
}
|
|
62
62
|
let mean = loo_estimates.iter().sum::<f64>() / n as f64;
|
|
63
|
-
let _ = full;
|
|
64
63
|
let ss: f64 = loo_estimates.iter().map(|x| (x - mean).powi(2)).sum();
|
|
65
64
|
((n as f64 - 1.0) / n as f64 * ss).sqrt()
|
|
66
65
|
}
|
|
@@ -107,11 +107,11 @@ fn bootstrap_engines_thread_count_invariant() {
|
|
|
107
107
|
#[test]
|
|
108
108
|
fn jackknife_se_of_constant_is_zero() {
|
|
109
109
|
let est = vec![2.0; 10];
|
|
110
|
-
assert!(jackknife_se(&est
|
|
110
|
+
assert!(jackknife_se(&est) < 1e-12);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
#[test]
|
|
114
114
|
fn jackknife_se_positive_for_varying() {
|
|
115
115
|
let est = vec![1.0, 2.0, 3.0, 4.0, 5.0];
|
|
116
|
-
assert!(jackknife_se(&est
|
|
116
|
+
assert!(jackknife_se(&est) > 0.0);
|
|
117
117
|
}
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "panelkit"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.8"
|
|
8
8
|
description = "Fast, from-scratch causal-inference estimators for panel/geo experiments (SC, ASC, SDID, DiD, MC-NNM)."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -774,12 +774,13 @@ class GeoDesign:
|
|
|
774
774
|
if unknown:
|
|
775
775
|
raise ValueError(f"unknown methods {unknown}; choose from {_METHODS}")
|
|
776
776
|
|
|
777
|
-
def _fit(method, tr):
|
|
777
|
+
def _fit(method, tr, Y=None):
|
|
778
|
+
Y = self.Y if Y is None else Y
|
|
778
779
|
if method == "SC":
|
|
779
|
-
return _panelkit.fit_sc(
|
|
780
|
+
return _panelkit.fit_sc(Y, tr, t0, 0.0, False, level)
|
|
780
781
|
if method == "ASC":
|
|
781
|
-
return _panelkit.fit_asc(
|
|
782
|
-
return _panelkit.fit_sdid(
|
|
782
|
+
return _panelkit.fit_asc(Y, tr, t0, 0.0, None)
|
|
783
|
+
return _panelkit.fit_sdid(Y, tr, t0, 1.0)
|
|
783
784
|
|
|
784
785
|
treated_series = self.Y[idx].mean(axis=0)
|
|
785
786
|
post_len = self.t - t0
|
|
@@ -826,17 +827,25 @@ class GeoDesign:
|
|
|
826
827
|
|
|
827
828
|
# --- engine: per-method null att-samples (+ donor placebo paths if used) ---
|
|
828
829
|
if inference == "placebo":
|
|
830
|
+
# Refit each donor as if treated, on the donor-ONLY sub-panel so the
|
|
831
|
+
# real treated unit(s) are excluded from every placebo's control pool
|
|
832
|
+
# (textbook Abadie — no leakage of the actual effect into the null).
|
|
829
833
|
treated_set = set(idx)
|
|
830
|
-
|
|
831
|
-
|
|
834
|
+
all_donors = [u for u in range(self.n) if u not in treated_set]
|
|
835
|
+
ydon = self.Y[all_donors] # rows = donors only
|
|
836
|
+
nd = len(all_donors)
|
|
837
|
+
rows = list(range(nd))
|
|
838
|
+
if nd > int(max_placebo):
|
|
832
839
|
rng = np.random.default_rng(int(seed))
|
|
833
|
-
|
|
834
|
-
rng.choice(donors, int(max_placebo), replace=False))
|
|
840
|
+
rows = sorted(int(r) for r in rng.choice(nd, int(max_placebo), replace=False))
|
|
835
841
|
pb = {m: [] for m in methods} # per method: list of (att_path, pre_rmspe)
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
842
|
+
# Need >= 2 donors so a placebo (1 treated + >= 1 control) is fittable;
|
|
843
|
+
# otherwise leave pb empty → inference is reported undefined/low-power.
|
|
844
|
+
if nd >= 2:
|
|
845
|
+
for r in rows:
|
|
846
|
+
for m in methods:
|
|
847
|
+
fj = _fit(m, [r], ydon)
|
|
848
|
+
pb[m].append((np.asarray(fj.att_path, dtype=float), float(fj.pre_rmspe)))
|
|
840
849
|
|
|
841
850
|
def _kept_att(samples, treated_pre_m):
|
|
842
851
|
keep = [p.mean() for (p, pre) in samples
|
|
@@ -895,7 +904,7 @@ class GeoDesign:
|
|
|
895
904
|
if inference == "placebo":
|
|
896
905
|
treated_pre = sum(wmap[m] * per[m]["pre_rmspe"] for m in order)
|
|
897
906
|
ens_pb = []
|
|
898
|
-
for di in range(len(
|
|
907
|
+
for di in range(len(pb[order[0]])):
|
|
899
908
|
path = sum(wmap[m] * pb[m][di][0] for m in order)
|
|
900
909
|
pre = sum(wmap[m] * pb[m][di][1] for m in order)
|
|
901
910
|
ens_pb.append((path, pre))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|