From 1a6c9dac1ad2693ce616aa1613638fe572d057ca Mon Sep 17 00:00:00 2001 From: LightChainr Date: Sat, 12 Sep 2026 15:43:04 +0800 Subject: [PATCH] N580: test independently bounded rung-specific leakage and correct P3 claim boundaries Executed same-block C2 sensitivity, not a common-ratio fit. Seven candidate images miss the simultaneous nominal mean ellipsoid even at |H8/H4|<=1; bare aspect remains compatible. Includes finite-cone projection argument, high-precision KKT checks, three analytic regression controls, generated summary and P3 correction addendum. --- .../CORRECTIONS-20260912.md | 63 ++++++ .../p3-projective-inference/README.md | 126 +++++------ notes/n580-rungwise-leakage-20260912.md | 126 +++++++++++ .../n580-rungwise-leakage-summary.json | 23 ++ scripts/n580_rungwise_leakage.py | 210 ++++++++++++++++++ tests/test_n580_rungwise_leakage.py | 35 +++ 6 files changed, 507 insertions(+), 76 deletions(-) create mode 100644 docs/manuscripts/p3-projective-inference/CORRECTIONS-20260912.md create mode 100644 notes/n580-rungwise-leakage-20260912.md create mode 100644 results/research-control-20260912/n580-rungwise-leakage-summary.json create mode 100644 scripts/n580_rungwise_leakage.py create mode 100644 tests/test_n580_rungwise_leakage.py diff --git a/docs/manuscripts/p3-projective-inference/CORRECTIONS-20260912.md b/docs/manuscripts/p3-projective-inference/CORRECTIONS-20260912.md new file mode 100644 index 00000000..ef74a5b4 --- /dev/null +++ b/docs/manuscripts/p3-projective-inference/CORRECTIONS-20260912.md @@ -0,0 +1,63 @@ +# P3 correction addendum — 2026-09-12 + +The historical manuscript/tables are retained, but are NOT submission-ready. +This addendum supersedes the incompatible claims listed below; it is not a +claim that the entire manuscript has been rewritten or externally reviewed. + +1. **Signed line versus ray.** The existing a in R model is a signed line. +A cone or a bounded nuisance image has different inference geometry. A general +one-parameter family of directions need not be a linear subspace. + +2. **Singular covariance.** A pseudoinverse alone is not a test. In exact-support +mode enforce U0^T(y-Va)=0, then use df=rank(S)-rank(W V Z), with Z the null +basis of the deterministic amplitude constraints. Empirical low rank does not +establish deterministic constraints. #703 now validates PSD and refuses an +undeclared singular/truncated policy. Saturated df=0 models have exact residual +zero after numerical consistency checking; roundoff is not a rejection. + +3. **Fieller equivalence.** On the same two coordinates the GLS line statistic +is Fieller's contrast squared. The three-rung gain is from additional data and +changed nuisance assumptions, not from defeating correct Fieller inference or +recovering information destroyed by the ratio parameterization itself. +A shared random stream is not required for a joint covariance: independent +runs have zero cross-covariance when independence is justified; coupled runs +require the actual covariance. Use source provenance, not matching batch IDs. + +4. **Recovered covariance.** #703 recovered cov(r2,r4)=5.5621485097801135e-9 +from existing shards. Bare aspect is no longer 'undetermined because covariance +is missing': the retrospective pure-line score is D=10.8644599/2, +p=.00437333, equivalent 2.84990 sigma, NOT rejected at the nominal 3-sigma +cutoff. The original frozen two-rung underpowered verdict is unchanged. +No new replay is needed for this entry. + +5. **Curvature and sign.** Raw curvature z=-3.11062 is a one-coordinate contrast, +not the two-df model test. The sign of a convex v is reversed by negative a; +'negative curvature excludes every signed convex-shape model' is invalid. +An annihilator removes an algebraic nuisance; it does not guarantee adequate +power or immunity from covariance uncertainty. + +6. **Common bound versus common ratio.** |rho_i|<=B for every rung does not +imply rho_1=rho_2=rho_4. Common-ratio results are labelled sensitivities. +The new rungwise bounded analysis in notes/n580-rungwise-leakage-20260912.md +removes that equality assumption. Even at B=1 seven of eight candidate images +miss a common nominal 99.73% three-dimensional mean ellipsoid. Do not assign +an ordinary chi-square law with guessed residual df to the bounded cones. + +7. **Novelty and literature.** The linear algebra is classical. Do not claim +ratio testing is ubiquitous, or that no multivariate Fieller analogue exists, +from an unverified gap. Use #701/#695's retrieved sources only at their actual +PRIMARY_TEXT_READ/ABSTRACT_ONLY level. Frame the contribution around this +worked observation/design failure and its corrected inference, not a newly +invented general statistical theory. + +8. **Design.** N650 does not cleanly identify angular H8 because angle and +Smith class move together (#589). Three rows cannot identify four unconstrained +columns (constant, H4, H8, Smith nuisance). Also, two unanchored model cones +both contain zero: their minimum pairwise distance is zero. A maximin sample +allocation needs a justified nonzero signal range, a fixed-SNR criterion, or +a source-anchored design objective. Do not hide this by assuming a strong +amplitude or calling an arbitrary normalization physical. + +All recovered and new bounded scores are same-block C2 analyses with estimated +covariance. They do not increase the count of independent experiments, identify +a continuum field, prove a threshold law, or turn this draft into a submission. diff --git a/docs/manuscripts/p3-projective-inference/README.md b/docs/manuscripts/p3-projective-inference/README.md index 47b655e2..909439b2 100644 --- a/docs/manuscripts/p3-projective-inference/README.md +++ b/docs/manuscripts/p3-projective-inference/README.md @@ -1,76 +1,50 @@ -# P3 — Test the ray, not the ratio - -Draft manuscript workspace for portfolio track **P3**, arising from -[issue #579](https://github.com/LightChainr/Matching-One/issues/579). - -**Target venue:** *Physical Review E*. - -| File | Role | -|---|---| -| [`manuscript.md`](manuscript.md) | the draft, sections 1–8 | -| [`tables.md`](tables.md) | **generated** — every numerical table (T1–T5) | -| `results/p3-projective-inference-manuscript/latest.json` | the machine-readable evidence artifact | -| `results/aspect-ladder-n580/latest.json` | the frozen Fieller scoring (§4.1, §4.3) | -| `results/aspect-ladder-n580-projective/latest.json` | the projective rescoring (§4.4–§4.6) | -| `predictions/aspect_ladder_n580_20260905.yaml` | the frozen design, competitor rays, declared systematic | -| `scripts/projective_inference.py` | the statistic: pseudo-inverse, subspace residual, χ² tail | -| `scripts/aspect_ladder_projective_rescore.py` | the N=580 rescoring | -| `scripts/p3_manuscript_evidence_table.py` | assembles the artifact and renders the tables | -| `tests/test_projective_inference.py` | 8 tests, including the Fieller identity anchor | -| `tests/test_aspect_ladder_projective_rescore.py` | 11 tests on the rescoring | -| `tests/test_p3_manuscript_evidence_table.py` | 11 tests locking the assembly and the tables | -| `notes/aspect-ladder-n580-projective-rescore-20260906.md` | the working note the draft is built from | - -## Ground rules honoured here - -No Monte Carlo was run for this manuscript and no frozen design was reopened. `p3_manuscript_evidence_table.py` -reads three committed artifacts and derives only statements that follow exactly from them; it rescores nothing -that was not already rescored and committed under #579. The one computation it performs that is not a lookup is -the two-entry control of §4.3 — the projective statistic restricted to the pair of rungs the frozen test used — -and that exists to *remove* a possible explanation for the paper's headline, not to supply one. - -No number in the draft is hand-typed into a generated table. `tables.md` is rendered from the artifact and -`test_the_rendered_tables_do_not_drift_from_the_artifact` fails if the two separate. The summary tables inside -`manuscript.md` §4.4–§4.6 restate T3–T5 for readability; the generated tables are authoritative. - -## Section readiness - -| § | Content | Status | -|---|---|---| -| Abstract | claim and scope | draft complete | -| 1 | the problem: proportions, ratios, conditioning, the design pathology | complete | -| 2.1–2.4 | ray, subspace, residual distance, Fieller as the 2×1 case | complete, proposition proved and tested | -| 2.5 | annihilating functionals | complete | -| 3 | why the ratio framework fails invisibly | complete | -| 4.1–4.2 | the measurement and the eight rays | complete, generated | -| 4.3 | two-entry control | complete, generated, `1.5e-15` | -| 4.4 | verdict table | complete, generated | -| 4.5 | curvature | complete, generated | -| 4.6 | the priced assumption | complete, generated | -| 5 | established / undetermined / not established | complete | -| 6 | the N=650 design consequence | complete; see [#583](https://github.com/LightChainr/Matching-One/issues/583) | -| 7 | reproducibility and preconditions | complete | -| 8 | related work | **one open item**: reference [6] is marked **[LIT]** and needs a primary reading | - -## One correction already applied to this draft - -The `|A₈/A₄|` column of §4.6 first shipped as the raw gap divided by the leakage coefficient, which is the -leading-order form and drops the `(u + 1)` the exact solution carries. It overstated the requirement by 2.4× for -the bare aspect ratio and by 45× for the weight-12 rays, where it read 783 instead of 17.5. The frozen design -records the leakage *per rung with its sign*, which is what makes the exact solve available at all; the fix is in -`required_spin8_ratio`, and `test_every_survivor_of_the_clean_pair_needs_a_large_spin8` now pins the top of the -column below 20 so the leading-order form cannot come back silently. The dichotomy is unchanged. - -## Open items before submission - -1. **Reference [6].** The claim that ratio-testing of aspect-ratio amplitudes is standard practice in the - conformal-invariance finite-size literature is stated from familiarity, not from a primary reading. Either - read and cite specific instances, or weaken §8 to a statement about this repository's own practice. This is - the only unresolved item in the draft and it is deliberately marked rather than quietly asserted. -2. **§5.2's undetermined verdict.** One deterministic replay of the N=580 ladder under the current scorer - recovers `cov(r2, r4)` and settles `bare_aspect_ratio`. The draft is publishable without it — an undetermined - verdict, reported as undetermined, is a legitimate result — but the replay is cheap and would remove the one - soft spot. -3. **Figure.** The draft is currently table-only. One figure would carry §4.4–§4.5 well: the three-rung response - with its jackknife errors, the eight competitor rays normalised through the `r=1` point, and the measured - concavity as a shaded band. Not required for the argument. +# P3 — Covariance-aware comparison of finite-size amplitude laws + +**Current status (2026-09-12): numerical corrections available; manuscript NOT +submission-ready.** Read [CORRECTIONS-20260912.md](CORRECTIONS-20260912.md) +before using the historical manuscript. Target venue remains a proposal, not +an acceptance/readiness claim. Track: #579. + +## Current result + +#703 recovered the complete N580 covariance from the existing delete-one shards, +without simulation. The retrospective three-rung pure-line score for bare aspect +is 10.8644599 on 2 df, nominal p=.00437333: not rejected at the declared nominal +3-sigma threshold. Seven other pure lines are rejected under that contract. +The original frozen two-rung underpowered result remains unchanged. + +A second completed analysis allows independently varying rung-specific H8/H4 +ratios. At a uniform bound B=1, the same seven candidate images remain outside +one nominal 99.73% three-dimensional mean ellipsoid; bare aspect intersects. +This is not a fitted-cone chi-square calibration, a measurement of H8, or a new +independent evidence block. + +## Files to use + +- `notes/n580-complete-covariance-20260912.md` and + `results/research-control-20260912/n580-complete-covariance-summary.json`: + executed covariance recovery and pure-line results. +- `notes/n580-rungwise-leakage-20260912.md` and + `results/research-control-20260912/n580-rungwise-leakage-summary.json`: + independently bounded leakage, projection proof, results and limits. +- `scripts/projective_inference.py`: explicit covariance-support policy; + `scripts/recover_n580_covariance.py`: existing-shard reader; + `scripts/n580_rungwise_leakage.py`: bounded-image calculation. +- `manuscript.md`, `tables.md`, and the original manuscript-evidence JSON: + HISTORICAL draft/evidence assembly, retained rather than silently overwritten. + Their readiness, missing-covariance, common-ratio and sign claims require the + corrections in the addendum. The old assembler does not generate the new tables. +- `predictions/aspect_ladder_n580_20260905.yaml` and + `results/aspect-ladder-n580/`: original freeze/results; do not rewrite history. + +## Remaining writing work, not more N580 production + +Integrate the addendum into the manuscript and a new versioned table assembly. +Separate the frozen two-rung analysis, retrospective pure-line comparison and +rungwise bounded sensitivity. Replace unsupported literature-practice/novelty +claims with the narrow sourced account. The existing #695/#701 retrieval is +input, not proof that all citations were read in full. N650 remains subject to +#589's angular/Smith identifiability question. + +No replay is needed for cov(r2,r4). No new size, free exponent or optional +sample top-up follows from this draft. diff --git a/notes/n580-rungwise-leakage-20260912.md b/notes/n580-rungwise-leakage-20260912.md new file mode 100644 index 00000000..a30cd89d --- /dev/null +++ b/notes/n580-rungwise-leakage-20260912.md @@ -0,0 +1,126 @@ +# N580: seven exclusions survive independently varying bounded H8 leakage + +2026-09-12. Direct analysis following #703; same-block retrospective C2, not +new sampling, not a revised freeze, and not a continuum identification. + +## Question and answer + +A uniform bound on |A8/A4| does not imply the SAME ratio on different moduli. +The common-ratio sensitivity in #703 and the older point-reconciliation column +therefore leave a genuine question: do the exclusions survive rung-specific +ratios? Yes, for B=0.2 and even B=1, against the explicit simultaneous mean +region below. Bare aspect remains compatible, already at B=0. + +The input is #703's recovered mean and full covariance, as committed at +b924b2af94ebb99a058e252df6884594c51da381. Local computation used the published +vector/matrix/rays, not a new local shard replay. All eight B=0 distances +reproduce that artifact. The script reads the committed input directly in a +complete checkout. Historical production data, scores and freezes are unchanged. + +## Model: weaken the unnecessary assumption, not the observation definition + +For each existing positive shape v, let + + mu_i = a v_i (1 + lambda_i rho_i), |rho_i| <= B, + lambda = (1148/21025) * (-1,+1,-1), a in R. + +The three rho_i may differ. A4 still obeys the nominated shape a*v; the only +allowed additional angular contribution here is the declared H8 leakage. +For 0 <= B < 21025/1148, the amplitude sign is preserved at every rung. +For a>=0, the model image is the cone over the eight vertices +v_i*(1+lambda_i*B*t_i), t_i in {-1,+1}; a<=0 gives its negative. An arbitrary +convex combination of vertices gives exactly all independently bounded rho_i. +Thus both amplitude signs are covered, without treating a signed line as a +positive ray. Opposite leakage signs do not reduce this larger set: independent +symmetric bounds absorb each sign. Equality of the ratios would be extra physics. + +The nearest point on either cone can be represented with at most three +linearly independent generating rays in R^3: a conic representation with more +than three can be reduced along a linear dependence until a coefficient is +zero. At the optimum, the positive coefficients satisfy the least-squares +normal equations on their active span. Enumerating supports of sizes 1,2,3 +and the origin therefore includes the global optimum. Both sign cones are +solved, not just whichever sign looks favourable in the observed data. + +The independent numerical optimality check re-solves each selected support at +60 dps and verifies q=S^-1(y-mu), g_j^T q<=0 on ALL eight rays, and mu^T q=0, +for both signs. These are sufficient convex projection conditions. This is a +high-precision numerical check, not an exact rational certificate. + +## A reference region, not an invented cone chi-square law + +Use one three-dimensional Gaussian mean ellipsoid + + E(y) = {mu: (y-mu)^T S^-1 (y-mu) <= 14.156413609126687}. + +Its nominal tail alpha is erfc(3/sqrt(2))=0.002699796063260189. The cutoff is +chi-square with 3 df because this is the full MEAN confidence region, not the +residual df of a fitted cone. With known Gaussian covariance it has the stated +coverage. With this estimated jackknife covariance it is nominal/asymptotic; +no exact finite-sample coverage is asserted. + +The simultaneous statement needs no guessed cone reference distribution: +on the event that E contains the true mean, every model image containing that +mean intersects E. Hence declaring any image disjoint from this SAME region +cannot falsely exclude a true image on that event. This applies simultaneously +to all eight models and nested bounds. It is conservative relative to an +individual 2-df line test, and is not its replacement or a change to the freeze. + +## Executed result + +| Shape | min D at B=0 | min D at B=1 | first B intersecting E | +|---|---:|---:|---:| +| bare aspect | 10.86446 | 5.72524 | 0 | +| no modulus dependence | 89.85851 | 73.37075 | 6.55584 | +| area scaling | 57.51249 | 50.29088 | 5.71612 | +| Q4 weight-4 shape | 55.58771 | 48.31480 | 5.49417 | +| weight-12 E12 | 132.26732 | 131.64755 | 17.33571 | +| weight-12 E4 cubed | 132.22612 | 131.60161 | 17.30638 | +| weight-12 delta | 513.65922 | 511.91617 | 18.31398 | +| weight-8 E8 | 115.80438 | 113.36508 | 14.29176 | + +The artifact also reports B=0.2. Seven images remain disjoint even at B=1. +In particular, under the stated shape-plus-H8 model a Q4 explanation needs +at least one |rho_i| of about 5.49 before it can reach this nominal region; +area scaling needs about 5.72. This is not a measurement of H8, does not +exclude other angular terms or observer errors, and does not refute the Q4 +module as a possible contributor to a different observable. + +Do not confuse these uncertainty-aware intersection bounds with fitting the +observed point exactly. For positive z_i=y_i/v_i and common |lambda_i|=lambda, +point interpolation first occurs at + + B_point = (max z - min z)/(lambda*(max z + min z)). + +This follows by choosing a=(max z+min z)/2 and equalizing the two extreme +relative residuals. Bare aspect has B_point=4.30327, yet B=0 already intersects +E: the point estimate's mismatch is not a rejection at this coverage level. +The earlier common-ratio point requirement must not be promoted into a lower +confidence bound on contamination. + +## Validation and reproduction + +Three inexpensive mathematical controls passed: an identity-covariance toy +with exact projection (42/11,14/11,14/11) and D=2/11; B=0 versus GLS; sign +reversal and nesting. All 24 fixed-bound fits and both endpoints of each +positive B threshold were checked at 60 dps on both cones. Fixed-bound maximum +relative KKT/complementarity residuals were 1.76e-61 and 5.10e-61. Threshold +brackets are numerical 38-step bisections, not exact intervals. + + python scripts/n580_rungwise_leakage.py --summary --source-revision b924b2af94ebb99a058e252df6884594c51da381 + python -m unittest discover -s tests -p 'test_n580_rungwise_leakage.py' + +Omit --summary for fitted means, nuisance witnesses and branch distances. +--output refuses to overwrite an existing file. NumPy/mpmath are sufficient. +The compact generated result is +results/research-control-20260912/n580-rungwise-leakage-summary.json. + +## Decision + +No new N580 sampling or covariance replay is justified by this question. +The seven exclusions are not merely a common-ratio artefact. Bare aspect is +not established; it remains a surviving finite model at the declared evidence +resolution. Further angular acquisition belongs to #589's identifiability +question, not an attempt to push this same block across a preferred cutoff. +The independent next analyses remain #622's within-model shape motion and +#681's restricted finite-torus/cylinder dictionary. Neither needs a GPU. diff --git a/results/research-control-20260912/n580-rungwise-leakage-summary.json b/results/research-control-20260912/n580-rungwise-leakage-summary.json new file mode 100644 index 00000000..7f30cafc --- /dev/null +++ b/results/research-control-20260912/n580-rungwise-leakage-summary.json @@ -0,0 +1,23 @@ +{ + "schema": "matching-one.n580-rungwise-leakage.v1", + "source_path": "results/research-control-20260912/n580-complete-covariance-summary.json", + "input_mean": [0.0009016433036753112, 0.0029109770266212776, 0.004131807633330795], + "input_covariance": [[6.207020770273794e-8,1.3480872826970252e-9,-8.011196220988015e-9],[1.3480872826970252e-9,6.713835319545046e-8,5.5621485097801135e-9],[-8.011196220988015e-9,5.5621485097801135e-9,3.807514679910218e-8]], + "standing": "C2 same-block retrospective sensitivity; not a new experiment or amended freeze", + "model": "mu_i=a*v_i*(1+leak_i*rho_i), signed a, independent |rho_i|<=B", + "leakage": [-0.05460166468489893,0.05460166468489893,-0.05460166468489893], + "reference": {"alpha":0.002699796063260189,"mean_dimension":3,"ellipsoid_cutoff":14.156413609126687,"calibration":"Known Gaussian covariance: simultaneous mean region; estimated jackknife covariance: nominal/asymptotic. NOT a fitted-cone chi-square law."}, + "source_revision_declared": "b924b2af94ebb99a058e252df6884594c51da381", + "fixed_bounds": [0.0,0.2,1.0], + "validation": {"precision_dps":60,"max_kkt_violation_relative":1.752675059801698e-61,"max_complementarity_relative":5.098343976919491e-61,"boundary_endpoints":"38-step numerical bisection; both endpoints re-solved and KKT checked","scope":"Numerical checks, not exact rational certificates; no local shard replay."}, + "results": { + "bare_aspect_ratio": {"shape":[1,2,4],"minimum_D":[10.86445991488253,9.74509254800503,5.725238696529666],"ellipsoid_intersects":[true,true,true],"first_intersection_B_bracket":[0.0,0.0],"point_interpolation_B":4.303270536830905}, + "no_modulus_dependence": {"shape":[1,1,1],"minimum_D":[89.85851023621422,86.39871390455572,73.37075188747089],"ellipsoid_intersects":[false,false,false],"first_intersection_B_bracket":[6.55584366158984,6.555843661656468],"point_interpolation_B":11.753112511511077}, + "plain_area_scaling": {"shape":[1,4,16],"minimum_D":[57.512493327374884,56.0949653359015,50.29088287143035],"ellipsoid_intersects":[false,false,false],"first_intersection_B_bracket":[5.716120946982922,5.71612094704955],"point_interpolation_B":10.159333776915771}, + "q4_jordan_weight4": {"shape":[1,2.75,10.9908008589],"minimum_D":[55.58771053243131,54.15771504988703,48.31479684287533],"ellipsoid_intersects":[false,false,false],"first_intersection_B_bracket":[5.494173654615238,5.494173654681866],"point_interpolation_B":8.71507766254339}, + "weight12_E12": {"shape":[1,32.515625,2080.30719731],"minimum_D":[132.26732359383956,132.14876716559357,131.64755162607125],"ellipsoid_intersects":[false,false,false],"first_intersection_B_bracket":[17.335707481691877,17.335707481758504],"point_interpolation_B":18.23395057396472}, + "weight12_E4_cubed": {"shape":[1,20.796875,1327.6635036],"minimum_D":[132.22611687853123,132.1066545820167,131.60160831283216],"ellipsoid_intersects":[false,false,false],"first_intersection_B_bracket":[17.306379074781873,17.3063790748485],"point_interpolation_B":18.18846733903283}, + "weight12_delta": {"shape":[1,0.125,2.79010739704e-5],"minimum_D":[513.6592181764852,513.3257486417529,511.9161666098316],"ellipsoid_intersects":[false,false,false],"first_intersection_B_bracket":[18.313976744188892,18.31397674425552],"point_interpolation_B":18.314236913782494}, + "weight8_E8": {"shape":[1,7.5625,120.79770352],"minimum_D":[115.80437790454678,115.33656826633613,113.36508234095133],"ellipsoid_intersects":[false,false,false],"first_intersection_B_bracket":[14.291762888017313,14.291762888083941],"point_interpolation_B":16.97570720119975} + } +} diff --git a/scripts/n580_rungwise_leakage.py b/scripts/n580_rungwise_leakage.py new file mode 100644 index 00000000..a84fce79 --- /dev/null +++ b/scripts/n580_rungwise_leakage.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python3 +"""Bounded rung-specific H8 sensitivity, not a common-ratio fit or fresh experiment. + +For fixed positive v, fit mu_i=a*v_i*(1+leak_i*rho_i), |rho_i|<=B, +with independently varying rho_i and a of either sign. Each sign is a cone +on eight box vertices. Conic Caratheodory in R^3 permits <=3 active rays; +enumerating all such supports gives the global projection onto each cone. +The reported reference is intersection with ONE 3-d mean ellipsoid, not a +chi-square calibration for the fitted cone. Estimated covariance makes that +reference nominal/asymptotic. No stochastic resampling, simulation, or refit of v. +""" +from __future__ import annotations +import argparse +import itertools +import json +import math +from pathlib import Path +import numpy as np +from mpmath import mp + +ROOT = Path(__file__).resolve().parents[1] +SOURCE = ROOT/'results/research-control-20260912/n580-complete-covariance-summary.json' +LEAK = np.array([-1., 1., -1.])*(1148/21025) +SIGNS = np.array(list(itertools.product((-1,1), repeat=3))) +SUPPORTS = [s for k in (1,2,3) for s in itertools.combinations(range(8),k)] + + +def cone_projection(y, covariance, v, bound, leak=LEAK): + """Global numerical projection; return both sign branches for KKT checking.""" + y,s,v,leak = (np.asarray(x,dtype=float) for x in (y,covariance,v,leak)) + if y.shape!=(3,) or s.shape!=(3,3) or v.shape!=(3,) or leak.shape!=(3,): + raise ValueError('three rungs required') + if not all(np.isfinite(x).all() for x in (y,s,v,leak)) or np.any(v<=0): + raise ValueError('finite inputs and positive model shape required') + if not math.isfinite(bound) or bound<0 or bound*np.max(np.abs(leak))>=1: + raise ValueError('bound must preserve the sign of each shape entry') + if not np.allclose(s,s.T,rtol=1e-13,atol=0): + raise ValueError('covariance must be symmetric') + L=np.linalg.cholesky(s) + wy=np.linalg.solve(L,y) + vertices=(v*(1+bound*SIGNS*leak)).T + positive=np.linalg.solve(L,vertices) + branches=[] + for sign in (1,-1): + G=sign*positive + lengths=np.linalg.norm(G,axis=0) + Gn=G/lengths + best={'distance':float(wy@wy),'active':[],'sign':sign} + for active in SUPPORTS: + X=Gn[:,active] + coeff,_,rank,_=np.linalg.lstsq(X,wy,rcond=1e-12) + if rank!=len(active) or np.min(coeff)<-1e-12*max(1,np.linalg.norm(wy)): + continue + coeff=np.maximum(coeff,0) + residual=wy-X@coeff + d=float(residual@residual) + if dmp.mpf('1e-35'): + raise ArithmeticError('cone projection failed high-precision KKT check') + distance=((y-mu).T*q)[0] + if abs(distance-branch['distance'])>mp.mpf('1e-8')*max(1,distance): + raise ArithmeticError('float and high-precision projections disagree') + amplitude=branch['sign']*mp.fsum(coeff) + rho=[(mu[i]/(amplitude*vv[i])-1)/ll[i] for i in range(3)] if amplitude else None + checked.append({'distance':float(distance),'sign':branch['sign'], + 'amplitude':float(amplitude),'mean':[float(t) for t in mu], + 'rho':[float(t) for t in rho] if rho is not None else None, + 'kkt_violation_relative':float(kkt),'complementarity_relative':float(complement)}) + best=min(checked,key=lambda b:b['distance']) + return {**{k:best[k] for k in ('distance','sign','amplitude','mean','rho')}, + 'max_kkt_violation_relative':max(b['kkt_violation_relative'] for b in checked), + 'max_complementarity_relative':max(b['complementarity_relative'] for b in checked), + 'branch_distances':[b['distance'] for b in checked]} + + +def ellipsoid_cutoff(): + """3-d Gaussian mean ellipsoid with alpha equal to the two-sided 3-sigma tail.""" + with mp.workdps(50): + alpha=mp.erfc(3/mp.sqrt(2)); lo=mp.mpf(0); hi=mp.mpf(100) + for _ in range(180): + mid=(lo+hi)/2 + if mp.gammainc(mp.mpf('1.5'),mid/2,mp.inf,regularized=True)>alpha: + lo=mid + else: + hi=mid + return float(alpha),float((lo+hi)/2) + + +def analyze(payload): + y,s=payload['response_vector'],payload['covariance'] + alpha,cutoff=ellipsoid_cutoff(); results={} + for name,source in payload['competitors'].items(): + v=source['ray']; rows={} + for bound in (0.,.2,1.): + proj=cone_projection(y,s,v,bound) + checked=high_precision_check(y,s,v,bound,proj) + rows[str(bound)]={**checked,'ellipsoid_intersects':checked['distance']<=cutoff} + if rows['0.0']['distance']<=cutoff: + interval=[0.,0.] + else: + lo=0.; hi=(1-1e-8)/max(abs(LEAK)) + if cone_projection(y,s,v,hi)['distance']>cutoff: + raise ArithmeticError('upper bound does not reach the ellipsoid') + for _ in range(38): + mid=(lo+hi)/2 + if cone_projection(y,s,v,mid)['distance']>cutoff: + lo=mid + else: + hi=mid + interval=[lo,hi] + endpoint_D=[high_precision_check(y,s,v,b,cone_projection(y,s,v,b))['distance'] for b in interval] + if not endpoint_D[0]>cutoff>=endpoint_D[1]: + raise ArithmeticError('threshold bracket failed high-precision recheck') + z=np.asarray(y)/np.asarray(v) + # Closed-form smallest uniform bound that interpolates the observed mean. + point_bound=(max(z)-min(z))/(max(z)+min(z))/max(abs(LEAK)) if np.all(z>0) else None + results[name]={'shape':v,'fixed_bounds':rows, + 'first_ellipsoid_intersection_B_bracket':interval, + 'point_interpolation_B':float(point_bound) if point_bound is not None else None} + return {'schema':'matching-one.n580-rungwise-leakage.v1', + 'source_path':str(SOURCE.relative_to(ROOT)), + 'input_mean':y,'input_covariance':s, + 'standing':'C2 same-block retrospective sensitivity; not a new experiment or amended freeze', + 'model':'mu_i=a*v_i*(1+leak_i*rho_i), signed a, independent |rho_i|<=B', + 'leakage':LEAK.tolist(), + 'reference':{'alpha':alpha,'mean_dimension':3,'ellipsoid_cutoff':cutoff, + 'calibration':'Known Gaussian covariance: simultaneous mean region; estimated jackknife covariance: nominal/asymptotic. NOT a fitted-cone chi-square law.'}, + 'results':results} + + +def summarize(result): + """Compact generated artifact; --summary changes storage, not the fit.""" + rows=result['results']; checks=[f for row in rows.values() for f in row['fixed_bounds'].values()] + result={k:v for k,v in result.items() if k!='results'} + result['fixed_bounds']=[0.,.2,1.] + result['validation']={ + 'precision_dps':60, + 'max_kkt_violation_relative':max(f['max_kkt_violation_relative'] for f in checks), + 'max_complementarity_relative':max(f['max_complementarity_relative'] for f in checks), + 'boundary_endpoints':'38-step numerical bisection; both endpoints re-solved and KKT checked', + 'scope':'Numerical checks, not exact rational certificates; no local shard replay.'} + result['results']={name:{ + 'shape':row['shape'], + 'minimum_D':[row['fixed_bounds'][str(b)]['distance'] for b in (0.,.2,1.)], + 'ellipsoid_intersects':[row['fixed_bounds'][str(b)]['ellipsoid_intersects'] for b in (0.,.2,1.)], + 'first_intersection_B_bracket':row['first_ellipsoid_intersection_B_bracket'], + 'point_interpolation_B':row['point_interpolation_B']} for name,row in rows.items()} + return result + + +def main(): + parser=argparse.ArgumentParser(description=__doc__) + parser.add_argument('--source',type=Path,default=SOURCE) + parser.add_argument('--output',type=Path) + parser.add_argument('--summary',action='store_true') + parser.add_argument('--source-revision',help='Provenance annotation supplied by caller, not inferred') + args=parser.parse_args(); result=analyze(json.loads(args.source.read_text())) + try: + result['source_path']=str(args.source.resolve().relative_to(ROOT)) + except ValueError: + result['source_path']=str(args.source) + if args.source_revision: + result['source_revision_declared']=args.source_revision + if args.summary: + result=summarize(result) + text=json.dumps(result,indent=2,allow_nan=False)+'\n' + if args.output: + # Never overwrite a committed or pre-existing result by default. + args.output.parent.mkdir(parents=True,exist_ok=True) + with args.output.open('x') as f: + f.write(text) + else: + print(text,end='') + +if __name__=='__main__': + main() diff --git a/tests/test_n580_rungwise_leakage.py b/tests/test_n580_rungwise_leakage.py new file mode 100644 index 00000000..12f3d7eb --- /dev/null +++ b/tests/test_n580_rungwise_leakage.py @@ -0,0 +1,35 @@ +"""Cheap mathematical controls of the cone projection, not a data-rescoring suite.""" +from pathlib import Path +import sys +import unittest +import numpy as np +sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'scripts')) +import n580_rungwise_leakage as m +import projective_inference as p + +class ConeTests(unittest.TestCase): + def test_exact_identity_covariance_toy(self): + y=[4,1,1];s=np.eye(3);v=[1,1,1];leak=[1,1,1] + got=m.cone_projection(y,s,v,.5,leak) + checked=m.high_precision_check(y,s,v,.5,got,leak) + self.assertAlmostEqual(checked['distance'],2/11,places=13) + np.testing.assert_allclose(checked['mean'],[42/11,14/11,14/11],rtol=1e-13) + + def test_bound_zero_equals_signed_gls_line(self): + y=[.3,.7,.9];s=[[1,.1,0],[.1,2,.1],[0,.1,1]];v=[1,2,4] + got=m.cone_projection(y,s,v,0) + expected=p.ray_residual(y,s,v)['statistic'] + self.assertAlmostEqual(got['distance'],expected,places=13) + + def test_sign_reversal_and_nested_bounds(self): + y=np.array([4,1,1]);s=np.eye(3);v=[1,1,1];leak=[1,1,1] + previous=float('inf') + for b in (0,.1,.3,.5,.7): + value=m.cone_projection(y,s,v,b,leak)['distance'] + self.assertLessEqual(value,previous+1e-12) + self.assertAlmostEqual(value,m.cone_projection(-y,s,v,b,leak)['distance'],places=13) + previous=value + self.assertLess(previous,1e-20) + +if __name__=='__main__': + unittest.main()