mixle.doe package¶
Design and analysis of computer experiments for mixle.
This package covers the full loop of reasoning about an expensive black-box model f(x) over a
bounded input space:
Designs – space-filling (Latin hypercube, maximin, Sobol’/Halton, MaxPro maximum-projection), classical factorial / fractional-factorial / Plackett-Burman / response-surface / mixture, and optimal designs (D/A/I/G/E/c criteria).
Bayesian optimization – the single-point acquisitions (EI/PI/UCB/Thompson/knowledge-gradient), Monte-Carlo q-EI and local-penalization batch design, Max-value Entropy Search, trust-region BO (TuRBO) for high dimensions, constrained and multi-objective BO, and cost-aware multi-fidelity BO.
Active learning & optimal design – sequential design to learn a surrogate (ALM / ALC-IMSE) or model parameters (expected information gain, closed-form and nested-Monte-Carlo).
Analysis – global sensitivity (Sobol’/Morris/FAST/DGSM), forward uncertainty propagation, and Kennedy-O’Hagan calibration to field data. (These were the standalone
mixle.uqpackage; folded in here they share this package’s quasi-Monte-Carlo sampling, GP surrogate, and kernels.)
The space-filling and classical design generators all return a plain (n, d) numpy matrix of
input points scaled into the supplied per-dimension bounds:
>>> from mixle.doe import latin_hypercube
>>> x = latin_hypercube([(0.0, 1.0), (-2.0, 2.0)], n=8, seed=0)
>>> x.shape
(8, 2)
- full_factorial(bounds, levels)[source]
Return a full-factorial grid design over
bounds.levelsis the number of evenly-spaced levels per dimension (a scalar applied to all dimensions, or one entry per dimension, each>= 1). The result hasprod(levels)rows in row-major (last axis fastest) order. A dimension with one level is placed at its midpoint.
- halton_design(bounds, n, seed=None, *, scramble=True)[source]
Return an
n-point Halton low-discrepancy design overbounds.Halton is a quasi-random sequence (coprime van der Corput sequences per axis) that, like Sobol’, fills space more evenly than iid uniform sampling and works for any
n(no power-of-two preference).scramble=Truerandomizes it reproducibly fromseed.
- latin_hypercube(bounds, n, seed=None, *, center=False)[source]
Return an
n-point Latin hypercube design overbounds.Each of the
daxes is partitioned intonequal strata and exactly one sample falls in each stratum (the defining LHS property), with the per-axis stratum assignments independently permuted. Withcenter=Trueeach sample sits at its stratum midpoint; otherwise it is drawn uniformly within the stratum.
- maximin_latin_hypercube(bounds, n, seed=None, *, trials=32)[source]
Return the best of
trialsLatin hypercube designs by the maximin criterion.Generates
trialsindependent LHS designs and keeps the one whose minimum pairwise (Euclidean, bound-normalized) distance is largest, a simple way to improve space-fillingness.
- maxpro_design(bounds, n, seed=None, *, restarts=3, swaps=1500, maxiter=300)[source]
Return a maximum-projection (MaxPro) space-filling design (Joseph, Gul & Ba 2015).
MaxPro minimizes
sum_{i<j} 1 / prod_k (x_ik - x_jk)^2, which forces the points to spread out in every subspace projection, not just the full space – the design of choice when only some inputs turn out to matter (factor screening / sloppy models), since the points stay space-filling even projected onto the active subset.Built by the paper’s two-stage procedure, repeated from
restartsLatin-hypercube starts: (1) a MaxProLHD coordinate-exchange phase (swapswithin-column swaps) finds a good basin while keeping the LHS structure, then (2) continuous L-BFGS-B optimization (analytic gradient,maxitersteps) moves the points off the grid to the true MaxPro optimum – the refinement that cuts the criterion by far more than the swap phase alone. The best design over restarts is returned as an(n, d)array.Each restart’s continuous refinement is only kept if the optimizer reports success and returns a finite objective/gradient/point; otherwise that restart falls back to its swap-refined discrete design instead, which is always a legitimate (if less-refined) MaxPro candidate – see
_maxpro_swap(). A restart can therefore never contribute an unverified, possibly-divergent optimizer iterate to the result (MXR-080-0175).
- random_design(bounds, n, seed=None)[source]
Return
niid uniform points overboundsas an(n, d)array.
- sobol_design(bounds, n, seed=None, *, scramble=True)[source]
Return an
n-point Sobol’ low-discrepancy design overbounds.Sobol’ is a quasi-random sequence whose discrepancy (deviation from perfectly even coverage) is far lower than iid uniform sampling, so it fills the space more evenly for moderate
n.scramble=Trueapplies Owen scrambling, which randomizes the sequence reproducibly fromseedwhile preserving the low-discrepancy structure;scramble=Falsereturns the raw deterministic sequence. Balance properties are best whennis a power of two.
- class DistillationDesign(indices, scores, task_counts=<factory>, modality_counts=<factory>, candidate_scores=<factory>, metadata=<factory>)[source]
Bases:
objectSelected pool indices and diagnostics for a distillation design.
indicespoint into the exact candidate pool supplied to the selector.scoresare the sequential merits assigned to the chosen candidates.candidate_scorespreserves the base uncertainty/preference score before diversity, coverage, and cost terms are applied.metadatarecords the target coverage and weights needed to audit or reproduce the design.
- distillation_design(features, n, *, task_labels=None, modalities=None, uncertainty=None, preference=None, cost=None, task_weights=None, modality_weights=None, reference_features=None, eligible=None, uncertainty_weight=1.0, diversity_weight=1.0, task_coverage_weight=1.0, modality_coverage_weight=1.0, preference_weight=1.0, cost_weight=1.0, seed=None)[source]
Select a pool subset for teacher labeling or student distillation.
featuresis an(N, d)embedding/feature matrix for candidate examples.task_labelsandmodalitiesmay be one tag per row or a sequence of tags per row.uncertaintymay be(N,)or(N, T); the latter is averaged across the task tags present on each candidate. Higher uncertainty/preference and better coverage increase merit; highercostlowers it.- Parameters:
features (Any)
n (int)
task_labels (Sequence[Any] | Sequence[Sequence[Any]] | ndarray | None)
modalities (Sequence[Any] | Sequence[Sequence[Any]] | ndarray | None)
uncertainty (Any | None)
preference (Any | None)
cost (Any | None)
modality_weights (Mapping[Any, float] | Sequence[float] | None)
reference_features (Any | None)
eligible (Any | None)
uncertainty_weight (float)
diversity_weight (float)
task_coverage_weight (float)
modality_coverage_weight (float)
preference_weight (float)
cost_weight (float)
seed (int | RandomState | None)
- Return type:
DistillationDesign
- multitask_distillation_design(*args, **kwargs)[source]
Alias for
distillation_design()that reads naturally at multi-task call sites.
- cross_modal_distillation_design(modality_features, n, *, task_labels=None, uncertainty=None, preference=None, cost=None, required_modalities=None, min_modalities=2, alignment_weight=1.0, seed=None, **kwargs)[source]
Select paired cross-modal records for distillation/alignment training.
modality_featuresmaps modality name to an(N, d_m)feature matrix. Rows with non-finite values are treated as missing for that modality. The selector fuses standardized modality features, tags each row by available modalities, and adds an alignment-disagreement preference for modality pairs that share the same embedding width. By default only rows with at least two modalities are eligible.
- fractional_factorial(bounds, generators, *, coded=False)[source]
Two-level fractional factorial
2**(k-p)from pyDOE-style generator strings.generatorsnames one column per factor as a product of base factors, e.g."a b c ab ac"– a2**(5-2)design whose factorsd, eare deliberately aliased asd = ab,e = ac. Base factors are the distinct single letters; each token is the elementwise product of its letters, optionally negated with a leading-. The number of tokens must equallen(bounds).Rejects a
generatorsspec that collapses a factor to a constant column (repeated letters cancelling entirely, e.g."aa") or that aliases two of the named factors with each other (two tokens whose reduced letter-words are identical or exact opposites, e.g. tokens"a"and"-a") – both silently produced a degenerate design with no diagnostic before (MXR-080-0179). This does not affect the intentional aliasing a fractional design is built on: a compound token like"ab"is fine and expected, it just cannot repeat another factor’s own word. Usegenerator_alias_structure()to see which factors are aliased with which interaction.Returns a
(2**k, d)design (k= number of base factors) mapped intobounds– or the raw coded+/-1matrix ifcoded=True.
- generator_alias_structure(generators, *, max_order=2)[source]
Return signed defining words and complete alias chains through
max_order.The result is a JSON-friendly record with:
factor_labelsmapping every public positional factor name to its source token;base_factorsmapping each latent generator letter to its named factor and sign;generatorsexpressing every compound generator using those public factor names;defining_relationsand the complete generateddefining_groupas signed words; andalias_setsfor the identity and every effect through the requested interaction order.
A word record has an integer
sign(+1or-1) and afactorslist. For example,"a b ab"definesI = +x0:x1:x2; through order two,x0is aliased with+x1:x2andx2with+x0:x1. Negated base or compound tokens propagate their signs through every relation and alias. This supplies the actual confounding structure rather than only repeating the compound generator fragments (MXR-080-1477).Every latent base letter must have one named singleton token so aliases can be mapped unambiguously to the positional
xNlabels used bymixle.doe.analysis. The generator syntax is otherwise validated exactly likefractional_factorial().
- plackett_burman(bounds, *, coded=False)[source]
Plackett-Burman two-level screening design for
len(bounds)factors.Returns
Nruns whereNis the smallest multiple of four that is at leastd + 1(so the design is saturated or near-saturated, ideal for screening many factors in few runs). ForNa power of two the design is a Hadamard matrix (a resolution-III fractional factorial); forNin{12, 20, 24}a known cyclic generator is used; otherwiseNis rounded up to the next power of two so a design always exists. Main effects are mutually orthogonal but aliased with two-factor interactions – use it to find the few large effects, then follow up with a fuller design.
- central_composite(bounds, *, center=4, alpha='rotatable', coded=False)[source]
Central-composite design (CCD) for fitting a full second-order response surface.
A CCD stacks three parts, in this row order (see
central_composite_point_kinds()to recover which output row is which): the2**dtwo-level factorial corners (estimate linear and interaction terms),2*daxial / star points at distancealphaon each axis (estimate the pure-quadratic curvature), andcenterreplicates at the centre (estimate pure error and curvature).alphasets the axial distance:"rotatable"(default) –alpha = (2**d)**0.25, so prediction variance depends only on distance from the centre;"orthogonal"– the value making the second-order terms orthogonal (depends oncenter);"face"(a face-centred CCD / CCF) –alpha = 1, keeping every run inside the cube;a positive, finite float – used directly.
boundsdefines the factorial cube (-1/+1map to each factor’slow/high): the factorial-corner and centre rows are therefore always exactly withinbounds. Axial points sit at coded distancealphaon a single axis, and for"rotatable"/"orthogonal"that distance is normally greater than 1 – a mathematical requirement of the rotatability/orthogonality property, not a clamp tobounds– so those rows routinely fall outsideboundson purpose. Onlyalpha="face"(or a numericalpha <= 1) guarantees every row stays withinbounds(MXR-080-0179); usecentral_composite_point_kinds()to tell the row kinds apart programmatically when that distinction matters to the caller.Returns
(2**d + 2*d + center, d)rows mapped intobounds(or coded ifcoded=True).
- central_composite_point_kinds(bounds, *, center=4)[source]
Row-kind labels for
central_composite()’s output, in the same row order.Returns a length-
(2**d + 2*d + center)string array of"factorial"/"axial"/"center"entries."factorial"and"center"rows are always exactly withinbounds;"axial"rows are guaranteed withinboundsonly whencentral_composite()was called withalpha="face"(or a numericalpha <= 1) – see its docstring for why rotatable/ orthogonal axial points routinely extend pastboundson purpose (MXR-080-0179). Pass the samecenterused in the matchingcentral_composite()call so the lengths line up, e.g.:design = central_composite(bounds, center=4, alpha="rotatable") kinds = central_composite_point_kinds(bounds, center=4) in_bounds_rows = design[kinds != "axial"]
- box_behnken(bounds, *, center=None, coded=False)[source]
Box-Behnken response-surface design (3 levels per factor, no corner runs).
For every pair of factors it runs the four
(+/-1, +/-1)combinations with all other factors at the centre, pluscentercentre replicates. Unlike a CCD it never sets all factors to an extreme at once (no cube corners), which is useful when those combinations are expensive or infeasible, and it needs only three levels per factor. Every row is always withinbounds(no analogue of a CCD’s rotatable axial points here). Requiresd >= 3.Returns
(4 * C(d, 2) + center, d)rows mapped intobounds(or coded ifcoded=True).
- simplex_lattice(q, m)[source]
{q, m}simplex-lattice design forqmixture components.Each component takes one of the
m + 1evenly spaced proportions0, 1/m, ..., 1and the proportions in a blend sum to one. The design is exactly the set of such blends –C(q+m-1, m)points – and supports a degree-mScheffe mixture polynomial.Returns a
(C(q+m-1, m), q)array of blends (rows sum to 1).
- simplex_centroid(q)[source]
Simplex-centroid design for
qmixture components.Runs the centroid of every non-empty subset of components: the
qpure components, theC(q,2)binary 1/2:1/2 blends, … up to the overall centroid (all components at1/q) –2**q - 1blends in total. Supports the special cubic mixture model.Returns a
(2**q - 1, q)array of blends (rows sum to 1).
- to_pseudocomponents(blends, lower)[source]
Map canonical simplex blends onto pseudo-components with per-component lower bounds.
With lower bounds
l_i(finite, non-negative, summing to< 1), a constrained mixture’s feasible region is itself a smaller simplex; this maps a canonical blendx– itself a finite(n, q)array of genuine simplex points (non-negative, rows summing to 1) – onto the real proportionsa_i = l_i + (1 - sum l) * x_i(the standard L-pseudocomponent transform), so any simplex design above can be run inside the constrained region. Rows still sum to 1.- Raises:
ValueError –
loweris not a finite, non-negative, 1-D vector summing to less than 1 (i.e. one that itself admits at least one feasible simplex point), orblendsis not a finite 2-D array of shape(n, len(lower))whose rows are genuine canonical simplex points (non-negative, summing to 1). Invalid input is rejected outright instead of silently mapped to an out-of-simplex result (MXR-080-0180): e.g. blend[2, -1]with lower bounds[0.1, 0.1]used to silently return[1.7, -0.7], a negative “proportion”.- Parameters:
- Return type:
- factorial_effects(design, y, *, interactions=True, coded=False)[source]
Estimate main effects and two-factor interactions from a two-level design.
Fits the linear model
y ~ 1 + x_i (+ x_i x_j)in coded+/-1units by least squares; the coefficients are half the classical effects.designis the(n, d)run matrix (the real factor levels, coded to+/-1automatically – or passcoded=Trueif it is already coded, in which case every entry must be exactly-1.0or1.0),ythe measured responses. Setinteractions=Falsefor a main-effects-only (e.g. screening) fit.Rejects designs that cannot support the requested model outright: non-finite values, fewer runs than model parameters, and (for
coded=True) levels other than+/-1. A design that has enough runs but still cannot separate every term – aliasing, including a factor that never varies – is not rejected: the aliased terms come back asnanincoef/effects, with the one combined quantity the data does support reported inestimable_contrasts(seeFactorialEffects). That automatic resolution only covers the classical case where the aliasing is exact term-for-term confounding, as in any standard fractional-factorial / Plackett-Burman alias structure; a design that is rank-deficient for some other reason (e.g. too few runs and not a clean fractional design) raises instead of guessing which contrasts might be estimable.
- class FactorialEffects(terms, coef, effects, intercept, residual_std, se, aliases, estimable_contrasts)[source]
Bases:
objectEstimated effects from a two-level factorial / fractional-factorial / Plackett-Burman design.
Only estimable quantities are reported as effects. When the design cannot separate two or more terms – classical aliasing/confounding, including a factor that never varies – those individual terms have no unique estimate: their entries in
coef/effectsarenan.aliasessays which terms are aliased with which;estimable_contrastsgives the one well-defined combined quantity the data actually supports for each such group.- Parameters:
- coef
least-squares regression coefficients in coded
+/-1units (nanfor a term that is aliased with another and so has no individual estimate).- Type:
- effects
the classical effect per term – the change in mean response as a factor moves from its low to its high level, i.e.
2 * coef(the intercept entry is just the grand mean).- Type:
- intercept
the grand mean of the response (
nanif the intercept itself is aliased, e.g. with a factor that never varies).- Type:
- residual_std
residual standard deviation when the design has spare runs (else
None).- Type:
float | None
- se
standard error of each entry of
effects.Nonethroughout when the design has no spare degrees of freedom to estimate a residual variance (e.g. a saturated design); individual entries arenanwherevereffectsis (aliased terms).- Type:
numpy.ndarray | None
- aliases
for each term, the other term names it is aliased with (empty list if the term is uniquely estimable).
- estimable_contrasts
for each alias group of two or more terms, keyed by its member term names joined by their signed defining relation (for example
"x0-x1"for opposite columns), the(effect, se)of the exact combined quantity that is estimable – empty when the design has no aliasing.
- response_surface(x, y)[source]
Fit a full second-order (quadratic) response surface and analyse its stationary point.
Least-squares-fits
y = b0 + sum b_i x_i + sum_{i<=j} b_{ij} x_i x_jto the design runsx(n, d)and responsesy, then solves the stationarity equationB x* = -b/2for the stationary point and classifies it from the eigenvalues of the quadratic matrixB. WhenBis singular a solution only exists if-b/2lies in its range, which is checked explicitly via the residual of the stationarity equation – a least-squares “solution” that does not actually zero the gradient is reported askind="no_stationary_point"rather than a fake stationary point (seeResponseSurface). Fit on the coded design for a well-conditioned model (the classic central-composite / Box-Behnken workflow).- Return type:
ResponseSurface
- class ResponseSurface(coef, terms, b, B, stationary_point, eigenvalues, kind, residual_std, model_rank, n_parameters, degrees_of_freedom, estimable)[source]
Bases:
objectA fitted second-order response surface
y = b0 + b'x + x'Bxand its canonical analysis.- Parameters:
- coef
full coefficient vector (intercept, linears, then the upper-triangular second-order terms).
- Type:
- b
linear coefficient vector
(d,).- Type:
- B
symmetric
(d, d)matrix of quadratic coefficients (cross terms split onto both halves).- Type:
- stationary_point
x*solving the stationarity equationB x* = -b/2, orNonewhen no such point exists – i.e. the gradientb + 2 B xis never zero anywhere, which can only happen whenBis singular (kind == "no_stationary_point"; see below).- Type:
numpy.ndarray | None
- eigenvalues
eigenvalues of
B– all negative => a maximum, all positive => a minimum, mixed signs => a saddle; any eigenvalue ~0 (with a genuine stationary point) => a ridge, a whole line/subspace of equally-stationary points, of whichstationary_pointis one representative (the minimum-norm) point.- Type:
- kind
"maximum"/"minimum"/"saddle"/"ridge"/"no_stationary_point". The last case is distinct from a ridge: a ridge is a genuine (degenerate) stationary subspace, while"no_stationary_point"means the stationarity equation has no solution at all (e.g. the exact surfacey = x0**2 + x1, whose gradient’s second component is always exactly1).- Type:
- residual_std
residual standard deviation when the design has spare runs (else
None).- Type:
float | None
- model_rank
rank of the fitted quadratic model matrix.
- Type:
- n_parameters
number of quadratic coefficients requested.
- Type:
- degrees_of_freedom
residual degrees of freedom,
n_runs - n_parameters.- Type:
- estimable
whether every requested coefficient is identified. Construction refuses a non-estimable fit, so returned surfaces always report
True.- Type:
- predict(x)[source]
Predict the response at points
x(m, d)from the fitted surface.- Return type:
- design_diagnostics(design, model, *, ref=None)[source]
Quality diagnostics for a design under a model – “is this a good design to run?”.
Builds the model matrix
F = model(design)and reports, relative to a hypothetical perfectly orthogonal design (where each is1.0):d_efficiency–det(M)**(1/p) / n: overall coefficient-estimation precision;a_efficiency–p / (n * trace(M^-1)): average coefficient variance;g_efficiency–p / (n * max prediction variance)overref(or the design itself);condition_numberofM(large => near-collinear / fragile to fit;Nonewhen the requested model is rank-deficient), plus a finiteeffective_condition_numberwithin the estimable subspace and explicitrank/full_rankfields;max_correlation– the largest absolute pairwise correlation among the non-intercept model columns (the aliasing check;0for an orthogonal design).
modelis a model-matrix function such asmixle.doe.optimal.polynomial_features(). Use it on the coded design for meaningful efficiencies.ref– when given – is a reference design: raw candidate points in the same(m, d)raw-factor-column form asdesign(e.g. a finer grid over the same region, or a wider region to probe extrapolation risk), not a pre-built model matrix. It is passed through the samemodelused to build the design’s own model matrix before its prediction variance is computed, sog_efficiencycompares like with like; arefwhose raw column count does not matchdesign’s raises.g_efficiencyis guaranteed to fall on the documented(0, 1]scale only for the self-referential case (ref=None, orrefequal todesignitself) – a reference set concentrated in a lower-variance region than the design’s own points (e.g. just its centre) can legitimately score above1.0.The raw design and every transformed model matrix must be nonempty, two-dimensional, finite, and preserve the run axis. A rank-zero model is rejected. A partially estimable model reports zero full-model efficiencies,
condition_number=None, and its finite effective condition number rather than publishing NaN/Inf quality evidence.- Return type:
- class OptimizationResult(x, y)[source]
Bases:
objectCommon outcome of a model-based optimization run: the full evaluation history.
xis the(N, d)matrix of evaluated points andythe corresponding objective values (an(N,)vector for single-objective runs, an(N, M)matrix for multi-objective). Concrete result types extend this with their best-point / Pareto-front fields.
- class BayesOptResult(x, y, best_x, best_y, n_evaluations, failed_evaluations, stopped_reason, *, surrogate_repairs=())[source]
Bases:
OptimizationResultOutcome of a Bayesian-optimization run.
- Parameters:
- numerical_repairs()[source]
Repairs the surrogate applied during this run –
()when none were needed.Same channel and spelling as the distribution families’ and the GP’s own: a covariance ridged to stay factorable is a repair, and the proposals it produced are approximations whether or not the run reported a best point (R07-F05).
- expected_improvement(mean, std, best, xi=0.0, *, maximize=False, **_)[source]
Return the expected-improvement acquisition at points with surrogate
meanandstd.For minimization the improvement over the incumbent
bestisbest - mean - xi; for maximization it ismean - best - xi.xi >= 0trades exploration for exploitation. Points with (near-)zero predictivestdget the DETERMINISTIC LIMITmax(improve, 0)– a point-mass posterior has no uncertainty to average over, so the “expected” improvement is exactly the guaranteed one, not 0. Higher is better (maximized over candidates).Raises
ValueErrorifstdis negative/non-finite,mean/stdshapes disagree,mean/bestare non-finite, orxiis negative/non-finite.
- knowledge_gradient(mean, cov, noise=1.0e-6)[source]
Knowledge-gradient acquisition value of one observation at each candidate (Frazier et al. 2009).
Given the Gaussian-process posterior
meanand jointcovover a candidate set, returns, for each candidatex, the expected increase in the best posterior mean after fantasizing one (noisy) observation there:KG(x) = E_y[max_x' mu_{n+1}(x')] - max_x' mu_n(x'). Maximizing KG is the one-step Bayes-optimal, look-ahead choice (it values information, not just immediate improvement), so it explores where an observation would most change the believed optimum. Assumes a maximization objective; negatemeanfor minimization. Computed exactly via the piecewise-linear epigraph of the fantasized posterior means, and>= 0by construction.
- propose_knowledge_gradient(x, y, bounds, *, maximize=False, n_candidates=512, seed=None, gp=None, fit_kwargs=None, noise=1.0e-6)[source]
Propose the next evaluation point by maximizing the knowledge gradient over a candidate set.
Fits the GP surrogate to
(x, y), drawsn_candidatesLatin-hypercube points, evaluates the joint posterior, and returns the candidate with the largestknowledge_gradient()– the look-ahead Bayesian-optimization proposal.maximizeselects the objective sense (the mean is negated for minimization).Raises
ValueErrorif the surrogate’s predicted mean/covariance don’t match the candidate contract (wrong shape, non-finite, asymmetric covariance) or if every candidate’s knowledge-gradient value is non-finite (see_validate_prediction()/_select_index()).
- log_expected_improvement(mean, std, best, xi=0.0, *, maximize=False, **_)[source]
Return the log expected-improvement acquisition – a numerically stable EI (Ament et al. 2023).
Mathematically
log(EI), but computed so it stays finite and informative deep in the no-improvement tail whereEIitself underflows to 0 (andlog EIto-inf), keeping the optimizer’s ordering and gradients usable. Same argmax asexpected_improvement(); points with (near-)zero predictivestdget the deterministic limitlog(max(improve, 0))–-infwhen the point-mass outcome does not improve onbest, and the log of the guaranteed improvement when it does (seeexpected_improvement()). Higher is better. Thez >= 0branch is the direct well-conditioned form; thez < 0tail uses the scaled complementary error functionerfcx(Phi(z)/phi(z) = sqrt(pi/2) erfcx(-z/sqrt2)), which is bounded there and so never under/overflows.Raises
ValueErrorifstdis negative/non-finite,mean/stdshapes disagree,mean/bestare non-finite, orxiis negative/non-finite.
- probability_of_improvement(mean, std, best, *, maximize=False, xi=0.0, **_)[source]
Return the probability-of-improvement acquisition.
The probability that a candidate improves on the incumbent
bestby at leastxi:P(f < best - xi)for minimization,P(f > best + xi)for maximization. Where the predictivestdis zero the improvement is deterministic (1.0 if it improves, else 0.0). A NEGATIVEstdis rejected outright (see_validate_acquisition_inputs()) rather than treated as this same deterministic case – it is an invalid input, not a zero-variance one. Higher is better.Raises
ValueErrorifstdis negative/non-finite,mean/stdshapes disagree,mean/bestare non-finite, orxiis negative/non-finite.
- upper_confidence_bound(mean, std, best=0.0, *, maximize=False, kappa=1.96, **_)[source]
Return the confidence-bound acquisition (UCB for maximization, LCB for minimization).
Returns a merit that is maximized over candidates: the optimistic bound
mean + kappa * stdwhen maximizing, andkappa * std - meanwhen minimizing (so picking the largest merit selects the most promising low-objective point).kappa >= 0trades exploration for exploitation;bestis ignored. Higher is better.Raises
ValueErrorifstdis negative/non-finite,mean/stdshapes disagree,mean/bestare non-finite, orkappais negative/non-finite.
- thompson_sampling(mean, std, best=0.0, *, maximize=False, rng=None, **_)[source]
Thompson-sampling acquisition: one marginal posterior draw
N(mean, std)per candidate.Returns a merit (maximized over candidates) equal to the drawn value when maximizing and its negation when minimizing, so the selected point is the optimum of the sampled objective. A randomized, exploration-aware acquisition – repeated proposals explore competing optima in proportion to posterior probability, with no exploration knob to tune. This is the low-cost marginal variant (independent per-candidate draws, ignoring the GP’s cross-candidate correlation). The proposal loop (
_propose_one(), and sopropose_next()/propose_batch()/BayesianOptimizer) automatically threads its own candidate-generationrngthrough to this acquisition, so a seeded caller gets reproducible draws with no extra wiring; passrngexplicitly viaacq_kwargsonly to override that with a different generator. Called directly with norngat all, this draws from a fresh, unseeded generator (matching_as_rng’s ownNoneconvention) – reproducible only through the proposal loop’s threading above.bestis ignored.Raises
ValueErrorifstdis negative/non-finite,mean/stdshapes disagree,mean/bestare non-finite, orrngis neitherNonenor anumpy.randomRandomState/Generator.
- register_acquisition(name, fn, aliases=())[source]
Register an acquisition
fnundername(and anyaliases).fnis called asfn(mean, std, best, *, maximize, **params)and must return a merit array that the proposal loop maximizes over candidates. This is the extension point for new acquisitions – registering is all that is needed, no edits topropose_next/minimize.
- available_acquisitions()[source]
Return the sorted names (and aliases) of all registered acquisitions.
- minimize(objective, bounds, n_init=5, n_iter=15, seed=None, *, maximize=False, xi=0.0, acq='ei', acq_kwargs=None, n_candidates=512, fit_kwargs=None)[source]
Run sequential GP Bayesian optimization of a scalar
objectiveoverbounds.Seeds with an
n_init-point Latin-hypercube design, then runsn_iteracquisition-driven steps usingacq("ei"by default; also"pi"/"ucb"or any registered acquisition). Minimizes by default; setmaximize=Trueto maximize.objectivetakes a(d,)point and returns a float.A non-finite objective response is recorded in
failed_evaluationsand stops the run withstopped_reason='objective_failed'. It is never admitted to the fittedx/yhistory.The GP surrogate needs the optional torch extra (
pip install "mixle[torch]"). On a base install that is checked up front, before the first objective evaluation – never after then_initdesign has already spent expensive black-box calls.- Parameters:
- Return type:
BayesOptResult
- propose_next(x, y, bounds, n_candidates=512, seed=None, *, maximize=False, xi=0.0, acq='ei', acq_kwargs=None, gp=None, fit_kwargs=None, return_acquisition=False)[source]
Propose the next point to evaluate by maximizing an acquisition function.
Fits a GP to
(x, y), scoresn_candidatesLatin-hypercube points by theacqacquisition ("ei"/"pi"/"ucb"or any registered name / callable), and returns the best candidate (a(d,)array), optionally with its merit.xiis forwarded to acquisitions that use it (EI, PI); per-acquisition parameters such askappago inacq_kwargs.Raises
ValueErrorif the surrogate’s predicted mean/covariance don’t match the candidate contract (wrong shape, non-finite, asymmetric covariance) or if every candidate’s acquisition merit is non-finite (validated at the shared surrogate boundary, see_propose_one()).- Parameters:
- Return type:
- propose_batch(x, y, bounds, q, n_candidates=512, seed=None, *, maximize=False, xi=0.0, acq='ei', acq_kwargs=None, fit_kwargs=None)[source]
Propose a batch of
qpoints to evaluate together, via the kriging-believer heuristic.Each pick maximizes the acquisition; the GP posterior mean at the chosen point is then appended as a fantasized observation and the surrogate refit, so the next pick is steered away from it. Returns a
(q, d)array. This needs no true objective evaluations between picks, so it suits parallel/asynchronous experiment campaigns.Raises
ValueErrorif the surrogate’s predicted mean/covariance or fantasized single-point prediction don’t match the candidate contract, or if every candidate’s acquisition merit is non-finite at some step (see_validate_prediction()/_select_index()).
- class VerifiableOracle(name, tier, score_fn, fidelity=None, timeout=None, max_outstanding_timeouts=4)[source]
Bases:
objectA callable
candidate -> OracleResultthat declares its verifiability tier and fidelity.score_fndoes the actual verification (wrap a simulator, an executable check, a held-out ground-truth lookup, or a real measurement pipeline;mixle.task.toolcall’sToolCalleris the same “external check as a callable” shape for tool calls). Construction raises iftieris not one ofVERIFIABILITY_TIERS– “self-graded by a model” is not a valid tier and is rejected here, not silently accepted and discovered later.score_fnmay optionally accept acancel_event: threading.Eventkeyword argument (detected once, at construction, via introspection – see_accepts_keyword). A side-effectingscore_fnthat wraps something cancellable (a subprocess, an HTTP request) should periodically checkcancel_event.is_set()and tear its underlying call down promptly once set. This is a best-effort, cooperative cancellation boundary, not a forced kill – Python cannot forcibly terminate a thread. Calls that ignore cancellation remain quarantined, count againstmax_outstanding_timeouts, and eventually open a circuit that prevents additional worker creation. Their outcomes are captured inlate_resultswhen they finish. See_call_with_timeout.- Parameters:
- property late_results: tuple[LateOracleResult, ...]
Immutable snapshot of late outcomes accumulated so far.
- property outstanding_timeouts: int
Number of timed-out workers that have not cooperatively stopped or completed.
- class OracleResult(score, receipt=<factory>, cost=1.0, abstained=False, passed=True, valid=True, call_id=None, call_started=True)[source]
Bases:
objectOne candidate’s verification outcome: its score, a receipt of how it was scored, and its cost.
Construction validates its own shape (MXR-080-0189): a real, finite
scoreunlessabstained=True, a finite nonnegativecost, and adictreceipt. This is the boundary ascore_fn’s raw, untrusted return value crosses (seeVerifiableOracle._validate_returned), so a wrong type, a NaN/inf that leaked in from some computation, or a negative “cost” is caught immediately here rather than silently reaching a GP fit or a cost report.abstainedmarks a result that is NOT a genuine observation of the oracle’s true objective at the scored candidate – for example,VerifiableOracle’s timeout abstention. An abstained result’sscoreis a placeholder (-infby convention, never a claim about the true objective) kept only so the receipted history stays complete; consumers such asoptimize_under_oracle()gate onabstainedand must never feed one to a fit as if it were ground truth.
- class DesignCandidate(x, result, phase=None)[source]
Bases:
objectOne proposed-and-verified candidate: the point tried and what the oracle said about it.
- class DesignRun(oracle_name, oracle_tier, oracle_fidelity, _oracle=None)[source]
Bases:
objectThe full receipted history of a design loop: every candidate tried, and the oracle’s identity.
- Parameters:
- property history: tuple[DesignCandidate, ...]
Immutable chronological snapshot of the append-only candidate ledger.
- append(candidate)[source]
Append one immutable candidate record; existing ledger entries can never be replaced.
- Parameters:
candidate (DesignCandidate)
- Return type:
None
- property oracle_calls: int
Return the number of candidates attempted against the oracle (abstentions included).
- property candidate_attempts: int
All proposed candidates, including circuit-breaker abstentions that started no external call.
- property genuine_history: tuple[DesignCandidate, ...]
Return
historyfiltered to genuine (non-abstained) observations.An abstention (see
OracleResult.abstained– e.g. a timeout) is not a real observation of the oracle’s objective, so it is excluded here; usehistorydirectly for the full, unfiltered receipted record, abstentions included.
- property best: DesignCandidate
Return the highest-scoring GENUINE candidate in the run history.
Abstained candidates (see
OracleResult.abstained) never win: an abstention is not a real observation of the oracle’s objective, and surfacing one as “the best candidate found” would report a fabricated result as if it were verified. Raises if every candidate abstained (no genuine observation exists to report), distinct from the empty-history case.
- scores()[source]
Return the run’s oracle scores in chronological order, abstentions included (not hidden).
- Return type:
- report()[source]
Named receipt of the run: which oracle, at what tier/fidelity, the best candidate found.
provisional_total_costis the cost known when calls returned. Late outcomes linked by immutable call IDs are reconciled intosettled_late_costandsettled_total_cost.total_costis only populated once no timed-out call remains outstanding or unresolved.
- optimize_under_oracle(oracle, bounds, *, n_init=5, n_iter=15, seed=None, **bo_kwargs)[source]
Run a propose-verify-refit design loop under a fixed oracle budget.
The loop proposes candidates, verifies each one with
oracle, keeps the receipted history, refits the proposal model on every GENUINE observation, and repeats under ann_init + n_iterbudget of oracle calls.oracle=Noneraises immediately with the explicit refusal (“no verifiable objective; cannot optimize”) – the hard precondition checked before any candidate is proposed. Continuous/low-dimensionalboundsonly (see module docstring); the proposal model isBayesianOptimizer, maximizing the oracle’s score.An abstained result (
OracleResult.abstained– e.g. a timeout; seeVerifiableOracle) is never told to the proposal model as if it were a real observation (MXR-080-0189): a timeout means the oracle did not answer, not that the true score at that candidate is-inf, and training a fit on a fabricated-inf“observation” can corrupt it. The abstained candidate is still appended torun.history– the receipted record keeps every attempt, genuine or not – it is simply excluded from what the optimizer learns from.BayesianOptimizer.askis explicitly designed to tolerate this (its initial-design dispensing is gated on points asked, not points told), so skippingtellfor an abstention does not desynchronize or corrupt the proposal model’s state.If the entire initial phase abstains, however, the model has no observation at all to fit an acquisition step on, and
askraises rather than guessing. The adaptive phase is therefore not entered in that case: the run stops and is returned with its receipts intact, so an all-abstention run still yields its audit report (status="no_verified_result") instead of dying inside the proposal model (MXR-080-1488).
- amplify_and_capture(oracle, bounds, *, n_init=5, n_iter=10, candidate_pool_size=200, degree=2, significance=0.05, seed=None)[source]
Round 1: search the oracle for a budget of
n_init + n_itercalls (the amplified teacher).The search must beat a budget-matched random baseline – also
n_init + n_iteroracle-verified draws, not one – on a one-sided permutation test of “round 1’s best score exceeds the baseline’s best score by more than a fair reshuffling of the pooled2 * budgetscores would typically produce”, at the prespecifiedsignificancelevel. A single best-of-N-vs-one-draw comparison is a multiple-comparisons trap (see the module docstring): matching the baseline’s budget to the search’s, and testing the two best-of-budget scores against the null distribution obtained by repeatedly reshuffling which of the2 * budgetoracle-verified scores “belong” to round 1 versus the baseline (rather than a bare, un-tested “is my number bigger” check), is what makesbeats_baselinea calibrated claim instead of a counter that trends toward “always passes” as the budget grows. If the search does not clear the gate, this returns the explicitstopped_early=Trueresult with nothing distilled.Otherwise: fit
StudentTeacherfrom round 1’s history; round 2 uses the student to rank a large, FRESH candidate pool (never round 1’s own points – see the round 2 comment below) and spends the same oracle-call budget verifying only the top-ranked fresh candidates – student-guided, not blind, but every accepted score is still oracle-verified. Runsmixle.task.collapse.collapse_monitor()over the two rounds.
- class AmplifyReport(round1, round2, baseline, baseline_p_value, significance, beats_baseline, round2_beats_round1, incumbent_best_score, collapse, student, stopped_early, reason, seeds, round1_effective_n, baseline_effective_n, round2_effective_n)[source]
Bases:
objectReceipt for a two-round amplify-and-capture run.
round1is the initial oracle-driven search.baselineis a random draw matched to round 1’s exact oracle-call budget (not a single draw – seeamplify_and_capture), so every oracle call either side spent is accounted for in its own receiptedAmplificationRound.baseline_p_valueis the one-sided permutation-test p-value for “round 1’s best score exceeds the baseline’s best score by more than chance”, tested against the prespecifiedsignificancelevel to producebeats_baseline.round2is present only when round 1 clears that gate, and a captured student is used to propose the matched-budget follow-up batch from a FRESH candidate pool (round 1’s own points are never re-offered to round 2, soround2_beats_round1measures generalization to unseen candidates, not re-verification of already-known ones).incumbent_best_scoreis bookkeeping only – the best score retained across whichever rounds ran – and, unlike round 1’s era of this report, plays no part in computinground2_beats_round1orcollapse.collapserecords the trajectory-level collapse verdict when both rounds run.- Parameters:
round1 (AmplificationRound)
round2 (AmplificationRound | None)
baseline (AmplificationRound)
baseline_p_value (float | None)
significance (float)
beats_baseline (bool)
round2_beats_round1 (bool)
incumbent_best_score (float | None)
collapse (CollapseVerdict | None)
student (StudentTeacher | None)
stopped_early (bool)
reason (str | None)
seeds (AmplificationSeeds)
round1_effective_n (int)
baseline_effective_n (int)
round2_effective_n (int | None)
- class AmplificationRound(run, best_score, xs)[source]
Bases:
objectOne oracle-verified amplification round and its best observed score.
- class StudentTeacher(coef, degree)[source]
Bases:
objectCaptured regression surrogate used to rank follow-up design candidates.
The object is callable as
student(x) -> predicted_scoreso it can be used like other teacher/task-model callables, but its role here is only proposal ranking. Accepted scores still come from the verifiable oracle.
- fit_student(run, *, degree=2)[source]
Fit
StudentTeacherfromrun’s GENUINE (non-abstained) oracle-verified history.Fits against
run.genuine_history, notrun.history: an abstained candidate’s placeholder-infscore (OracleResult.abstained– e.g. a timeout) is not a real observation of the oracle’s objective, and least-squares regression has no tolerance for a non-finite target at all – unlike the permutation test inamplify_and_capture, where a lone-infonly nudges a p-value, here a SINGLE abstained candidate anywhere inrun.historydrives every coefficient incoeftonan(confirmed: a clean fit against 8 well-posed genuine points, then adding one abstained candidate to the same history turns the entire coefficient vector tonan), silently turning the captured student that guides round 2’s candidate ranking into a useless, uniformly-nanpredictor with no visible error at the call site.- Parameters:
run (DesignRun)
degree (int)
- Return type:
StudentTeacher
- optimal_design(bounds, n, *, candidates=None, model=None, criterion='D', n_candidates=256, n_restarts=5, max_iter=100, ref=None, seed=None)[source]
Return an
n-point optimal design selected from a candidate pool by Fedorov exchange.The pool is either generated as a Sobol design of
n_candidatespoints over per-dimensionbounds, or supplied directly as an(P, d)candidatesarray (in which caseboundsmay beNone).modelis a model-matrix function (defaultpolynomial_features()degree 1, i.e. linear with intercept);criterionselects the optimality merit ("D"/"A"/"I"or any registered name / callable). The best design overn_restartsrandom starts is returned as an(n, d)array. For"I"optimality, prediction variance is averaged overref(a model matrix) when given, else over the candidate pool.All count controls are exact positive non-Boolean integers. Candidate and model matrices must be finite nonempty two-dimensional arrays with exactly one model row per candidate;
refis a finite nonempty model matrix with the same feature width. RaisesValueErrorif those contracts fail or ifnis below the number of model parameters (the information matrix would be singular), andInfeasibleDesignError(aValueErrorsubclass) ifnis otherwise sufficient by count but the candidate pool’s model matrix is rank-deficient – e.g. a constant or otherwise degenerate pool, wheren >= prows can never make up for the pool itself spanning fewer thanpindependent directions – or if, defensively, every exchange restart still fails to find a finite-merit design.
- polynomial_features(degree=1, *, bias=True)[source]
Return a model-matrix function building polynomial features up to
degree(with interactions).The returned
f(X)maps an(n, d)point array to an(n, p)model matrix: an optional intercept column, then every monomialprod(x_j)over index multisets of size1..degree(sodegree=1is linear,degree=2is a full quadratic response surface including the cross termsx_i x_j).
- d_criterion(info, *, ref=None)[source]
D-optimality merit:
log det M(-infifMis singular). Higher is better.Raises
ValueErrorifinfois not a finite, symmetric, PSD matrix.log detis computed via a Cholesky factorization (PSD-aware: it fails cleanly on a singularMrather than a raw determinant, which would happily return a number for any square matrix regardless of definiteness).
- a_criterion(info, *, ref=None)[source]
A-optimality merit:
-trace(M^{-1})(-infif singular). Higher is better.Raises
ValueErrorifinfois not a finite, symmetric, PSD matrix.
- i_criterion(info, *, ref=None)[source]
I-optimality merit:
-meanprediction variance overref(-infif singular).The prediction variance at a reference row
gisg M^{-1} g; this returns the negative mean over the reference model matrixrefso larger is better. Falls back to A-optimality when no reference set is supplied.Raises
ValueErrorifinfois not a finite, symmetric, PSD matrix, or ifrefis given and its column count does not matchinfo’s dimension.
- g_criterion(info, *, ref=None)[source]
G-optimality merit:
-maxprediction variance overref(-infif singular).Where I-optimality minimizes the average prediction variance, G-optimality minimizes its worst case over the reference region, so the fitted surface has a bounded error everywhere. Returns the negative maximum of
g M^{-1} gover the reference rows (falls back to the largest coefficient variancemax diag(M^{-1})when no reference set is given).Raises
ValueErrorifinfois not a finite, symmetric, PSD matrix, or ifrefis given and its column count does not matchinfo’s dimension.
- e_criterion(info, *, ref=None)[source]
E-optimality merit: the smallest eigenvalue of
M(higher is better).Maximizing the minimum eigenvalue of the information matrix shrinks the variance along the worst-determined parameter contrast, so no direction in coefficient space is left poorly estimated.
0for a singular (rank-deficient) design.Raises
ValueErrorifinfois not a finite, symmetric, PSD matrix.
- c_criterion(c)[source]
Return a c-optimality criterion targeting the linear combination
c'.betaof coefficients.c-optimality minimizes the variance of a specific quantity of interest
c'.beta(e.g. a contrast or a prediction at one point). The returned criterion has merit-c' M^{-1} c(-infif singular), so it plugs straight intooptimal_design()orregister_criterion().Raises
ValueError(eagerly, at construction) ifcis not 1-D, and (per call) ifinfois not a finite, symmetric, PSD matrix or ifc’s length does not matchinfo’s dimension.- Parameters:
c (ndarray)
- Return type:
Criterion
- register_criterion(name, fn, aliases=())[source]
Register an optimality criterion
fnundername(and anyaliases).fnis called asfn(info, *, ref)with the information matrixM = F.T @ Fand must return a merit thatoptimal_design()maximizes. This is the extension point for new criteria – registering is all that is needed, no edits to the exchange loop.
- available_criteria()[source]
Return the sorted names (and aliases) of all registered optimality criteria.
- class ConstrainedBayesOptResult(x, y, best_x, best_y, n_evaluations, failed_evaluations, stopped_reason, c, feasible, *, surrogate_repairs=())[source]
Bases:
BayesOptResultOutcome of a constrained Bayesian-optimization run.
cholds the(N, K)observed constraint values (feasible rows have all entries<= 0) andfeasibleis the corresponding boolean mask.best_x/best_yare the best feasible point; if no feasible point was found they fall back to the least-infeasible observation.
- probability_of_feasibility(mean, std)[source]
Return the per-point probability that all constraints are satisfied (
c_k <= 0).meanandstdare(n, K)posterior predictive moments of theKconstraint surrogates: rowiholds theKconstraint moments at pointi. A scalar or 1-D input of lengthnis treated asnpoints under a single constraint and reshaped to(n, 1)– it is never reinterpreted as one point undernconstraints. Returns an(n,)array, the product over constraints ofPhi(-mean_k / std_k). Where a constraint’sstdis zero the feasibility is deterministic (1.0 ifmean <= 0).- Raises:
ValueError –
meanandstddo not have identical shape once normalized, either is not finite,stdis negative anywhere, or there are zero constraint columns.- Parameters:
- Return type:
- propose_next_constrained(x, y, c, bounds, n_candidates=512, seed=None, *, maximize=False, xi=0.0, acq='ei', acq_kwargs=None, fit_kwargs=None, return_acquisition=False)[source]
Propose the next point under inequality constraints
c_k(x) <= 0.Fits a GP to the objective
(x, y)and one GP per constraint column ofc(an(N, K)array), then maximizes the feasibility-weighted acquisition overn_candidatesLatin-hypercube points. Until a feasible observation exists the acquisition factor is held at 1 so the search targets feasibility; afterwards the incumbent is the best feasible objective. Returns the chosen(d,)point, optionally with its merit.- Parameters:
- Return type:
- constrained_minimize(objective, constraints, bounds, n_init=5, n_iter=15, seed=None, *, maximize=False, xi=0.0, acq='ei', acq_kwargs=None, n_candidates=512, fit_kwargs=None)[source]
Constrained GP Bayesian optimization of
objectivesubject toconstraintsoverbounds.Each callable in
constraintsmaps a(d,)point to a scalar that is feasible when<= 0. Seeds with ann_init-point Latin-hypercube design, then runsn_iterfeasibility-weighted acquisition steps. Minimizes the objective by default; returns the best feasible point (or the least-infeasible one if none feasible) along with the full evaluation history.
- class MultiObjectiveResult(x, y, pareto_mask, pareto_x, pareto_y)[source]
Bases:
OptimizationResultOutcome of a multi-objective Bayesian-optimization run.
yis the(N, M)matrix of observed objective vectors (all minimized);pareto_maskflags the non-dominated rows, andpareto_x/pareto_yare those points and their objective vectors.
- pareto_mask(y)[source]
Return a boolean mask of the non-dominated rows of
y(an(N, M)minimization objective).Row
iis dominated when some other row is<=it on every objective and strictly<on at least one; the mask isTruefor the rows that survive (the Pareto-optimal set).Raises
ValueErrorifyis empty, wrong-width, or contains a non-finite (NaN/Inf) value.
- multi_minimize(objectives, bounds, n_init=10, n_iter=20, seed=None, *, rho=0.05, n_candidates=512, fit_kwargs=None)[source]
Multi-objective GP Bayesian optimization of
objectivesoverbounds(ParEGO).Each callable in
objectivesmaps a(d,)point to a scalar; all are minimized. Seeds with ann_init-point Latin-hypercube design, then runsn_itersteps, each drawing a random Tchebycheff weighting, scalarizing the observed objectives, and taking one GP-EI step on that scalar. Returns the full evaluation history and the Pareto-optimal subset.
- class BayesianOptimizer(bounds, *, acq='ei', acq_kwargs=None, maximize=False, n_init=None, xi=0.0, n_candidates=512, fit_kwargs=None, seed=None)[source]
Bases:
objectStateful ask-tell wrapper around the GP Bayesian-optimization loop.
askproposes the next point (or a batch),tellrecords evaluated observations, andbestreturns the incumbent. Minimizes by default; setmaximize=Trueto maximize. The acquisition is selected byacq("ei"/"pi"/"ucb"or any registered name / callable) with per-acquisition parameters inacq_kwargs.ask()tracks every point it returns as pending (asked, not yet told) until a matchingtell()call resolves it. A second, overlappingask()– issued before an earlier one’s points are told, as in a parallel/async evaluation campaign – folds those still-pending points into the surrogate fit as fantasized (kriging-believer) observations, the same mechanismpropose_batch()already uses to keep a single batch’s own picks apart, so acquisition is steered away from proposing them again (MXR-080-0188).- Parameters:
- property x: ndarray
Return the observed points as an
(N, d)array.
- property y: ndarray
Return the observed objective values as an
(N,)array.
- property n_observations: int
Return the number of recorded observations.
- property pending: ndarray
Return currently pending (asked, not yet told) points as a
(P, d)array.
- property n_pending: int
Return the number of currently pending (asked, not yet told) points.
- property best: BayesOptResult
Return the incumbent (best observed point) as a
BayesOptResult.
- ask(q=1)[source]
Return the next point to evaluate as a
(d,)array, or a(q, d)batch whenq > 1.The first
n_initpoints come from a space-filling design; subsequent points are GP acquisition proposals (a kriging-believer batch whenq > 1). Every returned point is tracked as pending untiltell()resolves it; a second, overlappingask()before anytell()folds still-pending points into the GP fit as fantasized observations so it is steered away from proposing them again (see the class docstring, MXR-080-0188).This call is atomic: if it raises (e.g. a GP proposal attempted with zero observations), no internal state changes, so a failed call is always safe to retry.
- tell(x, y)[source]
Record one or more evaluated observations; returns
selffor chaining.xis a(d,)point or(m, d)batch andythe matching scalar or(m,)values. Every point must be finite and withinbounds, and every outcome must be finite – a NaN/Inf in either would otherwise poison every downstream GP fit and acquisition score silently. Every point must also match a currently pending proposal, i.e. one this same optimizer’s ownask()actually returned and that has not already been told:a point that was never returned by
ask()(an unsolicited observation) is rejected – this is almost always a caller bug (wrong array, a stale point from a different optimizer), so it is rejected by default rather than silently accepted;a point that was already told (whether repeated within this same call or told in a previous one) is rejected as a duplicate –
tell()is write-once per point, there is no “update an existing observation” path.
(MXR-080-0188.) Raises
ValueErrorfor any of the above. Validation covers the whole batch before anything is applied, so a batch that is only partly invalid never half-applies.
- monte_carlo_qei(mean, cov, best, *, maximize=False, samples=512, seed=0)[source]
Monte-Carlo multi-point Expected Improvement of a batch with joint posterior
N(mean, cov).Draws
samplesjoint posterior realizations of theqbatch points and averages the batch improvement over the incumbentbest–max(best - min_i f_i, 0)for minimization, ormax(max_i f_i - best, 0)for maximization. Forq = 1this reduces to ordinary EI.- Raises:
ValueError – if
meanis empty,cov’s shape does not matchmean, either contains a non-finite value,covis not a valid (finite, PSD-within-tolerance) covariance, orsamplesis not a positive integer. See_safe_cholesky()for the covariance validation/healing policy – it never silently downgrades a true joint request to an independent one.- Parameters:
- Return type:
- propose_qei_batch(x, y, bounds, q, *, n_candidates=256, mc_samples=256, maximize=False, seed=None, gp=None, fit_kwargs=None)[source]
Propose a
q-point batch by greedy Monte-Carlo q-EI under the joint GP posterior.Fits the GP to
(x, y), then builds the batch one point at a time: each new point is the Latin-hypercube candidate maximizing the q-EI of{batch so far} + candidate(evaluated with common random numbers so the greedy comparison is fair). Because the joint posterior is used, an already-chosen point lowers the marginal value of nearby candidates, so the batch self-diversifies without any fantasized observations. Returns a(q, d)array.- Raises:
ValueError – if
q,n_candidates, ormc_samplesis not a positive integer, if there are zero observations, or if every candidate scores a non-finite q-EI merit at some batch step (rather than silently leaving that step’s pick undefined).- Parameters:
- Return type:
- propose_local_penalization(x, y, bounds, q, *, n_candidates=512, maximize=False, seed=None, gp=None, fit_kwargs=None)[source]
Propose a
q-point batch by local penalization (Gonzalez et al. 2016).Picks points sequentially from a single GP fit (no refitting): each pick maximizes the expected improvement multiplied by a soft exclusion factor around every pending pick. The exclusion radius is set from a Lipschitz estimate
Lof the objective (the largest posterior-mean gradient over the candidates) and the gap to the incumbent, so the penalty is principled rather than a fixed distance. Cheaper than q-EI for largeq(one GP fit, closed-form penalties). Returns a(q, d)array.- Raises:
ValueError – if
qorn_candidatesis not a positive integer, ifq > n_candidates, if there are zero observations, or if every candidate scores a non-finite acquisition merit (rather than lettingargmax– which treats NaN as the maximum – silently select one).- Parameters:
- Return type:
- max_value_entropy_search(mean, std, max_samples, *, maximize=True)[source]
Max-value Entropy Search acquisition at candidates with posterior
mean/std.Given samples
max_samplesof the global optimum valuey*, returns the per-candidate mutual informationI(y; y*) = (1/M) sum_m [ gamma_m phi(gamma_m)/(2 Phi(gamma_m)) - log Phi(gamma_m) ]withgamma_m = (y*_m - mu)/sd(maximization; for minimization the sense is flipped by the caller). Higher is better – it favors uncertain candidates near the believed optimum. A candidate withsd == 0is deterministic and scores exactly0: its observation is a constant, which carries no mutual information withy*(MXR-080-1901).- Raises:
ValueError – if
mean/stdare empty, mismatched in shape, non-finite, orstdis negative; ifmax_samplesis empty or non-finite; or if the resulting per-candidate information is non-finite (e.g. an extreme-but-individually-finitemean/std/max_samplescombination can overflowgamma = (y* - mu)/sdto +/-inf, andinf * 0in thegamma * pdfterm then silently yields NaN).- Parameters:
- Return type:
- sample_max_values(mean, std, n_samples=64, *, seed=0)[source]
Sample plausible global-max values
y*via the Gumbel approximation (Wang & Jegelka 2017).The CDF of the maximum over the candidate cloud is
P(max <= y) = prod_i Phi((y - mu_i)/sd_i); a Gumbel is fit to its 25/50/75 percentiles (found by bisection) and sampled. Returns an(n_samples,)array ofy*draws (never below the best posterior mean).- Raises:
ValueError – if
mean/stdare empty, mismatched in shape, non-finite, orstdis negative; or ifn_samplesis not a positive integer.- Parameters:
mean (Any)
std (Any)
n_samples (int)
seed (int | RandomState)
- Return type:
- propose_mes(x, y, bounds, *, n_candidates=512, max_samples=64, maximize=False, seed=None, gp=None, fit_kwargs=None)[source]
Propose the next point by Max-value Entropy Search.
Fits the GP to
(x, y), samplesmax_samplesoptimum values viasample_max_values(), scores Latin-hypercube candidates bymax_value_entropy_search(), and returns the maximizer as a(d,)array.maximizeselects the optimization sense (default minimize, matching the rest of the BO layer).
- turbo_minimize(objective, bounds, *, n_init=None, max_evals=100, batch_size=1, maximize=False, n_candidates=None, seed=None, fit_kwargs=None)[source]
Optimize a black-box
objectiveoverboundswith TuRBO (trust-region BO).Starts from a Latin-hypercube design of
n_initpoints (default2*d), then repeatedly fits a GP on the normalized data, draws Thompson candidates inside the current trust region, evaluates the bestbatch_sizeof them, and resizes the region by success/failure. On collapse it restarts from a new design. Runs untilmax_evalsobjective calls.n_init(default2*d),max_evals,batch_size, andn_candidates(defaultmin(2000, 100*d)) must each be exact positive integers – none is silently truncated or coerced.max_evals >= n_initand1 <= batch_size <= n_candidatesare both required up front: the first because the initial design alone spendsn_initreal evaluations before any GP step can begin, the second because a batch can never select more distinct candidates than the trust region generates for it, no matter how many times it retries (MXR-080-0196).A well-defined numerical failure while fitting the local GP or sampling its joint posterior (a singular or indefinite covariance –
numpy/torchlinalg.LinAlgError) shrinks the trust region and retries next iteration, the same policy as an ordinary non-improving batch. Anything else (a configuration or programming bug – a badfit_kwargsoptimizer name, a missing torch install, …) propagates instead of being silently caught and relabeled “model failure” (MXR-080-0197).Returns
{'x', 'y', 'X', 'Y', 'n_restarts', 'n_bayes_batches', 'n_fit_failures', 'last_fit_error', 'degraded_to_random_search', 'stopped_reason'}: the best point/value and the full evaluation history; how many trust-region collapses restarted from a fresh Latin-hypercube design (n_restarts); how many batches were genuine GP-guided Thompson proposals (n_bayes_batches) versus caught numerical failures (n_fit_failures, with the most recent one’s diagnostic string inlast_fit_error, elseNone);degraded_to_random_searchis True iff every batch attempt failed numerically, meaning the entire result came from Latin-hypercube restarts and the GP-guided search never once ran; andstopped_reasonis always"budget_exhausted"(this loop’s only normal termination) for any call that returns rather than raises.
- class TrustRegion(dim, length=0.8, length_min=0.0078125, length_max=1.6, success_tol=3, failure_tol=0)[source]
Bases:
objectExpand/shrink state of a TuRBO trust region (side length in normalized
[0, 1]^dcoordinates).The length doubles after
success_tolconsecutive improving batches and halves afterfailure_tolconsecutive non-improving ones;collapsedis True once it drops belowlength_minand the caller should restart.failure_toldefaults to the dimension (Eriksson 2019).__post_init__validates the complete region invariant (MXR-080-0196):dimis an exact positive integer;length,length_min, andlength_maxare finite with0 < length_min <= length <= length_max(so the region can never start collapsed, inverted, or unboundedly sized);success_tolis an exact positive integer andfailure_tolan exact non-negative one (0is the “default todim” sentinel resolved right below). Anything outside that invariant raises immediately instead of accepting geometry with no sensible search meaning – e.g. alength_max < length_minwould let a “successful” expansion (min(length * 2, length_max)) silently shrink the region, and a non-finite/non-positivelengthwould make every candidate box_tr_candidates()draws undefined or empty.- Parameters:
- property collapsed: bool
Return whether the trust-region length has shrunk below its usable minimum.
- update(improved)[source]
Return the next validated state after recording one batch outcome.
States are immutable: callers must retain the returned instance. This prevents a region that passed construction validation from later being assigned invalid geometry.
- Parameters:
improved (bool)
- Return type:
TrustRegion
- alm_scores(gp, x, y, candidates)[source]
Active Learning MacKay scores: the GP posterior predictive variance at each candidate.
- alc_scores(gp, x, y, candidates, reference)[source]
Active Learning Cohn / IMSE scores: integrated posterior-variance reduction per candidate.
Adding candidate
creduces the posterior variance at a reference pointrbycov_post(r, c)^2 / var_post(c); this returns the sum over the reference set (the negative change in integrated MSE), so the maximizer is the most globally informative next point.
- propose_active_learning(x, y, bounds, *, method='alc', n_candidates=512, n_reference=256, seed=None, gp=None, fit_kwargs=None)[source]
Propose the next active-learning point (
method='alc'IMSE, or'alm'max variance).n_candidates(andn_reference, formethod='alc') must be exact positive integers (MXR-080-0158): a fractional count used to be silently truncated by a bareint()cast, and ann_reference=0reduced ALC to an empty reference set (all-zero merits, an arbitrary argmax).
- active_learning_design(objective, bounds, *, n_init=None, max_evals=40, method='alc', seed=None, fit_kwargs=None)[source]
Sequentially place points to maximize surrogate accuracy, returning the design and its responses.
Starts from a Latin-hypercube design, then repeatedly fits the GP and adds the most informative point (by
method) untilmax_evalsevaluations. Returns{'X', 'Y'}– a design tailored to learnobjectivewell everywhere, not just near an optimum.n_init(default2 * len(bounds)) andmax_evalsmust both be exact positive integers with1 <= n_init <= max_evals(MXR-080-0158): an initial design bigger than the whole budget used to be evaluated in full and returned over budget instead of rejected, a fractional count was silently truncated, and an explicitn_init=0was silently replaced by the default rather than treated as the caller error it almost certainly is.
- expected_information_gain_linear(model_matrix, *, noise=1.0, prior_cov=None)[source]
Exact expected information gain of a linear-Gaussian design
y = F.theta + eps(= Bayesian D-opt).For a Gaussian prior
theta ~ N(0, Sigma0)and observation noiseeps ~ N(0, noise^2 I), the mutual information between the data andthetais0.5 * log det(I_p + noise^-2 Sigma0 F^T F).model_matrixis the(n, p)design matrixF(e.g. frommixle.doe.optimal.polynomial_features()). Higher EIG = a more informative design.By Sylvester’s determinant identity,
det(I_p + Sigma0 F^T F / noise^2) == det(I_n + F Sigma0 F^T / noise^2)exactly – the two sides differ only in which of the(p, p)or(n, n)matrix gets formed and factorized. This function forms whichever is smaller. That matters beyond speed: scoring a handful of candidate observations (nsmall, e.g. a few new monitoring sites) against a model with many parameters (plarge, e.g. hundreds of grid cells) is exactly this function’s typical caller (mixle_pde.monitoring_design,mixle_pde.geophysics), and forming the full dense(p, p)matrix in that regime is reliably ill-conditioned forslogdet– verified to throw spurious divide-by-zero/overflowRuntimeWarning``s on a real ``p=720case that the(n, n)formulation computes cleanly (identical value, to float64 precision, with zero warnings).noisemust be finite and strictly positive, andprior_cov(when given) must be a finite, symmetric, positive-semidefinite(p, p)matrix – a real covariance, not merely a matrix that happens to make a determinant come out positive (MXR-080-0159: invalid inputs used to reachslogdetunchecked and could return-infor a plausible-looking scalar for a model that is not actually a probability distribution). Given valid inputs, the information matrix is guaranteed symmetric positive-definite by construction (an identity plus a PSD term), so its log-determinant is computed from a Cholesky factorization –2 * sum(log(diag(L)))– rather thanslogdet: more numerically stable, and it doubles as a final validity check.F Sigma0 F^T(then <= pfast path) is symmetric for any symmetricSigma0, since it is sandwiched byF/F^T, butSigma0 F^T F(the other order, needed whenp < n) is generally not, even though both factors are – the product of two symmetric matrices need not commute – so that branch instead sandwichesF^T Fbetween a symmetric square root ofSigma0, which keeps the determinant exactly (Sylvester’s identity again) while keeping the matrix handed to Cholesky genuinely symmetric.
- expected_information_gain_nmc(prior_sampler, log_likelihood, simulate, *, n_outer=256, n_inner=256, seed=None)[source]
The nested-Monte-Carlo EIG point estimate.
A thin wrapper around
expected_information_gain_nmc_estimate()for callers that only want the point value; see its docstring for the full draw-contract validation (MXR-080-0160) and for how to also get the Monte Carlo standard error / confidence interval.
- multi_fidelity_minimize(objective, bounds, *, fidelities=(0.5, 1.0), costs=None, target=None, n_init=None, max_cost=40.0, n_candidates=256, maximize=False, seed=None, fit_kwargs=None)[source]
Cost-aware multi-fidelity Bayesian optimization of
objective(x, s).objective(x, s)returns the response at inputxand fidelitys(one offidelities); the largest fidelity (ortarget) is the true objective.target, if given, must itself be one offidelities: this function never evaluates a fidelity outside that set, so an out-of-set target could otherwise only ever be “satisfied” by silently substituting a lower-fidelity response for it.costsis the per-fidelity evaluation cost (default: the fidelity value itself) and, if given, must supply exactly one entry per fidelity. The loop fits a GP over[x, s], proposesxby Expected Improvement at the target fidelity, then evaluates at the fidelity maximizing target-variance reduction per unit cost. Every evaluation – initial per-fidelity seeding and the sequential loop alike – reserves its cost againstmax_costbefore callingobjective, so cumulative cost never overshootsmax_cost; amax_costtoo small to afford even one evaluation is rejected up front.Returns
{'x', 'y', 'X', 'Y', 'cost', 'target_evaluated', 'stopped_reason', 'error', 'failed_evaluations'}.X/Yare the usable finite augmented evaluation history (fidelity in the last column ofX) andcostis the total actually spent, including failed calls.failed_evaluationsseparately preserves each unusable attempt’s point, fidelity, cost, status, and error.x/yare the best target-fidelity point and response, but only whentarget_evaluatedis true: if the budget ran out before any target-fidelity evaluation was affordable,x/yareNonerather than silently standing in a lower-fidelity result for the target-fidelity answer the caller asked for.stopped_reasonis"budget_exhausted"(the loop ran until no further evaluation fit inmax_cost– the normal, successful termination for this optimizer, which has no other stopping criterion) or"surrogate_fit_failed"(a well-defined numerical failure – e.g.numpy/torchlinalg.LinAlgErrorfrom a singular covariance – aborted the loop early;errorthen holds a diagnostic string, elseNone). Any other exception out of surrogate fitting (a badfit_kwargsoptimizer name, a missing torch install, …) propagates rather than being reported as a quiet early stop.
- sobol_indices(func, bounds, n=4096, *, seed=0, names=None, n_bootstrap=200, confidence=0.95)[source]
First- and total-order Sobol sensitivity indices (Saltelli sampling, Jansen estimators).
- Parameters:
func (Callable[[ndarray], ndarray]) – a vectorized model
f(X) -> ymapping an(m, d)array of inputs to an(m,)array of scalar outputs.bounds (Sequence[tuple[float, float]]) –
[(lo, hi), ...]per input – the input is taken uniform on the box.n (int) – base sample size; the total number of model evaluations is
n * (d + 2)(bootstrap resampling below is free of additionalfunccalls, so this count is exact).seed (int) – RNG seed for the (Sobol) base samples.
names (Sequence[str] | None) – optional input names for the returned dict.
n_bootstrap (int) – number of bootstrap resamples used for the standard error / confidence interval of each index (see “Returns” below).
confidence (float) – confidence level for the bootstrap interval, in
(0, 1)– e.g.0.95for a two-sided 95% interval.
- Returns:
'S1'/'ST': the raw, unclipped point estimate. A finite-sample Sobol estimator can legitimately land slightly negative, or (forS1) slightly above 1, purely from Monte Carlo noise – most often when the true index is near 0 or 1. That is not a bug in the estimate; it is the honest signal that sampling noise is comparable to the index’s true magnitude, and this raw value is always what is returned here (never silently clamped).'S1_clipped'/'ST_clipped': the same estimate clipped into its theoretically valid range (S1into[0, 1],STbelow at0) – a separate, explicitly-named convenience for e.g. plotting or reporting a single non-negative “share of variance”; never the only value returned, and never used in place of the raw estimate above.'S1_standard_error'/'ST_standard_error': a bootstrap standard error, fromn_bootstrapresamples (with replacement) of the already-evaluatedA/B/AB_irows, each re-run through the same S1/ST formula – the standard uncertainty-quantification approach for Sobol’ estimators (Archer, Saltelli & Sobol’ 1997), since no exact closed-form sampling distribution exists for them in general.'S1_ci_low'/'S1_ci_high'and'ST_ci_low'/'ST_ci_high': the corresponding percentile bootstrap confidence interval at theconfidencelevel.
Plus
'names','var'(the total output variance), and'sampling_method'(normally'scrambled_sobol';'pseudorandom_fallback'only when SciPy’s QMC capability is absent).S1[i]is the fraction of output variance from inputialone;ST[i]includes all interactions involvingi(soST[i] - S1[i]measuresi’s interaction strength, andST[i] ~ 0– relative to its standard error, not just numerically close – means inputican be fixed).- Return type:
A dict with, for both first- and total-order
- morris_screening(func, bounds, *, trajectories=20, levels=4, seed=0, names=None)[source]
Morris elementary-effects screening – a low-cost first factor ranking.
Walks
trajectoriesrandomized-direction one-factor-at-a-time paths on alevels-point grid per dimension (Morris 1991; Campolongo, Cariboni & Saltelli 2007); the mean absolute elementary effectmu_star[i]ranks influence and the spreadsigma[i]flags nonlinearity/interactions. Cost:trajectories * (d + 1)evaluations – far fewer than Sobol, for an initial screen.Each trajectory walks the grid
{0, 1/(p-1), 2/(p-1), ..., 1}(p = levels) and takesdone-at-a-time steps, one per input in a random order, each changing exactly one coordinate by the fixed stepdelta = p / (2*(p-1)) = (p/2) / (p-1)– i.e. exactlyp/2grid points, chosen (the standard choice) so the step always lands exactly on another grid point. Both the visit order and each dimension’s step direction (up bydeltaor down bydelta) are independently randomized per trajectory. The starting coordinate for a dimension stepping up is drawn only from the grid’s lower half (indices0..p/2-1, which by construction have room for a+deltamove without leaving[0, 1]); for a dimension stepping down, only from the upper half (indicesp/2..p-1, symmetric room for-delta). Every step therefore lands on the grid and inside bounds by construction – never clipped or silently shrunk to a smaller step – and, because the two halves are equal-sized and a dimension’s pre-step value is confined to its assigned half while its post-step value always lands in the other, every grid level is visited with equal (1/p) probability, marginally, by any one coordinate at any position along a trajectory: the design is unbiased across the input box, not concentrated away from either boundary.levelsmust be even, so the grid-index steplevels // 2is exact (an odd level count has no step that both equals the standarddeltaformula and lands on a grid point).
- fast_indices(func, bounds, n=600, *, harmonics=6, seed=0, names=None, n_bootstrap=200, confidence=0.95)[source]
First-order sensitivity indices via Random Balance Designs FAST (RBD-FAST).
A Fourier alternative to
sobol_indices()for the first-order indices: every input is driven along the same triangle-wave search curve but under an independent random permutation, the model is evaluated once over thenpoints, and for each input the output – reordered along that input’s curve – has its variance concentrated at the base frequency’s firstharmonicsharmonics. The ratio of that power to the total is the first-order index (with the Tarantola bias correction). Cost is a single batch ofnevaluations, independent of dimension.S1is the raw Tarantola-corrected finite-sample estimate.S1_clippedis a separate presentation convenience. Circular moving-block bootstrap fields report the raw estimator’s standard error and percentile interval without additional model evaluations.
- dgsm(func, bounds, n=1024, *, seed=0, rel_step=1.0e-4, names=None)[source]
Derivative-based global sensitivity measures (DGSM): mean squared partial derivatives.
nu[i] = E[(df/dx_i)^2]over the input box, estimated by central finite differences atnlow-discrepancy points. Unlike the first-order Sobol index, a DGSM is nonzero whenever an input matters anywhere – including purely through interactions – so it is a low-cost, robust screen that upper-bounds the total Sobol index (Sobol & Kucherenko, via the Poincare inequality:ST[i] <= (L_i / pi)^2 * nu[i] / Var(y)for a uniform input of widthL_i). The reportedimportanceisL_i^2 * nu[i]normalized to sum to one – a dimensionless influence ranking.Returns
{'nu': (d,), 'importance': (d,), 'names': [...]}.
- propagate(func, mean, cov=None, *, n=10000, method='montecarlo', quantiles=(0.05, 0.5, 0.95), seed=0)[source]
Propagate a Gaussian input
N(mean, cov)throughfuncto output statistics.- Parameters:
func (Callable[[ndarray], ndarray]) – a vectorized model
f(X) -> ymapping(m, d)inputs to(m,)(or(m, k)) outputs.mean (ndarray) – length-
dinput mean.cov:(d, d)input covariance (defaults to identity).n (int) – Monte Carlo sample size (ignored by the unscented method).
method (str) –
'montecarlo'(sample + summarize, gives quantiles) or'unscented'(sigma-point moment propagation, mean + std only). Looked up through the propagator registry.quantiles (tuple[float, ...]) – output quantiles to report (Monte Carlo only).
cov (ndarray | None)
seed (int)
- Returns:
{'mean', 'std', 'quantiles' (mc only), 'samples' (mc only)}.- Raises:
ValueError – if
meanis non-finite,cov’s shape doesn’t matchmean,covis not a valid (finite, PSD-within-tolerance) covariance,nis not a positive integer, anyquantilesentry is outside[0, 1], ormethodis not registered.- Return type:
- register_propagator(name)[source]
Decorator registering a propagation method under
nameforpropagate().The decorated callable receives
(func, mean, cov, *, n, quantiles, seed)(mean/covalready coerced to float arrays) and returns the output-statistics dict.(MXR-080-1901) Registering a name that is already taken raises instead of replacing it. The old
_PROPAGATORS[name] = fnsilently overwrote, so re-registering"montecarlo"(by import order, a name collision between two plugins, or a module imported twice) changed what EVERY existingpropagate(..., method="montecarlo")call in the process returns – the same call site, the same documented method name, different outputs, and nothing anywhere recording the substitution. This is the registry’s only mutation point, so refusing the collision here is enough to make a resolved method name mean one fixed thing for the life of the process. Adding a NEW name is unaffected: that is the extension point and it stays open. To deliberately replace a built-in, delete the existing entry from_PROPAGATORSfirst – an explicit, greppable act rather than an invisible one.
- unscented_transform(func, mean, cov, *, alpha=1e-3, beta=2.0, kappa=0.0)[source]
Propagate
(mean, cov)throughfuncwith the unscented (sigma-point) transform.Returns the output
(mean, covariance). Exact for an affinefunc; for a nonlinear one it captures the mean and covariance to second order with only2d+1evaluations.- Raises:
ValueError – if
meanis non-finite,cov’s shape doesn’t matchmean,covis not a valid covariance (see_safe_cholesky()),alpha/beta/kappaare not finite non-Boolean scalars,alpha <= 0,beta < 0,d + lambda <= 0,func’s return doesn’t have a leading dimension of2d+1(rejected explicitly, not silently reinterpreted via a total-size-only reshape), orfunc’s return or derived covariance is non-finite/invalid.- Parameters:
- Return type:
- noisy_minimize(objective, bounds, n_init=5, n_iter=15, seed=None, *, maximize=False, gp=None, fit_kwargs=None, **minimize_kwargs)[source]
Bayesian optimization of a NOISY objective, reporting the posterior-mean incumbent.
Runs
mixle.doe.bayesopt.minimize()(same exploration), then replaces the rawargmin-of- observations incumbent with the posterior-mean incumbent (posterior_incumbent()), sobest_xis the model’s believed optimum rather than the luckiest noisy draw andbest_yis its denoised estimate. The full(x, y)evaluation history is preserved on the result.
- posterior_incumbent(x, y, *, maximize=False, gp=None, fit_kwargs=None)[source]
Among the evaluated points
x, return the one with the best GP POSTERIOR MEAN (min by default).Fits a GP surrogate on
(x, y)– the same surrogate the BO loop uses – and predicts the denoised mean at every evaluated point, so the reported optimum reflects the model’s belief, not a single lucky noisy observation. For a deterministic objective the posterior mean at the observed points is ~the observations, so this reduces to the ordinary argmin/argmax.Raises
ValueErrorifxcontains non-finite values, or if the surrogate’s predicted mean doesn’t match the candidate contract (wrong length, non-finite, or entirely non-finite – seemixle.doe.bayesopt._validate_prediction()/_select_index), the same shared surrogate boundary the sequential/batch/knowledge-gradient proposal paths use (MXR-080-0170).
- class IncumbentResult(best_x, best_mean, best_index)[source]
Bases:
objectThe posterior-mean incumbent among evaluated points: its location, posterior mean, and index.
- calibrate(simulator, x, y, theta0, *, discrepancy=True, discrepancy_lengthscale=None, seed=0, max_iter=1000)[source]
Calibrate
simulator(x, theta)to field data(x, y)with a GP discrepancy term.Maximizes the marginal likelihood of the residual
r(theta) = y - eta(x, theta)under a GP + noise model, overthetaand the discrepancy amplitude + noise.discrepancy=Falsedrops the GP (plain nonlinear least squares) – useful to show the bias the discrepancy removes.The discrepancy correlation length is fixed (
discrepancy_lengthscale, default 10% of the input domain) rather than fitted: this is the standard resolution of the Kennedy-O’Hagantheta/deltaidentifiability problem – a short discrepancy length forces the GP to model only local model-form error, leaving the smooth global trend to the parametric simulator sothetastays identifiable. Set it to the scale of model error you expect.- Parameters:
simulator (Callable[[ndarray, ndarray], ndarray]) –
eta(x, theta) -> predictions(vectorized over the rows ofx).x (ndarray) – field inputs and observations.
xandymust have the same number of rows, andx,y,theta0, andsimulator(x, theta0)must all be finite.y (ndarray) – field inputs and observations.
xandymust have the same number of rows, andx,y,theta0, andsimulator(x, theta0)must all be finite.theta0 (Sequence[float]) – initial calibration parameters (its length sets the parameter count). There must be more observations than free
thetaparameters, and the fitted simulator sensitivity matrix must have full parameter-column rank.discrepancy (bool) – include the GP discrepancy term (the Kennedy-O’Hagan model).
discrepancy_lengthscale (float | None) – fixed GP correlation length;
None(default) uses 10% of the input domain. If given explicitly it must be positive – unlikeNone,0is not silently treated as “use the default”: a caller-supplied non-positive value is a contract violation, not a request for the default.seed (int) – seeds the small, reproducible random perturbation used to initialize the optimizer, so the same seed value reproduces the same fit and a different seed can escape an exact tie or a degenerate flat ridge at the unperturbed starting point.
max_iter (int) – positive optimizer iteration budget. Reused, unmodified, for the internal no-discrepancy warm-start fit when
discrepancy=True.
- Raises:
ValueError – on an
x/yrow-count mismatch, non-finitex/y/theta0/simulator(x, theta0), asimulator(x, theta0)shape that does not matchy, a non-positivediscrepancy_lengthscaleormax_iter, fewer observations thanthetaparameters, rank-deficient simulator sensitivity, or if the optimizer fails to converge to a finite objective.- Return type:
KOCalibration
- class KOCalibration(theta, ls, amp, noise, simulator, x, y, theta_standard_error=None, *, sensitivity_rank=None, sensitivity_singular_values=None, sensitivity_condition_number=None)[source]
Bases:
objectResult of
calibrate(): a POINT MLE of the fitted parameters (not a posterior), the discrepancy GP, and a calibrated predictor.thetais the maximizer of the (marginal) likelihood, not a full Bayesian inference of it – there is no prior and no posterior distribution overthetahere.theta_standard_erroris an asymptotic (Laplace / observed-Fisher-information) standard error for eachthetacomponent, from the inverse Hessian of the negative log-likelihood at the MLE;theta_ci_low/ci_highare the corresponding two-sided 95% Wald intervals (theta +- 1.96 * theta_standard_error). This is a local, asymptotic approximation (it can be optimistic for smalln, strong parameter correlation, or a non-quadratic likelihood near the optimum) – not a substitute for a real posterior when that matters. All three are arrays ofnanwhen the Hessian at the optimum is not numerically invertible (or not positive-definite), which the point estimate itself does not depend on.sensitivity_rank,sensitivity_singular_values, andsensitivity_condition_numbercertify local structural identifiability; a rank-deficient fit raisesCalibrationIdentifiabilityErrorinstead of returning an arbitrary point.All fitted arrays are privately copied and frozen. Array properties return detached copies, so neither caller-owned inputs nor a returned view can retroactively change the fitted residual, interval, or predictor.
- Parameters:
- property theta: ndarray
Detached fitted parameter vector.
- predict(x_new, *, with_discrepancy=True)[source]
Calibrated prediction at
x_new: simulator at the fittedtheta, plus the GP discrepancy (the bias-corrected estimate of reality) unlesswith_discrepancy=False(the pure simulator).
- exception CalibrationIdentifiabilityError(*, rank, n_parameters, singular_values, non_identifiable_directions)[source]
Bases:
ValueErrorRaised when simulator sensitivity cannot identify every calibration-parameter direction.
Submodules¶
- mixle.doe.active module
- mixle.doe.amplify module
- mixle.doe.analysis module
- mixle.doe.batch module
- mixle.doe.bayesopt module
- mixle.doe.calibrate module
- mixle.doe.constrained module
- mixle.doe.designs module
- mixle.doe.distillation module
- mixle.doe.entropy module
- mixle.doe.factorial module
- mixle.doe.mixture module
- mixle.doe.multifidelity module
- mixle.doe.multiobjective module
- mixle.doe.optimal module
- mixle.doe.optimizer module
- mixle.doe.oracle module
- mixle.doe.propagate module
- mixle.doe.robust module
- mixle.doe.sensitivity module
- mixle.doe.sequential module
- mixle.doe.trust_region module