panelkit 0.2.7__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.
Files changed (82) hide show
  1. {panelkit-0.2.7 → panelkit-0.2.8}/Cargo.lock +5 -5
  2. {panelkit-0.2.7 → panelkit-0.2.8}/Cargo.toml +1 -1
  3. {panelkit-0.2.7 → panelkit-0.2.8}/PKG-INFO +1 -1
  4. {panelkit-0.2.7 → panelkit-0.2.8}/pyproject.toml +1 -1
  5. {panelkit-0.2.7 → panelkit-0.2.8}/python/panelkit/design.py +22 -13
  6. {panelkit-0.2.7 → panelkit-0.2.8}/BENCHMARKS.md +0 -0
  7. {panelkit-0.2.7 → panelkit-0.2.8}/GUIDE.md +0 -0
  8. {panelkit-0.2.7 → panelkit-0.2.8}/LICENSE-APACHE +0 -0
  9. {panelkit-0.2.7 → panelkit-0.2.8}/LICENSE-MIT +0 -0
  10. {panelkit-0.2.7 → panelkit-0.2.8}/README.md +0 -0
  11. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/Cargo.toml +0 -0
  12. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/benches/estimators.rs +0 -0
  13. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/did/bacon.rs +0 -0
  14. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/did/callaway.rs +0 -0
  15. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/did/mod.rs +0 -0
  16. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/did/sunab.rs +0 -0
  17. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/did/twfe.rs +0 -0
  18. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/fe/mod.rs +0 -0
  19. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/fe/within.rs +0 -0
  20. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/lib.rs +0 -0
  21. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/mcnnm/mod.rs +0 -0
  22. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/mcnnm/softimpute.rs +0 -0
  23. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/panel.rs +0 -0
  24. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/result.rs +0 -0
  25. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/sc/augmented.rs +0 -0
  26. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/sc/cpasc.rs +0 -0
  27. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/sc/mod.rs +0 -0
  28. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/sc/sdid.rs +0 -0
  29. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/src/sc/synthetic.rs +0 -0
  30. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/tests/cpasc.rs +0 -0
  31. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/tests/did.rs +0 -0
  32. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/tests/sc.rs +0 -0
  33. {panelkit-0.2.7 → panelkit-0.2.8}/crates/estimators/tests/sc_family.rs +0 -0
  34. {panelkit-0.2.7 → panelkit-0.2.8}/crates/geo/Cargo.toml +0 -0
  35. {panelkit-0.2.7 → panelkit-0.2.8}/crates/geo/src/diagnostics.rs +0 -0
  36. {panelkit-0.2.7 → panelkit-0.2.8}/crates/geo/src/lib.rs +0 -0
  37. {panelkit-0.2.7 → panelkit-0.2.8}/crates/geo/src/power.rs +0 -0
  38. {panelkit-0.2.7 → panelkit-0.2.8}/crates/geo/src/selection.rs +0 -0
  39. {panelkit-0.2.7 → panelkit-0.2.8}/crates/geo/src/types.rs +0 -0
  40. {panelkit-0.2.7 → panelkit-0.2.8}/crates/geo/tests/geo.rs +0 -0
  41. {panelkit-0.2.7 → panelkit-0.2.8}/crates/inference/Cargo.toml +0 -0
  42. {panelkit-0.2.7 → panelkit-0.2.8}/crates/inference/src/batch.rs +0 -0
  43. {panelkit-0.2.7 → panelkit-0.2.8}/crates/inference/src/bootstrap.rs +0 -0
  44. {panelkit-0.2.7 → panelkit-0.2.8}/crates/inference/src/ci.rs +0 -0
  45. {panelkit-0.2.7 → panelkit-0.2.8}/crates/inference/src/lib.rs +0 -0
  46. {panelkit-0.2.7 → panelkit-0.2.8}/crates/inference/src/parallel.rs +0 -0
  47. {panelkit-0.2.7 → panelkit-0.2.8}/crates/inference/src/placebo.rs +0 -0
  48. {panelkit-0.2.7 → panelkit-0.2.8}/crates/inference/tests/inference.rs +0 -0
  49. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/Cargo.toml +0 -0
  50. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/error.rs +0 -0
  51. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/factor/cholesky.rs +0 -0
  52. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/factor/eig_sym.rs +0 -0
  53. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/factor/mod.rs +0 -0
  54. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/factor/qr.rs +0 -0
  55. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/factor/randomized.rs +0 -0
  56. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/factor/svd.rs +0 -0
  57. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/factor/svd_gram.rs +0 -0
  58. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/lib.rs +0 -0
  59. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/matrix.rs +0 -0
  60. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/ops/matmul.rs +0 -0
  61. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/ops/mod.rs +0 -0
  62. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/ops/norms.rs +0 -0
  63. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/ops/transform.rs +0 -0
  64. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/opt/mod.rs +0 -0
  65. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/opt/simplex.rs +0 -0
  66. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/opt/softthresh.rs +0 -0
  67. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/rng.rs +0 -0
  68. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/solve/lstsq.rs +0 -0
  69. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/solve/mod.rs +0 -0
  70. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/src/solve/spd.rs +0 -0
  71. {panelkit-0.2.7 → panelkit-0.2.8}/crates/linalg/tests/numerics.rs +0 -0
  72. {panelkit-0.2.7 → panelkit-0.2.8}/crates/pypanelkit/Cargo.toml +0 -0
  73. {panelkit-0.2.7 → panelkit-0.2.8}/crates/pypanelkit/src/api_did.rs +0 -0
  74. {panelkit-0.2.7 → panelkit-0.2.8}/crates/pypanelkit/src/api_geo.rs +0 -0
  75. {panelkit-0.2.7 → panelkit-0.2.8}/crates/pypanelkit/src/api_sc.rs +0 -0
  76. {panelkit-0.2.7 → panelkit-0.2.8}/crates/pypanelkit/src/convert.rs +0 -0
  77. {panelkit-0.2.7 → panelkit-0.2.8}/crates/pypanelkit/src/lib.rs +0 -0
  78. {panelkit-0.2.7 → panelkit-0.2.8}/crates/pypanelkit/src/results.rs +0 -0
  79. {panelkit-0.2.7 → panelkit-0.2.8}/python/panelkit/__init__.py +0 -0
  80. {panelkit-0.2.7 → panelkit-0.2.8}/python/panelkit/_panelkit.pyi +0 -0
  81. {panelkit-0.2.7 → panelkit-0.2.8}/python/panelkit/estimators.py +0 -0
  82. {panelkit-0.2.7 → 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.7"
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.7"
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.7"
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.7"
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.7"
626
+ version = "0.2.8"
627
627
  dependencies = [
628
628
  "numpy",
629
629
  "panelkit-estimators",
@@ -3,7 +3,7 @@ resolver = "2"
3
3
  members = ["crates/linalg", "crates/estimators", "crates/inference", "crates/geo", "crates/pypanelkit"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.2.7"
6
+ version = "0.2.8"
7
7
  edition = "2021"
8
8
  rust-version = "1.74"
9
9
  license = "MIT OR Apache-2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: panelkit
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: Topic :: Scientific/Engineering
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "panelkit"
7
- version = "0.2.7"
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(self.Y, tr, t0, 0.0, False, level)
780
+ return _panelkit.fit_sc(Y, tr, t0, 0.0, False, level)
780
781
  if method == "ASC":
781
- return _panelkit.fit_asc(self.Y, tr, t0, 0.0, None)
782
- return _panelkit.fit_sdid(self.Y, tr, t0, 1.0)
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
- donors = [u for u in range(self.n) if u not in treated_set]
831
- if len(donors) > int(max_placebo):
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
- donors = sorted(int(j) for j in
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
- for j in donors:
837
- for m in methods:
838
- fj = _fit(m, [j])
839
- pb[m].append((np.asarray(fj.att_path, dtype=float), float(fj.pre_rmspe)))
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(donors)):
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