mod quench

module quench

Stopping a screening quench on a decision rather than an iteration count.

Measured on 38 points, 89 to 92 per cent of the charged budget goes into the screening pass: 12 383 hops spent 357 000 evaluations screening and 30 000 relaxing, because every proposal pays a fixed 25 descent steps whether or not the answer was settled after three. The screen exists to decide one question, whether finishing this relaxation can beat the incumbent, and a fixed length answers it at whatever precision that length happens to buy.

The descent supplies the information to stop earlier. A quench into a basin that is locally quadratic decreases its energy by decrements that shrink geometrically, so a short prefix of the trajectory already says roughly where it is going. Fitting that decay and extrapolating gives a predicted limit with an uncertainty attached, and the uncertainty is what makes it a decision: stop when the predicted limit is above the incumbent by more than the prediction error, or below it by more, and keep going only while the two are within reach of each other.

The model

Write the decrements as d_k = E_k - E_{k+1}. Under a geometric decay d_k = d_0 r^k with 0 < r < 1`, the energy remaining below ``E_k` is the tail sum_{j>=k} d_j = d_k r / (1 - r), so the limit is

E_inf = E_k - d_k * r / (1 - r)

and the ratio is estimated by least squares on log d_k against k. The residual scatter of that fit propagates to the tail, which is where the uncertainty comes from. Fitting in log space rather than on the decrements themselves is what keeps a single large early decrement from setting the rate: the first steps of a quench from a perturbed structure are not in the quadratic region at all, and on a linear fit they dominate every later point.

Measured, and off

The model does not hold on real quenches. Scoring each extrapolation against the value the full pass reaches, without acting on it, gives a mean absolute error of 12442 at the step where the rule would have stopped, 993 at a warmup of eight, 19.1 at twelve and 3.6 at sixteen. Minima near the bottom of the 38 point landscape are separated by well under one unit, so a usable energy costs about twenty of the twenty-five steps.

Acting on it is worse than the error alone suggests: with the extrapolated energy driving acceptance, eight seeds solved nothing where the fixed screen solved eight, because a chain handed energies off by four orders of magnitude rejects everything and stops exploring.

What this settles is not the rule but the premise behind it. The screening pass looked like overhead because it takes 89 to 93 per cent of the charged budget against 8 per cent for the relaxations it guards. It is not overhead. It is the quench, and the relaxation that follows is the polish on the 2 per cent of trials that survive. There is no factor of two there.

Why this is not a gradient tolerance

A tolerance asks whether the point has stopped moving. This asks whether the answer has stopped mattering, which is a different and much weaker question, and weaker questions are cheaper. A proposal 40 units above the incumbent can be abandoned after two steps while its gradient is still enormous, and a proposal within 0.01 has to be finished no matter how flat it looks.

Enums

enum Verdict

What to do with a screening quench that has run k steps.

Hopeless

The limit is decisively above the incumbent; the trial cannot improve.

Promising

The limit is decisively below the incumbent; finish the relaxation.

Undecided

The two are still within reach of each other.

Structs and Unions

struct Prediction

What a partial descent says about where it is going.

limit: f64

The extrapolated limit of the descent.

sigma: f64

One standard deviation of the extrapolation.

Infinite before the fit has enough points, which is what stops a caller from acting on two observations.

ratio: f64

The fitted decay ratio.

struct QuenchPredictor

Accumulates a descent’s energies and reports when the question is settled.

One instance per screening quench. It holds the trajectory, not the structure, so it costs nothing beyond the energies the descent produced anyway.

warmup: usize

Steps taken before any verdict is allowed.

Three decrements are the fewest that give a rate and a residual, and a rate with no residual is a point estimate a caller would act on as though it were certain.

confidence: f64

How many standard deviations of separation a verdict needs.

margin: f64

Extra separation required regardless of the fitted uncertainty.

The geometric model is an approximation, and near the incumbent an approximation that is slightly wrong is expensive: abandoning a trial that would have improved costs the whole reason the search is running. The margin buys asymmetry against that.

Implementations

impl QuenchPredictor

Functions

fn is_empty(&self) -> bool

Whether nothing has been observed.

fn last(&self) -> Option<f64>

The current energy, if any.

fn len(&self) -> usize

Steps observed.

fn new() -> Self

A predictor with the default warmup and confidence.

fn observe(&mut self, e: f64)

Records the energy after a descent step.

fn predict(&self) -> Option<Prediction>

The extrapolated limit of the descent so far.

None before there are enough decrements to fit, or when the descent is not decreasing, which happens when a line search has stalled and means the geometric model does not apply.

fn stopped_energy(&self, best: f64, fallback: f64) -> f64

The energy to hand a caller that stopped this descent early.

The extrapolated limit, floored so that it cannot sit at or below best. The floor is the invariant, not a correction: a structure whose descent was cut short is not a minimum, and an energy that beats the incumbent is recorded as the run’s answer. Arguing that the verdict already guarantees it is not enough. It was argued, and a run came back reporting a structure with a gradient of 7.1e2 where a relaxed one comes back at 1e-6, because a trial can leave the screen by a second route: the return screen takes the screened energy and structure directly, without the full relaxation that the promising verdict assumed would follow.

fallback is the value at the point where the descent stopped, used when there is no usable extrapolation.

fn verdict(&self, best: f64) -> Verdict

Whether the descent can still reach best.

Asymmetric on purpose. Calling a trial hopeless discards it, and a discarded improvement is unrecoverable, so that direction pays the margin as well as the confidence interval. Calling one promising only spends the evaluations the fixed-length screen would have spent anyway.

Traits implemented

impl Default for QuenchPredictor