mod screen¶
- module screen¶
Deciding which trials are worth relaxing, under a posterior.
The expensive step in a cluster search is the local relaxation, at roughly thirty charged evaluations against one for a proposal, and most trials are not worth it. The cheap version of that decision is a threshold on the energy after a few relaxation steps, and it is the one mechanism in this crate that is measurably worth having: at 75 points it takes the success rate from 2 seeds in 8 to 13 in 24. Its threshold is a hand-set margin.
This replaces the margin with inference. A partial relaxation supplies cheap features, the full relaxation supplies the answer, and a Bayesian linear model of the second given the first says how plausible it is that finishing the relaxation would improve on the incumbent. Spending the thirty evaluations is then a decision under a posterior rather than a comparison against a constant, which is what probabilistic numerics asks of a numerical procedure: treat the quantity you have not computed as unknown, not as absent.
Why the exploration floor is not optional
The model is trained on the trials it chose to relax, so a rule that relaxes only where it already predicts improvement never sees a counterexample and its own confidence is self-confirming. A fixed fraction of trials is relaxed regardless of the posterior, which keeps the training set from being censored by the decision rule it trains. This is the same reason a bandit keeps a floor on every arm, and
crate::allocatedoes it there.The approximation, stated
The conjugate Normal-Inverse-Gamma posterior gives a Student-t predictive. The tail probability here uses the Gaussian with the same variance, which is exact in the limit of many observations and understates the tails below it. That is why nothing is decided by the model until
Screen::warmupobservations have arrived; before then every trial is relaxed.Functions
- fn cost_asymmetric_threshold(screen_steps: usize, relax_steps: usize) -> f64¶
Bayes threshold from the hop’s own step counts.
Finishing the quench costs
Q = R - Sextra evaluations. A discarded winner costs one full hopRof opportunity. Net value of quenching isp R - (1-p) Q, which is positive exactly when p > Q / (Q + R) = (R - S) / (2 R - S).For the measured hop (
S = 25,R = 200) this is7/15, not a knob.
Structs and Unions
- struct DropModel¶
Remaining drop
D = E_sc - E_fullof a purchased quench.Features are an intercept and the screened energy. The predicted landing is
E_sc - E[D | E_sc]. A trial whose landing sits on a known floor is refused by the caller; this type only predicts the drop.Implementations
- impl DropModel¶
Functions
- fn calibrated(&self) -> bool¶
Whether enough purchased pairs have arrived to trust a refuse.
- fn new() -> Self¶
Weak prior, no exploration floor: the caller decides whether to buy.
- fn observations(&self) -> usize¶
Observations folded in.
- fn observe(&mut self, e_sc: f64, e_full: f64)¶
Fold in one purchased pair.
- fn predict_drop(&self, e_sc: f64) -> Option<(f64, f64)>¶
Predictive remaining drop at
e_sc.
- fn predicted_full(&self, e_sc: f64) -> Option<f64>¶
Predicted full-quench energy.
- fn warmup(&self) -> usize¶
Purchased pairs required before a predicted landing may refuse a quench.
This is the screen warmup the model was built with, not a search-level knob: refusing before it has seen that many pairs starves the driver.
Traits implemented
- struct Screen¶
Features of a partially relaxed trial, and whether it deserves a full one.
The design vector is the caller’s. What the model needs is that it be cheap relative to a relaxation and computed the same way at fit time and at decision time.
- warmup: usize¶
Observations required before the posterior is used at all.
- exploration: f64¶
Fraction of trials relaxed regardless of what the model says.
- threshold: f64¶
Posterior probability of improvement above which a trial is relaxed.
Set from the cost asymmetry rather than by taste: relaxing costs a fixed number of evaluations, and failing to relax a trial that would have improved costs the search that improvement. A low threshold spends more and misses less.
- decided: usize¶
Decisions made, and how many said relax.
- relaxed: usize¶
Of those, how many were relaxed.
- explored: usize¶
Relaxations forced by the exploration floor.
Implementations
- impl Screen¶
Functions
- fn coefficients(&self) -> Option<Array1<f64>>¶
Posterior mean of the coefficients, or
Nonebefore anything is known.
- fn decide(&mut self, x: ArrayView1<f64>, best: f64, u: f64) -> bool¶
Whether to pay for the full relaxation of a trial with features
x, given the incumbentbest.uis a uniform draw supplied by the caller, so the decision is reproducible under the caller’s seed rather than reaching for its own randomness.
- fn new(d: usize, warmup: usize, exploration: f64, threshold: f64) -> Self¶
A screen over
dfeatures, with a weak prior.The prior precision is a small multiple of the identity, which is a ridge: it keeps the first few updates from producing an ill-conditioned posterior without expressing an opinion about the coefficients.
- fn observations(&self) -> usize¶
Observations folded in so far.
- fn observe(&mut self, x: ArrayView1<f64>, y: f64)¶
Records a trial whose full relaxation is known.
- fn predict(&self, x: ArrayView1<f64>) -> Option<(f64, f64)>¶
Predictive mean and variance at
x.The variance is the Student-t scale, which carries both the noise and the uncertainty in the coefficients; the second term is what makes a trial unlike anything seen before come out uncertain rather than confidently predicted.
- fn probability_of_improvement(&self, x: ArrayView1<f64>, best: f64) -> Option<f64>¶
Posterior probability that a full relaxation would land below
best.