Verify NA-MQ hierarchy with general stochastic coupling
Browse files
outputs/namq_rdspac_coupling_audit.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"audit": "multiplicity-weighted NA-MQ to R-DS-PAC coupling",
|
| 3 |
+
"seed": 20260722,
|
| 4 |
+
"formula": "N=ceil(8*m*log(2*m/delta)); D'_Q(u)=c_u/m",
|
| 5 |
+
"coupon_stress": {
|
| 6 |
+
"trials": 10000,
|
| 7 |
+
"delta_per_trial": 0.05,
|
| 8 |
+
"multiplicity_modes": {
|
| 9 |
+
"all_distinct": 2500,
|
| 10 |
+
"one_heavy": 2500,
|
| 11 |
+
"zipf": 2500,
|
| 12 |
+
"dirichlet": 2500
|
| 13 |
+
},
|
| 14 |
+
"coupon_failures": 0,
|
| 15 |
+
"empirical_failure_rate": 0.0,
|
| 16 |
+
"worst_minimum_surplus": 23,
|
| 17 |
+
"largest_chernoff_union_bound": 1.043990016933941e-06
|
| 18 |
+
},
|
| 19 |
+
"stochastic_label_transcript_stress": {
|
| 20 |
+
"trials": 50000,
|
| 21 |
+
"query_order": [
|
| 22 |
+
0,
|
| 23 |
+
1,
|
| 24 |
+
0,
|
| 25 |
+
2,
|
| 26 |
+
1,
|
| 27 |
+
0
|
| 28 |
+
],
|
| 29 |
+
"multiplicities": [
|
| 30 |
+
3,
|
| 31 |
+
2,
|
| 32 |
+
1
|
| 33 |
+
],
|
| 34 |
+
"label_probabilities": [
|
| 35 |
+
0.2,
|
| 36 |
+
0.6,
|
| 37 |
+
0.85
|
| 38 |
+
],
|
| 39 |
+
"training_draws": 264,
|
| 40 |
+
"coverage_failures": 0,
|
| 41 |
+
"valid_transcripts": 50000,
|
| 42 |
+
"max_direct_vs_reconstructed_mean_gap": 0.0020799999999999708,
|
| 43 |
+
"max_direct_vs_reconstructed_covariance_gap": 0.0020765559999999664,
|
| 44 |
+
"max_reconstructed_vs_target_mean_gap": 0.0009799999999999809
|
| 45 |
+
},
|
| 46 |
+
"checks": {
|
| 47 |
+
"all_coupon_stress_trials_covered": true,
|
| 48 |
+
"analytic_union_bound_below_delta": true,
|
| 49 |
+
"stochastic_transcripts_covered": true,
|
| 50 |
+
"transcript_means_match": true,
|
| 51 |
+
"transcript_covariances_match": true,
|
| 52 |
+
"reconstructed_means_match_target": true
|
| 53 |
+
},
|
| 54 |
+
"all_checks_pass": true
|
| 55 |
+
}
|
outputs/theorem_5_2_5_3_proof_certificate.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Proof certificate: Theorems 5.2 and 5.3
|
| 2 |
+
|
| 3 |
+
This certificate reconstructs the two membership-query reductions in their full finite-sample form. It also repairs an omission in the printed proof of Theorem 5.3 without changing its asymptotic sample bound.
|
| 4 |
+
|
| 5 |
+
## Theorem 5.2: D-DS-PAC implies NA-MQ
|
| 6 |
+
|
| 7 |
+
Fix the target distribution `D`, hypothesis class `H`, and a D-DS-PAC learner whose deterministic training distribution is `D'` and whose sample size is `m`. Before observing any labels, an NA-MQ learner draws an ordered feature batch `(X_1,...,X_m) ~ (D')^m`. It submits that whole batch non-adaptively and passes the returned labeled sequence to the D-DS-PAC learner. Conditional on the features, each returned label is an independent draw from the stochastic labeling rule `f(X_i)`. Hence the simulated transcript has exactly the law `(D',f)^m`, including arbitrary label noise, and sample complexity and running time are unchanged.
|
| 8 |
+
|
| 9 |
+
## Preprocessing a general NA-MQ transcript
|
| 10 |
+
|
| 11 |
+
Definition 5.1 permits both random target examples and an independently randomized query batch. Generate every feature before seeing labels: draw the `m_rand` feature points from `D`, draw the batch from `Q`, and concatenate them in their original ordered positions. This is one randomized nonadaptive list `Q=(x_1,...,x_m)`, independent of `f`. Thus random target examples require no separate mechanism. Let `c_u` be the multiplicity of each distinct `u` in the combined list, so `sum_u c_u=m`.
|
| 12 |
+
|
| 13 |
+
## Theorem 5.3: NA-MQ implies R-DS-PAC
|
| 14 |
+
|
| 15 |
+
For a realized list `Q`, choose the training distribution
|
| 16 |
+
|
| 17 |
+
`D'_Q(u) = c_u/m`.
|
| 18 |
+
|
| 19 |
+
Set `delta=epsilon/2`, `L=log(2m/delta)`, and draw
|
| 20 |
+
|
| 21 |
+
`N = ceil(8 m L)`
|
| 22 |
+
|
| 23 |
+
i.i.d. labeled examples from `(D'_Q,f)`. For a distinct point `u`, its count `X_u` is binomial with mean at least `8 c_u L`. A multiplicative Chernoff bound gives
|
| 24 |
+
|
| 25 |
+
`P[X_u<c_u] <= exp(-c_u(a-1)^2/(2a))`, where `a=8L`.
|
| 26 |
+
|
| 27 |
+
Since `a>=4`, `(a-1)^2/(2a)>=a/4`; therefore this probability is at most `exp(-2 c_u L) <= (delta/(2m))^2 <= delta/m`. A union bound over at most `m` distinct points makes the simultaneous failure probability at most `delta`.
|
| 28 |
+
|
| 29 |
+
On the coverage event, take the first `c_u` observed labels for each `u` and put them back into the original positions of `Q`. Counts depend only on sampled features, so conditioning on coverage does not affect labels. The selected labels are independent draws from `f(u)`, including separate fresh labels for duplicate occurrences. The reconstructed ordered transcript therefore has exactly the law expected by the original NA-MQ learner.
|
| 30 |
+
|
| 31 |
+
Run the original learner at accuracy `epsilon/2`; on the failure event return any fixed hypothesis. For loss bounded by one,
|
| 32 |
+
|
| 33 |
+
`E[excess loss] <= epsilon/2 + delta = epsilon`.
|
| 34 |
+
|
| 35 |
+
Also `N=O(m_0(epsilon/2)(log m_0(epsilon/2)+log(1/epsilon)))`. If the original list is randomized, the induced law of `D'_Q` is the permitted randomized training-distribution meta-distribution, giving R-DS-PAC. If it is deterministic, `D'_Q` is fixed, giving D-DS-PAC.
|
| 36 |
+
|
| 37 |
+
## Printed-proof audit
|
| 38 |
+
|
| 39 |
+
The manuscript instead makes `D'_Q` uniform on the support and retains only the first label at each point. That construction is exact only when queries are distinct or duplicate labels are deterministic. Multiplicity weighting and retaining `c_u` labels close the gap for duplicated queries and stochastic labels. The theorem statement and stated asymptotic rate survive this repair.
|
pages/claim-5-membership-query-hierarchy/page.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
| 5 |
<!-- trackio-cell
|
| 6 |
{"type": "markdown", "id": "cell_3e53ff8de963", "created_at": "2026-07-17T04:36:14+00:00", "title": "Question and test"}
|
| 7 |
-->
|
| 8 |
-
The prompt states the D-DS-PAC→NA-MQ and NA-MQ→R-DS-PAC hierarchy and coupon-collector sample bound. We
|
| 9 |
|
| 10 |
|
| 11 |
---
|
|
@@ -14,17 +14,25 @@ The prompt states the D-DS-PAC→NA-MQ and NA-MQ→R-DS-PAC hierarchy and coupon
|
|
| 14 |
-->
|
| 15 |
Claim under test (verbatim): The paper establishes a hierarchy of learnability notions showing D-DS-PAC learning implies non-adaptive membership query (NA-MQ) learning, and NA-MQ learners can be converted into R-DS-PAC learners with sample complexity m(epsilon) = O(m0(epsilon/2) * (log m0(epsilon/2) + log(1/epsilon))) (Theorems 5.2 and 5.3).
|
| 16 |
|
| 17 |
-
Source locators: Theorems 5.2 and 5.3 and Appendix E. Both implication statements and the
|
| 18 |
|
| 19 |
-
|
| 20 |
|
| 21 |
-
|
| 22 |
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
|
| 26 |
---
|
| 27 |
<!-- trackio-cell
|
| 28 |
{"type": "markdown", "id": "cell_cc273205d4f8", "created_at": "2026-07-17T05:15:09+00:00", "title": "Normalized source locator"}
|
| 29 |
-->
|
| 30 |
-
Strict source locators: Theorem 5.2; Theorem 5.3; Appendix E. The
|
|
|
|
| 5 |
<!-- trackio-cell
|
| 6 |
{"type": "markdown", "id": "cell_3e53ff8de963", "created_at": "2026-07-17T04:36:14+00:00", "title": "Question and test"}
|
| 7 |
-->
|
| 8 |
+
The prompt states the D-DS-PAC→NA-MQ and NA-MQ→R-DS-PAC hierarchy and coupon-collector sample bound. We reconstruct both reductions for the full Definition 5.1 model, including random target examples, duplicated queries, randomized batches, and stochastic labels, then stress-test the finite coupon event and transcript law.
|
| 9 |
|
| 10 |
|
| 11 |
---
|
|
|
|
| 14 |
-->
|
| 15 |
Claim under test (verbatim): The paper establishes a hierarchy of learnability notions showing D-DS-PAC learning implies non-adaptive membership query (NA-MQ) learning, and NA-MQ learners can be converted into R-DS-PAC learners with sample complexity m(epsilon) = O(m0(epsilon/2) * (log m0(epsilon/2) + log(1/epsilon))) (Theorems 5.2 and 5.3).
|
| 16 |
|
| 17 |
+
Source locators: Definition 5.1, Theorems 5.2 and 5.3, and Appendix E in [arXiv:2602.08907v2](https://arxiv.org/abs/2602.08907). Both implication statements and the claimed coupon-collector order appear in the manuscript.
|
| 18 |
|
| 19 |
+
**Theorem 5.2, exact coupling.** A D-DS-PAC learner samples an ordered batch from its fixed training distribution `D'`. An NA-MQ learner draws those feature points before observing labels, submits the batch nonadaptively, and passes the returned labels to the original learner. Conditional on the features, the labels are independent draws from `f(x)`, so the transcript law, label noise, sample complexity, and running time are identical.
|
| 20 |
|
| 21 |
+
**Theorem 5.3, general coupling.** First draw the random target features and randomized query batch, all before labels, and concatenate them into one ordered list `Q`. If point `u` occurs `c_u` times, use the randomized training distribution `D'_Q(u)=c_u/m`, rather than a distribution uniform on the distinct support. With `delta=epsilon/2` and `N=ceil(8m log(2m/delta))`, a Chernoff bound and union bound give probability at least `1-delta` that every `u` occurs at least `c_u` times. Taking the first `c_u` independently drawn labels and restoring their ordered positions exactly reconstructs duplicated queries and stochastic labels. Running the NA-MQ learner at `epsilon/2`, with bounded-loss cost at most `delta` on failure, gives excess risk at most `epsilon` and
|
| 22 |
|
| 23 |
+
`N = O(m_0(epsilon/2)(log m_0(epsilon/2)+log(1/epsilon)))`.
|
| 24 |
+
|
| 25 |
+
For randomized `Q`, its induced law over `D'_Q` is precisely an R-DS-PAC meta-distribution; for deterministic `Q`, the distribution is fixed and yields D-DS-PAC. The complete inequality chain and coupling are frozen in `outputs/theorem_5_2_5_3_proof_certificate.md`.
|
| 26 |
+
|
| 27 |
+
**Independent executable audit.** `scripts/namq_rdspac_coupling_audit.py` tests 10,000 batches spanning all-distinct, one-heavy, Zipf, and Dirichlet multiplicities and 50,000 ordered stochastic-label transcripts with duplicates. It evaluates the finite Chernoff certificate, not only an asymptotic order. Frozen results are in `outputs/namq_rdspac_coupling_audit.json`.
|
| 28 |
+
|
| 29 |
+
**Proof audit disclosure.** Appendix E uses a distribution uniform over the support and retains only the first label. That printed construction omits multiplicities and is not exact for duplicated stochastic queries. The multiplicity-weighted construction above repairs the proof without changing the theorem statement or asymptotic bound.
|
| 30 |
+
|
| 31 |
+
Verdict: **VERIFIED**, with a documented repair to the manuscript's printed proof.
|
| 32 |
|
| 33 |
|
| 34 |
---
|
| 35 |
<!-- trackio-cell
|
| 36 |
{"type": "markdown", "id": "cell_cc273205d4f8", "created_at": "2026-07-17T05:15:09+00:00", "title": "Normalized source locator"}
|
| 37 |
-->
|
| 38 |
+
Strict source locators: Definition 5.1; Theorem 5.2; Theorem 5.3; Appendix E. The proof certificate covers arbitrary randomized nonadaptive lists and stochastic labels; the executable audit exercises duplicate multiplicities and ordered stochastic-label reconstruction.
|
pages/conclusion/page.md
CHANGED
|
@@ -12,7 +12,7 @@ This page consolidates the exact claim verdicts, scope and cost, checksum-verifi
|
|
| 12 |
<!-- trackio-cell
|
| 13 |
{"type": "markdown", "id": "cell_dba782593110", "created_at": "2026-07-17T05:10:20+00:00", "title": "Executive summary", "pinned": true, "pinned_at": "2026-07-17T05:10:21+00:00"}
|
| 14 |
-->
|
| 15 |
-
This reproduction does not confirm the six-claim package: Claim 1 is falsified as written by a mismatched formula and exact endpoint failure; Claims 2 and 3 are also falsified by moment errors and a junta counterexample. Claim 4 remains unresolved beyond a failed decoder proof component
|
| 16 |
|
| 17 |
## Scope & cost
|
| 18 |
|
|
|
|
| 12 |
<!-- trackio-cell
|
| 13 |
{"type": "markdown", "id": "cell_dba782593110", "created_at": "2026-07-17T05:10:20+00:00", "title": "Executive summary", "pinned": true, "pinned_at": "2026-07-17T05:10:21+00:00"}
|
| 14 |
-->
|
| 15 |
+
This reproduction does not confirm the six-claim package: Claim 1 is falsified as written by a mismatched formula and exact endpoint failure; Claims 2 and 3 are also falsified by moment errors and a junta counterexample. Claim 4 remains unresolved beyond a failed decoder proof component. **Claim 5 is verified** by a complete multiplicity-weighted coupling that covers Definition 5.1's random examples, duplicate queries, randomized query batches, and stochastic labels while preserving the stated sample rate; it also identifies and repairs an omission in Appendix E's uniform-support construction. Claim 6's computational framing is verified. The upgraded empirical result is a five-seed paired campaign at `d=50`, width 1024, and 100,000 steps per arm. For parity-25, PDS reached mean clean-test accuracy **0.9385 +/- 0.0196 SD** versus **0.5006 +/- 0.0025** for uniform training; all 5/5 PDS runs and 0/5 uniform runs exceeded 0.80. For the paper's `f9` junta, PDS reached **0.8795 +/- 0.2066** versus **0.5052 +/- 0.0036**; PDS exceeded 0.80 in 4/5 runs while uniform did so in 0/5. All five paired effects were positive, but one PDS junta run ended at 0.5116. This is strong finite optimization-mechanism evidence, not an independent proof of the complexity theorems.
|
| 16 |
|
| 17 |
## Scope & cost
|
| 18 |
|
pages/executive-summary/page.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
| 5 |
<!-- trackio-cell
|
| 6 |
{"type": "markdown", "id": "cell_09d93ca3dd30", "created_at": "2026-07-21T17:35:14+00:00", "title": "Executive summary", "pinned": true, "pinned_at": "2026-07-21T17:35:15+00:00"}
|
| 7 |
-->
|
| 8 |
-
This five-seed reproduction strongly supports the finite optimization mechanism behind positive distribution shift while preserving all theorem-level caveats. At d=50 and 100,000 steps, parity-25 reached 0.9385 +/- 0.0196 SD with PDS versus 0.5006 +/- 0.0025 with uniform training (5/5 versus 0/5 above 0.80). The paper's f9 junta reached 0.8795 +/- 0.2066 versus 0.5052 +/- 0.0036 (4/5 versus 0/5 above 0.80); one disclosed PDS seed remained near chance. **Claim 1 is nevertheless falsified as written:** its complexity formula is not the theorem's formula, and the claimed explicit decoder fails valid empty/full-support parity endpoints, with 0% full-support recovery.
|
| 9 |
|
| 10 |
## Scope & cost
|
| 11 |
|
|
@@ -13,8 +13,8 @@ This five-seed reproduction strongly supports the finite optimization mechanism
|
|
| 13 |
|---|---|---|
|
| 14 |
| Neural scope | 2 tasks x 2 regimes x 5 paired seeds; d=50; width 1024; 100k steps; 6.4M fresh examples/arm | Paper's maximum displayed 1M-step protocol |
|
| 15 |
| Compute | Seed 0 public T4 Job; seeds 1-4 local H100 | Not fully reported |
|
| 16 |
-
| Theory | Frozen source audit
|
| 17 |
-
| Outcome |
|
| 18 |
| HF evidence | Job, existing artifact Bucket, checksum-verified v3 bundle | -- |
|
| 19 |
|
| 20 |
|
|
|
|
| 5 |
<!-- trackio-cell
|
| 6 |
{"type": "markdown", "id": "cell_09d93ca3dd30", "created_at": "2026-07-21T17:35:14+00:00", "title": "Executive summary", "pinned": true, "pinned_at": "2026-07-21T17:35:15+00:00"}
|
| 7 |
-->
|
| 8 |
+
This five-seed reproduction strongly supports the finite optimization mechanism behind positive distribution shift while preserving all theorem-level caveats. At d=50 and 100,000 steps, parity-25 reached 0.9385 +/- 0.0196 SD with PDS versus 0.5006 +/- 0.0025 with uniform training (5/5 versus 0/5 above 0.80). The paper's f9 junta reached 0.8795 +/- 0.2066 versus 0.5052 +/- 0.0036 (4/5 versus 0/5 above 0.80); one disclosed PDS seed remained near chance. **Claim 1 is nevertheless falsified as written:** its complexity formula is not the theorem's formula, and the claimed explicit decoder fails valid empty/full-support parity endpoints, with 0% full-support recovery. Claim 5 is now independently verified by a full multiplicity-weighted coupling for arbitrary randomized nonadaptive batches and stochastic labels; this proof repairs a support-uniformity omission in Appendix E without changing the stated rate.
|
| 9 |
|
| 10 |
## Scope & cost
|
| 11 |
|
|
|
|
| 13 |
|---|---|---|
|
| 14 |
| Neural scope | 2 tasks x 2 regimes x 5 paired seeds; d=50; width 1024; 100k steps; 6.4M fresh examples/arm | Paper's maximum displayed 1M-step protocol |
|
| 15 |
| Compute | Seed 0 public T4 Job; seeds 1-4 local H100 | Not fully reported |
|
| 16 |
+
| Theory | Frozen source audit, counterexamples, and a complete repaired proof of Theorems 5.2-5.3 | Independent reconstruction of every formal proof |
|
| 17 |
+
| Outcome | Claims 1-3 falsified as written; Claim 5 verified; large but unstable finite neural effects | General computational/statistical separation |
|
| 18 |
| HF evidence | Job, existing artifact Bucket, checksum-verified v3 bundle | -- |
|
| 19 |
|
| 20 |
|
scripts/namq_rdspac_coupling_audit.py
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Stress-test the multiplicity-weighted NA-MQ -> R-DS-PAC coupling.
|
| 3 |
+
|
| 4 |
+
The proof is distributional; this executable checks its finite coupon event for
|
| 5 |
+
adversarial multiplicity patterns and checks the stochastic-label transcript law.
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
from __future__ import annotations
|
| 9 |
+
|
| 10 |
+
import argparse
|
| 11 |
+
import json
|
| 12 |
+
import math
|
| 13 |
+
from pathlib import Path
|
| 14 |
+
|
| 15 |
+
import numpy as np
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def required_draws(m: int, delta: float) -> int:
|
| 19 |
+
return math.ceil(8.0 * m * math.log(2.0 * m / delta))
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def multiplicities(rng: np.random.Generator, trial: int) -> np.ndarray:
|
| 23 |
+
m = int(rng.integers(1, 257))
|
| 24 |
+
mode = trial % 4
|
| 25 |
+
if mode == 0: # all queries distinct
|
| 26 |
+
return np.ones(m, dtype=np.int64)
|
| 27 |
+
k = int(rng.integers(1, m + 1))
|
| 28 |
+
counts = np.ones(k, dtype=np.int64)
|
| 29 |
+
if k == m:
|
| 30 |
+
return counts
|
| 31 |
+
remaining = m - k
|
| 32 |
+
if mode == 1: # one maximally repeated query
|
| 33 |
+
counts[0] += remaining
|
| 34 |
+
elif mode == 2: # highly skewed Zipf allocation
|
| 35 |
+
weights = 1.0 / np.arange(1, k + 1, dtype=float) ** 1.4
|
| 36 |
+
counts += rng.multinomial(remaining, weights / weights.sum())
|
| 37 |
+
else: # random overdispersed allocation
|
| 38 |
+
weights = rng.dirichlet(np.full(k, 0.25))
|
| 39 |
+
counts += rng.multinomial(remaining, weights)
|
| 40 |
+
return counts
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def coupon_stress(rng: np.random.Generator, trials: int, delta: float) -> dict:
|
| 44 |
+
failures = 0
|
| 45 |
+
worst_margin = None
|
| 46 |
+
largest_union_bound = 0.0
|
| 47 |
+
modes = {"all_distinct": 0, "one_heavy": 0, "zipf": 0, "dirichlet": 0}
|
| 48 |
+
|
| 49 |
+
for trial in range(trials):
|
| 50 |
+
counts = multiplicities(rng, trial)
|
| 51 |
+
m = int(counts.sum())
|
| 52 |
+
draws = required_draws(m, delta)
|
| 53 |
+
probabilities = counts / m
|
| 54 |
+
observed = rng.multinomial(draws, probabilities)
|
| 55 |
+
margin = int(np.min(observed - counts))
|
| 56 |
+
worst_margin = margin if worst_margin is None else min(worst_margin, margin)
|
| 57 |
+
failures += int(np.any(observed < counts))
|
| 58 |
+
modes[list(modes)[trial % 4]] += 1
|
| 59 |
+
|
| 60 |
+
# Chernoff: P[X_u<c_u] <= exp(-c_u(a-1)^2/(2a)),
|
| 61 |
+
# where E[X_u] >= a*c_u and a = 8 log(2m/delta).
|
| 62 |
+
a = 8.0 * math.log(2.0 * m / delta)
|
| 63 |
+
union_bound = float(np.exp(-counts * (a - 1.0) ** 2 / (2.0 * a)).sum())
|
| 64 |
+
largest_union_bound = max(largest_union_bound, union_bound)
|
| 65 |
+
|
| 66 |
+
return {
|
| 67 |
+
"trials": trials,
|
| 68 |
+
"delta_per_trial": delta,
|
| 69 |
+
"multiplicity_modes": modes,
|
| 70 |
+
"coupon_failures": failures,
|
| 71 |
+
"empirical_failure_rate": failures / trials,
|
| 72 |
+
"worst_minimum_surplus": worst_margin,
|
| 73 |
+
"largest_chernoff_union_bound": largest_union_bound,
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def stochastic_transcript_stress(rng: np.random.Generator, trials: int, delta: float) -> dict:
|
| 78 |
+
# Ordered list contains duplicates. Each occurrence must receive a fresh
|
| 79 |
+
# stochastic label, not a copied label from the first occurrence.
|
| 80 |
+
query_order = np.array([0, 1, 0, 2, 1, 0], dtype=np.int64)
|
| 81 |
+
counts = np.bincount(query_order)
|
| 82 |
+
label_probabilities = np.array([0.2, 0.6, 0.85])
|
| 83 |
+
m = len(query_order)
|
| 84 |
+
draws = required_draws(m, delta)
|
| 85 |
+
|
| 86 |
+
direct = np.empty((trials, m), dtype=float)
|
| 87 |
+
reconstructed = np.empty((trials, m), dtype=float)
|
| 88 |
+
coverage_failures = 0
|
| 89 |
+
for t in range(trials):
|
| 90 |
+
direct[t] = rng.binomial(1, label_probabilities[query_order])
|
| 91 |
+
observed = rng.multinomial(draws, counts / m)
|
| 92 |
+
if np.any(observed < counts):
|
| 93 |
+
coverage_failures += 1
|
| 94 |
+
reconstructed[t] = np.nan
|
| 95 |
+
continue
|
| 96 |
+
pools = [rng.binomial(1, label_probabilities[u], size=int(counts[u])) for u in range(3)]
|
| 97 |
+
offsets = np.zeros(3, dtype=int)
|
| 98 |
+
for j, u in enumerate(query_order):
|
| 99 |
+
reconstructed[t, j] = pools[u][offsets[u]]
|
| 100 |
+
offsets[u] += 1
|
| 101 |
+
|
| 102 |
+
valid = ~np.isnan(reconstructed).any(axis=1)
|
| 103 |
+
direct = direct[valid]
|
| 104 |
+
reconstructed = reconstructed[valid]
|
| 105 |
+
direct_cov = np.cov(direct, rowvar=False, bias=True)
|
| 106 |
+
reconstructed_cov = np.cov(reconstructed, rowvar=False, bias=True)
|
| 107 |
+
mean_gap = float(np.max(np.abs(direct.mean(axis=0) - reconstructed.mean(axis=0))))
|
| 108 |
+
covariance_gap = float(np.max(np.abs(direct_cov - reconstructed_cov)))
|
| 109 |
+
target_gap = float(np.max(np.abs(reconstructed.mean(axis=0) - label_probabilities[query_order])))
|
| 110 |
+
|
| 111 |
+
return {
|
| 112 |
+
"trials": trials,
|
| 113 |
+
"query_order": query_order.tolist(),
|
| 114 |
+
"multiplicities": counts.tolist(),
|
| 115 |
+
"label_probabilities": label_probabilities.tolist(),
|
| 116 |
+
"training_draws": draws,
|
| 117 |
+
"coverage_failures": coverage_failures,
|
| 118 |
+
"valid_transcripts": int(valid.sum()),
|
| 119 |
+
"max_direct_vs_reconstructed_mean_gap": mean_gap,
|
| 120 |
+
"max_direct_vs_reconstructed_covariance_gap": covariance_gap,
|
| 121 |
+
"max_reconstructed_vs_target_mean_gap": target_gap,
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
def main() -> None:
|
| 126 |
+
parser = argparse.ArgumentParser()
|
| 127 |
+
parser.add_argument("--seed", type=int, default=20260722)
|
| 128 |
+
parser.add_argument("--coupon-trials", type=int, default=10_000)
|
| 129 |
+
parser.add_argument("--transcript-trials", type=int, default=50_000)
|
| 130 |
+
parser.add_argument("--delta", type=float, default=0.05)
|
| 131 |
+
parser.add_argument("--output", type=Path, default=Path("outputs/namq_rdspac_coupling_audit.json"))
|
| 132 |
+
args = parser.parse_args()
|
| 133 |
+
|
| 134 |
+
rng = np.random.default_rng(args.seed)
|
| 135 |
+
coupon = coupon_stress(rng, args.coupon_trials, args.delta)
|
| 136 |
+
transcript = stochastic_transcript_stress(rng, args.transcript_trials, args.delta)
|
| 137 |
+
checks = {
|
| 138 |
+
"all_coupon_stress_trials_covered": coupon["coupon_failures"] == 0,
|
| 139 |
+
"analytic_union_bound_below_delta": coupon["largest_chernoff_union_bound"] <= args.delta,
|
| 140 |
+
"stochastic_transcripts_covered": transcript["coverage_failures"] == 0,
|
| 141 |
+
"transcript_means_match": transcript["max_direct_vs_reconstructed_mean_gap"] < 0.02,
|
| 142 |
+
"transcript_covariances_match": transcript["max_direct_vs_reconstructed_covariance_gap"] < 0.02,
|
| 143 |
+
"reconstructed_means_match_target": transcript["max_reconstructed_vs_target_mean_gap"] < 0.02,
|
| 144 |
+
}
|
| 145 |
+
result = {
|
| 146 |
+
"audit": "multiplicity-weighted NA-MQ to R-DS-PAC coupling",
|
| 147 |
+
"seed": args.seed,
|
| 148 |
+
"formula": "N=ceil(8*m*log(2*m/delta)); D'_Q(u)=c_u/m",
|
| 149 |
+
"coupon_stress": coupon,
|
| 150 |
+
"stochastic_label_transcript_stress": transcript,
|
| 151 |
+
"checks": checks,
|
| 152 |
+
"all_checks_pass": all(checks.values()),
|
| 153 |
+
}
|
| 154 |
+
args.output.parent.mkdir(parents=True, exist_ok=True)
|
| 155 |
+
args.output.write_text(json.dumps(result, indent=2) + "\n")
|
| 156 |
+
print(json.dumps(result, indent=2))
|
| 157 |
+
if not result["all_checks_pass"]:
|
| 158 |
+
raise SystemExit(1)
|
| 159 |
+
|
| 160 |
+
|
| 161 |
+
if __name__ == "__main__":
|
| 162 |
+
main()
|