mixle.doe.trust_region module

Trust-region Bayesian optimization (TuRBO, Eriksson et al. 2019) for higher-dimensional problems.

Global GP-BO degrades in high dimensions: one global surrogate is hard to fit and the acquisition is over-exploratory. TuRBO instead keeps a trust region – a box centered on the best point – and runs the BO only inside it, via Thompson sampling. The box side length grows after consecutive improvements and shrinks after consecutive failures; when it collapses, the search restarts from a fresh design. This local, self-tuning focus makes BO work for tens of dimensions where global EI stalls.

turbo_minimize() is the optimization loop (it calls your objective); TrustRegion is the expand/shrink state if you want to drive the loop yourself. Both fit the torch GP surrogate.

class TrustRegion(dim, length=0.8, length_min=0.0078125, length_max=1.6, success_tol=3, failure_tol=0)[source]

Bases: object

Expand/shrink state of a TuRBO trust region (side length in normalized [0, 1]^d coordinates).

The length doubles after success_tol consecutive improving batches and halves after failure_tol consecutive non-improving ones; collapsed is True once it drops below length_min and the caller should restart. failure_tol defaults to the dimension (Eriksson 2019).

__post_init__ validates the complete region invariant (MXR-080-0196): dim is an exact positive integer; length, length_min, and length_max are finite with 0 < length_min <= length <= length_max (so the region can never start collapsed, inverted, or unboundedly sized); success_tol is an exact positive integer and failure_tol an exact non-negative one (0 is the “default to dim” sentinel resolved right below). Anything outside that invariant raises immediately instead of accepting geometry with no sensible search meaning – e.g. a length_max < length_min would let a “successful” expansion (min(length * 2, length_max)) silently shrink the region, and a non-finite/non-positive length would 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

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 objective over bounds with TuRBO (trust-region BO).

Starts from a Latin-hypercube design of n_init points (default 2*d), then repeatedly fits a GP on the normalized data, draws Thompson candidates inside the current trust region, evaluates the best batch_size of them, and resizes the region by success/failure. On collapse it restarts from a new design. Runs until max_evals objective calls.

n_init (default 2*d), max_evals, batch_size, and n_candidates (default min(2000, 100*d)) must each be exact positive integers – none is silently truncated or coerced. max_evals >= n_init and 1 <= batch_size <= n_candidates are both required up front: the first because the initial design alone spends n_init real 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/torch linalg.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 bad fit_kwargs optimizer 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 in last_fit_error, else None); degraded_to_random_search is True iff every batch attempt failed numerically, meaning the entire result came from Latin-hypercube restarts and the GP-guided search never once ran; and stopped_reason is always "budget_exhausted" (this loop’s only normal termination) for any call that returns rather than raises.

Parameters:
Return type:

dict[str, Any]