UQ-Lite Sampling
Seeded multivariate-normal sampling over caller-supplied covariance blocks, SANDY-compatible moment estimators, and the decay perturbation consumer.
Nucleide UQ-lite draws seeded multivariate-normal samples over
caller-supplied covariance blocks: the SANDY role (seeded MVN draws
that reproduce caller covariance information) with no vendored covariance
stores, no transport coupling, and no ERRORR/NJOY machinery. The moment
estimators agree exactly with SANDY’s Samples.get_mean / get_cov
(oracle-check gate at 1e-9 against SANDY 1.1.0)fiorito-2017sandy-repo.
Overview
Given a mean vector and a covariance block , the kernel draws reproducible samples , checks the sample moments recover the inputs, and optionally applies the draws as relative/absolute/log-normal perturbations to decay data. A log-normal entry point draws in log space and returns . Seeds pin the ChaCha12 stream, so identical inputs give bit-identical samples.
Mathematical details
Factor sampling: with any such that and ,
The primary path takes from the Cholesky factorisation; when is positive-semidefinite but numerically singular, the fallback is the eigen-clipping reconstruction with eigenvalues floored at times the largest eigenvalue. Standard normals come from the Box–Muller transformbox-muller-1958.
Sample moments use the unbiased covariance (Anderson, Ch. 3)anderson-2003:
The denominator matches pandas.DataFrame.cov (ddof=1), which
is what SANDY’s Samples.get_cov calls — that shared convention is what
the oracle-check gate checks.
Convergence gates use the MVN sampling variances (Anderson, Ch. 7)anderson-2003:
Honest gates assert moments within standard errors at a stated (the fixtures pin ) — never hand-waved round numbers.
Perturbation conventions apply one draw elementwise:
Log-normal draws reuse the (U1) factor path and RNG stream, then map elementwise; / are log-space MVN parameters, never the moments of itself. The closed-form moments are
Branch fractions renormalise to preserve the incoming deficit (spontaneous-fission branches are dropped at generation time, so kept branches sum to the kept share, not 1.0):
Negative raw branches clamp to zero before renormalisation: the
negative-clamp half of SANDY Samples.truncate_normal(mode=1), which
additionally caps values above 2 at 2 for relative-unit samples centered
at 1 — no analogue here, since branches renormalise and energies are
absolute.
Fission yields renormalise to preserve the incoming block sum — the same
deficit discipline as (U5), except the preserver is sum(base) itself
(independent blocks sum to 2 per parent/energy set, cumulative blocks sum
higher), never a hard-coded constant:
Zero-base rows stay zero via . The kernel owns no
yield data and never selects the set: the caller supplies the block and
builds the relative draws (tape dY/Y sigmas, or correlated draws from
(U1) forwarded as ); set selection (e.g. the lowest-energy
independent set) lives with the caller. Explicit-covariance mode is that
composition — no new parameters.
Latin-hypercube draws reuse the (U1) factor path with a stratified normal source:
Per dimension , one jittered uniform per stratum: is a
Fisher–Yates permutation of and , both from
the seeded StdRng (ChaCha12); is the hand-rolled
inverse-normal CDF on f64 (Acklam/Beasley-Springer-Moro
rational-approximation class — same arithmetic class as the Box–Muller
closurebox-muller-1958); then the shared factor path
(Cholesky primary, eigen-clip fallback, reported never silent) and
. LHS is a draw mode, not a perturbation convention. The
pinned -SE IID gates (U3) are the wrong null for stratified draws —
LHS variance is smaller than IID by construction — so the separate gate
is: G1 stratification-exact (each dimension hits each of the
strata exactly once at the pinned seed) plus G2 LHS-valid moment bound
(sample mean/covariance within IID standard errors from (U3) as an
upper bound, never an equality null). Oracle-check SANDY get_mean/get_cov
1e-9 agreement is estimator identities, draw-independentfiorito-2017.
Algorithm
sample_mvn validates (non-empty, square, finite, symmetric within
relative tolerance — SANDY instead requires exact symmetry),
factorises (Cholesky, else eigen-clip with the taken path reported, never
silent), fills a Box–Muller stream from the seed, and applies (U1).
sample_lognormal reuses that path and stream, then applies
(f64::exp is the only addition); lognormal_mean / lognormal_cov
spell the closed-form (U6) moments. sample_lhs reuses the same
validation, factor path, and application with the
stratified (U7) normal source (per-dimension Fisher–Yates permutation plus
jitter from the seeded StdRng, hand-rolled ).
sample_mean / sample_cov implement (U2); check_convergence
implements (U3) with caller tolerances. perturb_branches implements
(U5); perturb_fission_yields implements (U8) over caller-supplied
yield blocks; perturb_energies implements
(U4) with a zero clamp (a no-op for the log-normal convention, whose draws
stay positive).
Worked example
The fixtures/uq/cov_2x2.json block
has the closed-form Cholesky factor
:
, ,
. At the pinned seed the 20,000 draws
recover the inputs within 0.78 standard errors (U1 gate, ).
The fixtures/uq/lognormal_2x2.json log-space block
(, with variances 0.04/0.09 and covariance
0.01) has closed-form log-normal moments
from (U6).
At the pinned seed the 50,000 draws satisfy the separate U5 gate:
recovers the log-space block within the MVN -SE gate and the sample mean
of recovers within standard errors () — the
MVN gates are not reused after the transform.
The fixtures/uq/lhs_2x2.json block (mean , as above,
, , seed 20260916) takes the Cholesky path at the pinned
seed and satisfies the separate U6 gate (theory U7): G1 exact
one-per-stratum recovery per dimension plus G2 sample mean/covariance
within the IID standard-error upper bound (moment worst 1.064 SE at
the pinned seed).
The U7 gate perturbs a caller-selected U235-thermal subset
(Te134/Xe138/Sr95 from the real yield library, dY/Y sigmas, ,
, seed 20260917) with theory (U8): every perturbed draw sums to
the incoming block sum exactly (kept sum 0.1556691), and the forwarded
relative draws recover their diagonal moment block within the IID -SE
gate (moment worst 1.534 SE at the pinned seed).
Assumptions and limitations
- Inputs are caller-supplied blocks; no covariance library is read or shipped, and no ENDF/ERRORR parsing exists here.
- Fission-yield perturbation over caller-supplied blocks is in
(
perturb_fission_yields, theory U8, U7 gate); ERRORR/NJOY covariance tapes for yields stay out (caller-supplied blocks only), as do MF32/MF40 resonance machinery and transport coupling. Latin-hypercube sampling over caller-supplied blocks is in (sample_lhs, theory U7, separate G1/G2 gate); tape-driven LHS workflows stay out. - Draws are not interchangeable with SANDY’s: the published SANDY scheme factorises the correlation structure with Cholesky, but the current SANDY implementation uses SVD behind a different RNG stream — same target distribution, different bits. Only the estimators agree.
Related work beyond Nucleide
- SANDY samples MF31–MF35/MF8 covariances from ENDF-6 tapes (including
decay data and fission yields) with NJOY/ERRORR preprocessing and
variance-decomposition sensitivity indices — beyond this kernel’s
caller-block scope. Fission-yield parity is closed over
caller-supplied blocks (
perturb_fission_yields, U8, U7 gate); tape-driven FY covariance workflows stay out. Latin-hypercube parity is closed over caller-supplied blocks (sample_lhs, U7, G1/G2 gate); tape-driven LHS workflows stay out. Log-normal sampling is covered here only over caller-supplied blocks ( post-transform with log-space mean/covariance semantics); tape-driven log-normal workflows stay out. - SANDY’s
summarize_sample(Frobenius-norm deviations, normality tests) is the closest analogue ofcheck_convergence; ours is the -standard-error formulation (U3) instead.
The validation/uq_lite_vs_sandy.py harness checks the kernel two ways:
seeded synthetic statistical checks in-repo and a live SANDY moment
comparison against the 1.1.0 wheel in the validation container.
See also
- Tutorial: UQ sampling
- Interactive: UQ sampling