mod construct¶
- module construct¶
Collective variables from the spectrum of the visited-basin graph. A posterior over what to build, rather than over which arm to pull.
The Bayesian machinery in this crate sits on allocation: which move to draw, at what temperature, with what budget. Every one of those decisions reweights a walk on the graph of basins, and the graph’s edges are set by the move rather than by the walk. Measured, the allocator does its job well and there is nothing left in it to win: on 98 points its arms carry thousands of draws each and it separates a 0.63 accept rate from a 0.00 one cleanly, so a hierarchical prior would shrink posteriors that are already sharp.
The one place a model can add an edge is the construction itself.
crate::latticebuilds a candidate from a local order and a fraction of the current structure to keep, and both are choices made blind: the source is drawn by the allocator and the fraction was not a parameter at all. A model that predicts the quenched energy of a construction from features of the candidate can choose them, and it learns from quenches the run pays for anyway.What it costs
Nothing on the ledger. Candidates are built and featured without calling the objective, so proposing four and keeping one costs four constructions and one quench, the same quench the move would have paid for a blind choice.
The model
The conjugate Normal-Inverse-Gamma regression already in
crate::screen, over features of the candidate rather than of a screened relaxation. The posterior carries its own variance, so the choice is Thompson sampling rather than a maximum: draw a coefficient vector, score the candidates under it, take the best. A construction the model has no evidence about scores with a wide posterior and gets tried.Features are structural and cheap: the fraction kept, the mean and spread of coordination in the candidate, the share of points at full coordination, and how far the candidate moved from the structure it was built from. None of them mentions a potential, so the model transfers to whatever is being optimised in the same way the growth does.
Variables
- const FEATURES: usize¶
Number of features the model regresses on.
Functions
- fn features(recipe: &Recipe, candidate: ArrayView1<f64>, parent: ArrayView1<f64>) -> Array1<f64>¶
Structural summary of a candidate, with no reference to the objective.
Structs and Unions
- struct Constructor¶
Chooses a construction by Thompson sampling over predicted quenched energy.
- width: usize¶
Candidates built and scored per proposal.
- proposals: usize¶
Constructions proposed.
- observations: usize¶
Quenches fed back.
Implementations
- impl Constructor¶
Functions
- fn coefficients(&self) -> Option<Array1<f64>>¶
The fitted coefficients, when there are enough observations to have them. Reported so a run can say what the model learned rather than only that it ran.
- fn new(width: usize) -> Self¶
A constructor scoring
widthcandidates per proposal.
- fn observe(&mut self, features: ArrayView1<f64>, energy: f64, from: f64)¶
Records how much a construction improved on the structure it came from.
The target is the change, not the quenched energy. Regressing on the energy makes the do-nothing construction optimal: keeping the whole structure and regrowing nothing quenches back to the incumbent, which is the lowest energy any proposal from that state can reach, so a posterior over energy learns to switch the move off. Measured, it did exactly that: accept rates fell from 0.44 to 0.07 and every source came back reporting the incumbent’s own value to six figures.
Against the change, a proposal that returns where it started scores zero and only one that goes lower scores negative, which is the preference the move exists to express.
- fn propose<R: Rng + ?Sized>(&mut self, parent: ArrayView1<f64>, n: usize, rng: &mut R) -> (Array1<f64>, Array1<f64>)¶
Builds
widthcandidates and returns the one the posterior likes, with its features so the caller can report the quench back.The sources offered are the library’s, and
keepis drawn across its whole range rather than around whatever has worked, because the posterior is what expresses the preference and it needs the range covered to have an opinion about it.
- fn seen(&self) -> usize¶
Quenched energies the model has seen.
Traits implemented
- impl Default for Constructor¶