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::lattice builds 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 width candidates 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 width candidates 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 keep is 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
struct Recipe

The parameters of one candidate construction.

source: Source

Which local order to grow.

keep: f64

Fraction of the current structure kept as the growth seed.