mod minima_hopping¶
- module minima_hopping¶
History-conditioned escape feedback, after Goedecker’s minima hopping.
Goedecker, J. Chem. Phys. 120, 9911 (2004).
The campaign’s own measurements say what is missing. From the structure a 75-point search settles into, none of 1800 single moves across the whole kernel set reaches anything lower, so crossing needs a sequence of accepted uphill quenches and a reason to accept them that does not destroy descent. A continuous collective variable cannot supply that reason: the Q4 gap between the two funnels is 0.023, under any usable deposition width.
This crate already keeps a history of visited basins and uses it to deposit bias. Minima hopping uses a history for something else: to scale the next escape. Revisiting a known minimum makes the next attempt more violent rather than the current one less attractive.
That difference is the whole mechanism and it is worth stating precisely, because the two are complementary and must stay separable:
escape feedback
basin bias
what a revisit raises
the escape scale
the potential on that basin
acceptance
adaptive threshold on the energy rise
Metropolis on
F + Vtransition regions
left crossable
filled if revisited
Goedecker argues against flooding transition regions for exactly this reason: the region between funnels has to stay crossable, so the response to a revisit should be a harder push rather than a higher potential where the chain needs to pass.
The escape scale grows geometrically while a chain revisits, which is the guarantee that no funnel is permanent: a chain that keeps returning keeps escalating until it leaves. Schoenborn, Goedecker, Roy and Oganov, J. Chem. Phys. 130, 144108 (2009), add feedback proportional to the visit count and report that this finds the LJ75 Marks decahedron where a cut-and-splice evolutionary algorithm does not.
Enums
- enum Visit¶
What a quench was, relative to the history.
- Same¶
The basin the chain was already in.
- Known¶
A basin the history has seen before, but not the current one.
- New¶
A basin not in the history.
Structs and Unions
- struct EscapeFeedback¶
Escape scale and acceptance threshold, both driven by the history.
Defaults are Goedecker’s: the escape scale grows by 1.05 on a revisit and shrinks by the same factor on a discovery, and the acceptance threshold moves the other way, so roughly half of proposals are accepted without a temperature being chosen.
- beta_same: f64¶
Growth on returning to the current basin.
- beta_known: f64¶
Growth on reaching a basin already in the history.
- beta_new: f64¶
Shrink on reaching a new basin.
- visits_coeff: f64¶
Enhanced feedback: the known-basin growth is multiplied by
1 + visits_coeff * visits, so a repeatedly seen basin is escaped harder than one seen once (Schoenborn et al.).
- alpha_accept: f64¶
Threshold multiplier on acceptance; below one.
- alpha_reject: f64¶
Threshold multiplier on rejection; above one.
- escape_ceiling: f64¶
Ceiling on the escape scale.
A streak of revisits grows the scale geometrically, and an unbounded scale eventually proposes a structure so scattered that its relaxation costs far more than an ordinary one. The ceiling keeps the charged cost of a proposal bounded without removing the escalation.
The default of four is set by that cost, not by taste. At a ceiling of sixty-four an LJ38 run paid 138 charged evaluations per hop against 39 without the controller, so the same budget bought 2173 hops rather than 7775 and the run solved 1 seed in 8 where the plain chain solved 8. Escalation that prices itself out of the budget is not escalation.
- escape_floor: f64¶
Floor on the escape scale, so a run of discoveries cannot drive it to zero and freeze the search.
- n_same: usize¶
Counts of each outcome, for reporting.
- n_known: usize¶
Quenches that landed in a known other basin.
- n_new: usize¶
Quenches that opened a new basin.
Implementations
- impl EscapeFeedback¶
Functions
- fn accept(&mut self, delta: f64) -> bool¶
Whether to accept a move of energy rise
delta, updating the threshold.The rule is Goedecker’s: accept when the rise is under the threshold, then move the threshold so the acceptance rate sits near a half. No temperature appears, which is the point: a Metropolis temperature cold enough to polish cannot cross and one hot enough to cross cannot polish, while this threshold adapts to whichever the chain is currently failing at.
- fn classify(&self, current: Option<usize>, reached: usize) -> Visit¶
Classifies a quench without recording it.
- fn discovery_rate(&self) -> f64¶
Fraction of quenches that were discoveries.
A run whose fraction is near zero is revisiting and should be escalating; one near one is wandering and should be settling. Reported because it says whether the feedback is doing anything.
- fn escape(&self) -> f64¶
Current escape scale.
- fn known_basins(&self) -> usize¶
Basins in the history.
- fn new(escape: f64, threshold: f64) -> Self¶
Controller starting at
escapeandthreshold, with Goedecker’s rates.
- fn observe(&mut self, current: Option<usize>, reached: usize) -> Visit¶
Records a quench and updates the escape scale.
Returns what the quench was. The scale rises on a revisit and falls on a discovery, which is the feedback: a chain that keeps returning escalates until it leaves, and one that keeps finding new structures settles down to explore them.
- fn threshold(&self) -> f64¶
Current acceptance threshold.
- fn visits(&self, basin: usize) -> u32¶
Times
basinhas been recorded.