mixle.doe.batch module

Rigorous batch (multi-point) Bayesian optimization for parallel experiment campaigns.

The kriging-believer batch in mixle.doe.bayesopt fantasizes the posterior mean at each pick – low-cost, but it discards the correlation between the batch points and the posterior uncertainty they share, so it can place near-duplicate points. This module proposes batches under the true joint GP posterior:

  • monte_carlo_qei() – the multi-point Expected Improvement E[max(best - min_i f(x_i), 0)] of a candidate batch with joint posterior N(mu, Sigma), estimated by Monte Carlo (Ginsbourger et al. 2010); the exact generalization of EI to q simultaneous evaluations.

  • propose_qei_batch() – greedily builds a q-point batch, each new point maximizing the q-EI of the batch-so-far-plus-candidate under the joint posterior. Rigorous (no fantasies) and tractable.

  • propose_local_penalization() – the Gonzalez et al. (2016) local-penalization batch: pick points one at a time but multiply the acquisition by a soft exclusion zone around the pending picks, sized by a Lipschitz estimate of the objective. Scales to large q without joint sampling.

monte_carlo_qei is pure NumPy. The proposal drivers fit the torch GP surrogate (like the rest of the BO layer), so they require PyTorch.

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 samples joint posterior realizations of the q batch points and averages the batch improvement over the incumbent best – max(best - min_i f_i, 0) for minimization, or max(max_i f_i - best, 0) for maximization. For q = 1 this reduces to ordinary EI.

Raises:

ValueError – if mean is empty, cov’s shape does not match mean, either contains a non-finite value, cov is not a valid (finite, PSD-within-tolerance) covariance, or samples is 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:

float

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, or mc_samples is 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:

ndarray

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 L of 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 large q (one GP fit, closed-form penalties). Returns a (q, d) array.

Raises:

ValueError – if q or n_candidates is not a positive integer, if q > n_candidates, if there are zero observations, or if every candidate scores a non-finite acquisition merit (rather than letting argmax – which treats NaN as the maximum – silently select one).

Parameters:
Return type:

ndarray