mod csa_cluster

module csa_cluster

A bank of chains under an annealed diversity threshold.

Ties crate::methods::bank to the cluster driver: the bank decides where to search from and what to keep, crate::methods::cluster_hopping::run does the searching, and crate::diversity narrows the threshold as the budget runs down.

The division of labour is the point. A single biased chain at 75 points reaches the global minimum in 4 runs of 8 at three million charged evaluations, and the four that fail all fail the same way: they settle in the icosahedral funnel and the decahedron is never seen. Nothing in a single chain notices that, because from inside the funnel the search looks healthy. A bank does notice, because it holds solutions from more than one funnel at once and spends its next start on the one it knows least about.

The budget is split, not multiplied. A bank of eight running eight chains of an eighth the length costs what one chain costs, which is the comparison that matters; a bank that quietly spends eight times the budget has proved nothing.

Functions

fn run<'g, D>(cfg: &Config, bank_cfg: &BankConfig, ledger: &mut Ledger, relax: Relax<'_>, mut grad: Option<&mut GradFn<'g>>, mut distance: D, seed: u64) -> BankOutcome
where
    D: FnMut(ArrayView1<f64>, ArrayView1<f64>) -> f64

Runs a bank of chains until the ledger is spent.

distance decides when two solutions are the same, and is the caller’s: with a shape distance Dcut is a length and transfers between sizes, which a threshold in descriptor space does not.

fn spectrum_distance(n_points: usize) -> impl FnMut(ArrayView1<f64>, ArrayView1<f64>) -> f64

Euclidean distance between sorted pairwise-distance spectra.

The default when no shape matching is available. It is a distance in descriptor space, so its threshold does not transfer between sizes; with the ira feature the caller should pass a shape distance instead.

Structs and Unions

struct BankConfig

How the bank is run.

capacity: usize

Solutions held at once.

slice: usize

Charged evaluations given to each chain before it reports back.

Short enough that a bad region is abandoned quickly and long enough that a chain settles into a minimum: a slice that ends mid-descent offers the bank a structure that says nothing about where it was going.

seeding: usize

Chains run from random starts before the bank is first used, to give Dcut a scale taken from the data.

dcut_floor: f64

Floor of the Dcut schedule, as a fraction of its start.

mix_fraction: f64

Share of rounds spent mixing two members instead of searching from one.

Without mixing the bank does not hold funnels apart, it holds variants apart. Measured at 75 points with a bank of thirty and a thousand slices, every member ended between -396.28 and -396.19: thirty icosahedral structures, each shape-distinct under the threshold and all in the same funnel, because each member’s chain descends on its own and nothing ever puts two of them together. The published method mixes by cutting one solution and splicing in part of another; that is crate::methods::splice, and it is the mix used when this fraction fires. The trial is not a minimum: the caller quenches it and offers the relaxed structure to the bank.

mix_images: usize

Independent splice trials drawn from one pair in a mixing round.

Each trial is a different plane and a separate quench, so one mix can offer several children without starting a chain slice for each.

acquisition: bool

Choose the next member to search from by expected improvement over morphology, rather than by which has been used least.

Least-used is a round robin, and a round robin over a bank that has collapsed into one funnel searches that funnel evenly. Measured at 75 points, every member ended between -396.28 and -396.19: thirty icosahedral variants, each distinct under the threshold, and the selection spread its starts across all of them. Expected improvement scores a morphology the search has no evidence about above one it has sampled repeatedly and found mediocre, which is the distinction a round robin cannot make. See crate::funnel_bo.

Traits implemented

impl Default for BankConfig
struct BankOutcome

What a bank run did.

best: f64

Lowest value found anywhere.

best_state: Option<Array1<f64>>

The structure attaining it.

slices: usize

Chains run.

hops: usize

Hops summed over the chains, so the report says what the run did rather than reporting a default.

basins: usize

Basins summed over the chains. Not distinct basins across the run: each chain keeps its own bias and its own numbering.

charged: usize

Charged evaluations spent.

improved: usize

Candidates that improved the member they resembled.

novel: usize

Candidates that resembled nothing in the bank.

duplicates: usize

Candidates discarded as near-copies.

improvements: Vec<(usize, usize, usize, f64)>

Hop, charged evaluations, basins and value at each new campaign best.

Merged from the slices with each slice’s spend offset by what the campaign had already spent, because a slice keeps its own sub-ledger and its counts start from zero. Without the merge a caller asking this arm for a first encounter time gets a censored answer from every run, including the ones that found the answer.

morphologies: usize

Morphologies the acquisition model holds.

mixes: usize

Rounds spent mixing two members.

mix_admitted: usize

Images from those rounds that were admitted to the bank.

mix_below_both: usize

Images from those rounds that beat both of their endpoints.

dcut: (f64, f64)

Dcut at the start and at the end.

bank: Vec<f64>

Energies held in the bank at the end, ascending.