panelkit 0.1.0__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.1.0/BENCHMARKS.md +70 -0
- panelkit-0.1.0/Cargo.lock +1116 -0
- panelkit-0.1.0/Cargo.toml +40 -0
- panelkit-0.1.0/GUIDE.md +198 -0
- panelkit-0.1.0/LICENSE-APACHE +201 -0
- panelkit-0.1.0/LICENSE-MIT +21 -0
- panelkit-0.1.0/PKG-INFO +231 -0
- panelkit-0.1.0/README.md +206 -0
- panelkit-0.1.0/crates/estimators/Cargo.toml +20 -0
- panelkit-0.1.0/crates/estimators/benches/estimators.rs +66 -0
- panelkit-0.1.0/crates/estimators/src/did/bacon.rs +183 -0
- panelkit-0.1.0/crates/estimators/src/did/callaway.rs +216 -0
- panelkit-0.1.0/crates/estimators/src/did/mod.rs +16 -0
- panelkit-0.1.0/crates/estimators/src/did/sunab.rs +195 -0
- panelkit-0.1.0/crates/estimators/src/did/twfe.rs +99 -0
- panelkit-0.1.0/crates/estimators/src/fe/mod.rs +5 -0
- panelkit-0.1.0/crates/estimators/src/fe/within.rs +72 -0
- panelkit-0.1.0/crates/estimators/src/lib.rs +21 -0
- panelkit-0.1.0/crates/estimators/src/mcnnm/mod.rs +5 -0
- panelkit-0.1.0/crates/estimators/src/mcnnm/softimpute.rs +240 -0
- panelkit-0.1.0/crates/estimators/src/panel.rs +155 -0
- panelkit-0.1.0/crates/estimators/src/result.rs +51 -0
- panelkit-0.1.0/crates/estimators/src/sc/augmented.rs +142 -0
- panelkit-0.1.0/crates/estimators/src/sc/cpasc.rs +273 -0
- panelkit-0.1.0/crates/estimators/src/sc/mod.rs +15 -0
- panelkit-0.1.0/crates/estimators/src/sc/sdid.rs +201 -0
- panelkit-0.1.0/crates/estimators/src/sc/synthetic.rs +131 -0
- panelkit-0.1.0/crates/estimators/tests/cpasc.rs +105 -0
- panelkit-0.1.0/crates/estimators/tests/did.rs +226 -0
- panelkit-0.1.0/crates/estimators/tests/sc.rs +84 -0
- panelkit-0.1.0/crates/estimators/tests/sc_family.rs +105 -0
- panelkit-0.1.0/crates/inference/Cargo.toml +18 -0
- panelkit-0.1.0/crates/inference/src/bootstrap.rs +149 -0
- panelkit-0.1.0/crates/inference/src/ci.rs +57 -0
- panelkit-0.1.0/crates/inference/src/lib.rs +19 -0
- panelkit-0.1.0/crates/inference/src/parallel.rs +58 -0
- panelkit-0.1.0/crates/inference/src/placebo.rs +98 -0
- panelkit-0.1.0/crates/inference/tests/inference.rs +117 -0
- panelkit-0.1.0/crates/linalg/Cargo.toml +21 -0
- panelkit-0.1.0/crates/linalg/src/error.rs +43 -0
- panelkit-0.1.0/crates/linalg/src/factor/cholesky.rs +112 -0
- panelkit-0.1.0/crates/linalg/src/factor/eig_sym.rs +122 -0
- panelkit-0.1.0/crates/linalg/src/factor/mod.rs +13 -0
- panelkit-0.1.0/crates/linalg/src/factor/qr.rs +156 -0
- panelkit-0.1.0/crates/linalg/src/factor/svd.rs +218 -0
- panelkit-0.1.0/crates/linalg/src/factor/svd_gram.rs +89 -0
- panelkit-0.1.0/crates/linalg/src/lib.rs +75 -0
- panelkit-0.1.0/crates/linalg/src/matrix.rs +215 -0
- panelkit-0.1.0/crates/linalg/src/ops/matmul.rs +154 -0
- panelkit-0.1.0/crates/linalg/src/ops/mod.rs +10 -0
- panelkit-0.1.0/crates/linalg/src/ops/norms.rs +58 -0
- panelkit-0.1.0/crates/linalg/src/ops/transform.rs +138 -0
- panelkit-0.1.0/crates/linalg/src/opt/mod.rs +8 -0
- panelkit-0.1.0/crates/linalg/src/opt/simplex.rs +262 -0
- panelkit-0.1.0/crates/linalg/src/opt/softthresh.rs +33 -0
- panelkit-0.1.0/crates/linalg/src/rng.rs +116 -0
- panelkit-0.1.0/crates/linalg/src/solve/lstsq.rs +63 -0
- panelkit-0.1.0/crates/linalg/src/solve/mod.rs +10 -0
- panelkit-0.1.0/crates/linalg/src/solve/spd.rs +17 -0
- panelkit-0.1.0/crates/linalg/tests/numerics.rs +309 -0
- panelkit-0.1.0/crates/pypanelkit/Cargo.toml +31 -0
- panelkit-0.1.0/crates/pypanelkit/src/api_did.rs +109 -0
- panelkit-0.1.0/crates/pypanelkit/src/api_sc.rs +201 -0
- panelkit-0.1.0/crates/pypanelkit/src/convert.rs +40 -0
- panelkit-0.1.0/crates/pypanelkit/src/lib.rs +41 -0
- panelkit-0.1.0/crates/pypanelkit/src/results.rs +194 -0
- panelkit-0.1.0/pyproject.toml +36 -0
- panelkit-0.1.0/python/panelkit/__init__.py +33 -0
- panelkit-0.1.0/python/panelkit/_panelkit.pyi +113 -0
- panelkit-0.1.0/python/panelkit/estimators.py +511 -0
- panelkit-0.1.0/python/panelkit/py.typed +0 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Benchmarks
|
|
2
|
+
|
|
3
|
+
Measured on an **Apple M4 Pro (14 cores)**, release build, panel size
|
|
4
|
+
**200 units × 130 periods (104 pre / 26 post)** — the scale of a realistic geo
|
|
5
|
+
experiment. Absolute times vary by hardware; re-run to regenerate.
|
|
6
|
+
|
|
7
|
+
Reproduce (regenerates the figures + `assets/bench_results.txt`):
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
maturin develop --release --manifest-path crates/pypanelkit/Cargo.toml
|
|
11
|
+
python benchmarks/make_plots.py # the figures used in the README
|
|
12
|
+
python benchmarks/bench_sc.py # single SC fit vs NumPy+SLSQP
|
|
13
|
+
python benchmarks/bench_placebo.py # full placebo inference vs NumPy+SLSQP
|
|
14
|
+
cargo bench -p panelkit-estimators # Rust-side criterion micro-benchmarks
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Single synthetic-control fit vs reference
|
|
18
|
+
|
|
19
|
+
The reference is the textbook implementation: simplex-constrained least squares
|
|
20
|
+
solved with `scipy.optimize` SLSQP. panelkit uses its from-scratch away-step
|
|
21
|
+
Frank–Wolfe solver in Rust. Median over 5 panels per size:
|
|
22
|
+
|
|
23
|
+
| N units | panelkit (ms) | reference (ms) | speedup |
|
|
24
|
+
|--------:|---------------:|---------------:|--------:|
|
|
25
|
+
| 20 | 0.032 | 1.43 | ~45× |
|
|
26
|
+
| 50 | 0.089 | 5.43 | ~61× |
|
|
27
|
+
| 100 | 0.371 | 23.99 | ~65× |
|
|
28
|
+
| 150 | 0.945 | 68.95 | ~73× |
|
|
29
|
+
| 200 | 2.040 | 121.40 | ~60× |
|
|
30
|
+
|
|
31
|
+
Estimates are identical (ATT |Δ| ≈ 1e-11). See `assets/bench_scaling.png`.
|
|
32
|
+
|
|
33
|
+
> **Robustness note.** SciPy SLSQP has occasional convergence cliffs on
|
|
34
|
+
> near-collinear donor panels — in this sweep individual panels ranged from tens
|
|
35
|
+
> of ms up to **9.5 s** at N=200 when SLSQP iterated to its cap. The table
|
|
36
|
+
> reports the **median** (typical case); the *mean* reference time is far worse.
|
|
37
|
+
> panelkit's Frank–Wolfe solver has no such cliffs.
|
|
38
|
+
|
|
39
|
+
## Full placebo inference (1 + 199 leave-one-out fits)
|
|
40
|
+
|
|
41
|
+
Where the per-fit speedup compounds and panelkit's multithreading (rayon) kicks
|
|
42
|
+
in. Both compute the same in-space placebo p-value.
|
|
43
|
+
|
|
44
|
+
| method | p-value | seconds |
|
|
45
|
+
|------------------------------|--------:|--------:|
|
|
46
|
+
| panelkit (Rust, parallel) | 0.0050 | 0.056 |
|
|
47
|
+
| reference (NumPy + SLSQP) | 0.0050 | 82.2 |
|
|
48
|
+
|
|
49
|
+
**≈ 1467× faster**, identical p-value. See `assets/bench_speedup.png`.
|
|
50
|
+
|
|
51
|
+
## Rust-side estimator micro-benchmarks (criterion)
|
|
52
|
+
|
|
53
|
+
Single fit, 200 × 130:
|
|
54
|
+
|
|
55
|
+
| estimator | time |
|
|
56
|
+
|-----------|-----:|
|
|
57
|
+
| SC | ~2.4 ms |
|
|
58
|
+
| ASC | ~3.3 ms |
|
|
59
|
+
| SDID | ~20 ms |
|
|
60
|
+
| MC-NNM | ~0.5–1.1 s (full SVD per SoftImpute iteration — the intrinsically heavy one) |
|
|
61
|
+
|
|
62
|
+
## Notes
|
|
63
|
+
|
|
64
|
+
- Determinism: the multiplier bootstrap and parallel placebo produce
|
|
65
|
+
**bit-identical** output regardless of `RAYON_NUM_THREADS`, because every
|
|
66
|
+
replicate draws from an independent seed-derived substream
|
|
67
|
+
(`Xoshiro256pp::substream(seed, b)`). Verified in CI at 1 and 8 threads.
|
|
68
|
+
- The reference numbers exist to anchor the speed comparison against a standard,
|
|
69
|
+
widely-used approach — not to claim the reference is the fastest possible
|
|
70
|
+
Python implementation.
|