Skip to content

feat(api): honour log scale with normal distributions + boundary guards (T48kw-T50vb) - #49

Merged
JavierGOrdonnez merged 5 commits into
developfrom
feat/log-scale-normal
Sep 29, 2026
Merged

JavierGOrdonnez merged 5 commits into
developfrom
feat/log-scale-normal

Conversation

@JavierGOrdonnez

Copy link
Copy Markdown
Collaborator

Why

The PR #47 review verdict (see that thread): the shipped "deliberate semantics" — log + normal input → rejected ("source parity; no invented log-normal") — was the wrong call. The log knob must compose with a normal: for a log-scale column, μ/σ describe the ln-space distribution, so raw draws are lognormal (positive by construction) and the surrogate sees exactly N(μ,σ) in the space it trains on. That is the same contract the log-uniform branch already honors ("the distribution describes what the model sees"). The same review confirmed four scale-boundary guards that shipped weaker than their docstrings claim. Spec: V46rn/V47st, bug B19ps.

What

Path Behaviour now for scale="log"
UQ manual sampling normal accepted: draws exp(N(μ,σ)) — lognormal in original units (resolve_log_scale + create_manual_uq_samples); constant stays rejected
Sobol log-normal input → frozen lognorm(s=σ, scale=e^μ) ppf — decomposition over what the model sees
MC-through-surrogate correlation log⊗normal accepted via the shared _uq_engine_distributions boundary
Flip matrix extended: the 3 distributions-taking entry points must move when a normal column turns log (V46rn machine guard)
compute_correlation_indices input_scales[var] is a required key — a variable missing from the map raises instead of silently defaulting to linear (docstring stops overstating)
compute_correlations / generate_lhs_samples / generate_grid_samples reject preprocessing overrides for columns not in play — the session path's exact-cover rule, everywhere
_uq_engine_distributions log-uniform upper bound validated present ∧ ordered at the api boundary → SumoInputError, not a mid-engine SumoEngineError
DomainSpec / DistributionSpec maximum ≤ minimum refused at construction (__post_init__) — kills the silently-descending inverted log grid axis; MOGA inverted domains become input errors
optimize docstring corrected: a log objective fits in ln space, the front is reported exp-restored in original units

Copilot review items #1–#4 from #47 are all addressed here. V&V Category I amended (I4/I7/I8/I9) + new I10 row for the guard set; TIER plan wording aligned.

Verification

  • Full suite 376 passed (baseline 365 + 11 new), real Dakota, nothing mocked.
  • The three "log+normal is rejected" tests flipped to behavior tests (Jensen direction on the UQ mean, Sobol share shift, Pearson move) + a fourth engine-level rejection found by the full run; new TestSpecValidation contract tests; flip matrix extended.
  • ruff check / ruff format --check / ty check clean (prek-equivalent).

Javier Garcia Ordonez added 5 commits September 29, 2026 16:15
…T48kw-T50vb opened

PR#47 review verdict: log scale must compose with normal distributions
(ln-space mu/sigma, lognormal raw draws) instead of being rejected, and
four scale-boundary guards shipped weaker than their docstrings claim.

Spec: V46rn, V47st, B19ps, tasks T48kw/T49dr/T50vb.
A log-scale normal now keeps its mean/std in ln space: raw draws are
exp(N(mu,sigma)) (lognormal, positive by construction) and the surrogate
sees exactly N(mu,sigma) in its training space -- the same contract the
log-uniform branch already honors. Reaching create_manual_uq_samples, the
Sobol ppf map (lognorm(s=sigma, scale=e^mu)) and the session boundary;
log+constant stays rejected.

Tests: 3 rejections flipped to behavior tests (Jensen direction on UQ
mean, Sobol decomposition shift, Pearson move), engine-level lognormal
draw test, flip matrix extended with a log-normal column over all 3
distributions-taking entry points. V&V I4/I7/I8/I9 + TIER plan wording
amended.

Closes T48kw (V46rn, V45ls, B19ps).
Four fixes from the PR#47 review, all confirmed against the code:
- compute_correlation_indices now requires an input_scales entry per
  correlated variable (membership ValueError instead of the silent
  per-variable linear default that contradicted its docstring)
- compute_correlations / generate_lhs_samples / generate_grid_samples
  reject preprocessing overrides for columns not in play, matching the
  session path's exact-cover rule
- _uq_engine_distributions validates the log-uniform upper bound (present
  and above the lower bound) so the failure is a SumoInputError at the
  boundary, not a SumoEngineError surfacing from the engine
- optimize Pareto docstring corrected: a log objective fits in ln space
  but the front is reported exp-restored in original units

Closes T49dr (V47st, V45ls, V23er, B19ps).
DomainSpec and DistributionSpec now refuse maximum <= minimum in
__post_init__ with a SumoInputError, instead of letting an inverted box
surface as a silently descending log grid axis or a mid-engine MOGA
failure. One-sided DistributionSpec bounds stay constructible; shape-
specific requirements remain where the shape is interpreted.

Adds TestSpecValidation (contract tests) and V&V Category I row I10
covering the full V47st guard set.

Closes T50vb (V47st, V23er).
@JavierGOrdonnez
JavierGOrdonnez merged commit 577bae0 into develop Sep 29, 2026
9 checks passed
@JavierGOrdonnez
JavierGOrdonnez deleted the feat/log-scale-normal branch September 29, 2026 14:47
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