Skip to content

feat(api): exact Sobol' pair estimator + domain⊥distribution split (T51pq, T52xx) → 0.1.0a8 - #50

Merged
JavierGOrdonnez merged 2 commits into
developfrom
jgo/port-t31rb-domain-split
Sep 30, 2026
Merged

JavierGOrdonnez merged 2 commits into
developfrom
jgo/port-t31rb-domain-split

Conversation

@JavierGOrdonnez

Copy link
Copy Markdown
Collaborator

What

The two backend tranches mmux_vite grew after the v1 port, ported to itis-sumo as one review train, per the owner decision to land both the T31rb estimator and the V26dd domain⊥distribution split now (no defer).

1. 0ef174d — exact arbitrary-d 2nd-order Sobol' pairs + order masses (T51pq, V48tr, B20qt)

The v1 port shipped mmux_vite's closed-form second-order identity, which mmux_vite B26nc proved underdetermined for d≥4 (pair sums collapse to 0 at d=4, negative beyond — typical 4–25-parameter studies produced invalid interactions) and B28pp proved non-translation-invariant (drift ∝ offset when mean≫std, e.g. stress in Pa). Ported from mmux_vite PR#649 (upstream/develop@6eda782d):

  • _saltelli_abc — A/B/C blocks from one 3·d scrambled Sobol' stream (C feeds the pair designs)
  • _saltelli_pair_designs — exact U^ij/V^ij mixed designs; surrogate cost n·(2 + d + d(d−1)), the documented price of pairs EXACT for any d
  • _sobol_algebra — scipy saltelli_2010 parity pinned by test (pooled A/B mean/var, centered products → single estimator for all d; retires the d==1 branch and the runtime scipy.stats.sobol_indices call)
  • _sobol_joint_bootstrap — ONE shared-row resample recomputes every index AND the M1/M2/R masses per replicate (estimator covariance + closure preserved)
  • public: OrderMasses + SobolResult.order_contributions, null exactly at zero sample variance (undefined fractions, never fake (0,0,0))
  • tests: the historic inlined-duplicate Ishigami math replaced by PRODUCTION-helper benchmarks (Ishigami, additive d=8, pair-interaction d=5, pair-quadratic d=10) with 3·CI-scaled tolerances + B26nc degeneracy regression

2. 59cf3c9 BREAKING — domain⊥distribution split (T52xx enforces V26dd)

evaluate_sobol sampled Saltelli A/B from modeller distributions — the conflation the SPEC scope line retires. Now the sensitivity box is domain vocabulary end to end:

  • evaluate_sobol(samples, variables, response, *, domains=None, ...); distributions= is gone (it stays the exclusive input of evaluate_uncertainty)
  • omitted boxes auto-inferred from observed sample bounds + detected scale; explicit boxes echoed verbatim; unknown names → SumoInputError; a column constant in the samples is pinned (never a fabricated box around it, V47st-consistent)
  • draws are uniform / log-uniform (V44ls) via the shared scale_distribution; log⊗normal Sobol sampling and any mean±3σ-derived box die
  • SobolResult: distributions → domains + fixed + effective_config (V21pf inspectable)
  • flip matrix: Sobol's scale flip rides DOMAIN boxes; the NORMAL matrix has no Sobol row by design (2 distribution entry points remain, asserted)

Verification

  • 387 passed full standalone suite (real itis-dakota 6.24.7, nothing mocked), incl. 26-test analytical tier and the 14-test test_sobol_indices.py gate
  • algebra pinned vs scipy to 1e-9 + translation invariance at ~100× output offset
  • V&V report: I7/I8 amended, I11 added, new "Estimator tier" section + M1/M2 gate rows
  • SPEC: V48tr, V26dd enforced, V9gh amended, T51pq/T52xx, B20qt; PORTING.md branch inventory updated

Release

pyproject bumped 0.1.0a7 → 0.1.0a8 (valid alpha, newer than all tags). After merge to develop: tag v0.1.0a8 → CI auto-publishes to TestPyPI, which unblocks the mmux_vite Phase C rewire (pin itis-sumo==0.1.0a8, delete the inline dakota/ + data_preprocessor/ backend).

Consumer impact (mmux_vite Phase C/D)

The FE UQ-panel feeds constant|uniform|normal per Sobol variable; post-V26dd the Sobol section migrates to a bounds editor (T27fr's remaining item). Uniform → DomainSpec(min,max); constant/narrow → omit or pin; normal → drop (auto-inferred domain is the scientifically sane default the split exists to enforce).

Javier Garcia Ordonez and others added 2 commits September 30, 2026 20:49
…51pq)

Port mmux_vite T31rb (PR#649) replacing the v1 closed-form second-order
identity, which mmux_vite B26nc proved underdetermined for d>=4 (pair sums
collapse to 0/negative - B20qt) and non-invariant under f->f+c (B28pp).

- _saltelli_abc: A/B/C blocks from one 3*d scrambled stream (C feeds pairs)
- _saltelli_pair_designs: exact U^ij/V^ij mixed designs, cost n*(2+d+d(d-1))
- _sobol_algebra: scipy saltelli_2010 parity pinned by test; pooled mean/var,
  centered products -> translation-invariant; single estimator for all d
  (retires the d==1 branch and the runtime scipy call)
- _sobol_joint_bootstrap: ONE shared-row resample recomputes every index AND
  the M1/M2/R masses per replicate (covariance + closure preserved)
- api: OrderMasses dataclass + SobolResult.order_contributions, null exactly
  at zero sample variance (undefined fractions, not fake 0/0/0)
- tests: production-helper analytic benchmarks (additive d=8, pair-interaction
  d=5, Ishigami, pair-quadratic d=10) with 3xCI-scaled tolerances + B26nc
  degeneracy regression; SPEC V48tr/T51pq/B20qt, V9gh amended

Co-Authored-By: Qwen3.8 Flash Next NVFP4 (AWS vLLM) <noreply@anthropic.com>
…main (T52xx)

V26dd landed early (owner call 2026-09-30: no defer). The Saltelli box
was being derived from modeller distributions — the exact conflation the
SPEC scope calls out. Sobol now speaks DOMAIN vocabulary end to end;
distributions stay the exclusive input of evaluate_uncertainty.

BREAKING CHANGE: evaluate_sobol(distributions=...) is gone; pass
domains: Mapping[str, DomainSpec] instead (or omit for the auto box).
SobolResult.distributions -> domains + fixed + effective_config.

- api: domains optional; unknown names -> SumoInputError; omitted boxes
  auto-inferred from observed bounds + detected scale; a column
  constant in the samples is pinned (never a fabricated box, V47st);
  log-scale domains positivity-guarded; draws uniform / log-uniform
  (V44ls) via the shared scale_distribution — normal-parameterized
  Sobol sampling dies with the mean±3σ artifact it descended from
- engine: evaluate_sobol_indices consumes the domain-sampling map
  ({minimum, maximum, log_scale?} | {value}); stale resolve_log_scale
  import dropped
- tests: explicit/auto/ghost-domain + narrow-box concentration +
  constant-column-pinned (real Dakota); NORMAL flip matrix loses its
  Sobol row by design (2 distribution entry points remain, asserted)
- docs: how-to/tutorials/reference rewritten to domain semantics; V&V
  gains I11 + estimator tier + M1/M2 gate rows; counts 387/26/14
- SPEC: V26dd enforced, T52xx, T27fr remaining = FE migration only

Co-Authored-By: Qwen3.8 Flash Next NVFP4 (AWS vLLM) <noreply@anthropic.com>
@JavierGOrdonnez
JavierGOrdonnez merged commit afcb916 into develop Sep 30, 2026
9 checks passed
@JavierGOrdonnez
JavierGOrdonnez deleted the jgo/port-t31rb-domain-split branch September 30, 2026 19:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant