mod allocate

module allocate

Cost-augmenting bias operators (well-tempered metadynamics, etc.). Proposal allocation and the budget-window temperature law. Allocating proposals among move kernels, and the budget-window temperature.

The cluster driver ran a fixed Metropolis temperature and drew its move kernel uniformly, while the theory this crate implements derives both. This module supplies the two, so the driver runs the law rather than a setting.

Functions

fn beta_draw<R: Rng + ?Sized>(a: f64, b: f64, rng: &mut R) -> f64

A Beta draw from two Gamma draws, since the crate carries no Beta sampler. A Beta draw, public for posteriors held outside this module.

Structs and Unions

struct BudgetWindowTemperature

Budget-window temperature: the descent boundary and the escape floor.

The law clamps a design point into the window where descent and escape are both feasible:

T = clamp(theta * g / d,   b / ln(B + e),   2 g / d)

The ceiling 2g/d is the sphere-model descent boundary, above which the expected one-step progress is negative. The floor b / ln(B + e) is the birth-death escape requirement: a barrier of depth b is not crossed within B remaining proposals at a temperature below it.

When the floor exceeds the ceiling the window is empty. The law then holds the floor and records the step as escape-forced, which is the regime a funnelled landscape sits in and is worth counting rather than hiding: on a multi-funnel cluster it is not an edge case but the normal condition.

On a hopping chain the state is a quenched minimum, so the gap is measured against the incumbent and the barrier is estimated from the uphill steps the chain actually failed to take.

dim: f64

Problem dimension, d in the law.

theta: f64

Design point as a fraction of the descent boundary; must be under two.

decay: f64

Decay of the barrier estimate, in (0, 1).

floor_temp: f64

Temperature never returned below this, so the chain never freezes hard.

escape_forced: usize

Steps where the escape floor exceeded the descent ceiling.

calls: usize

Times the law was evaluated.

Implementations

impl BudgetWindowTemperature

Functions

fn barrier(&self) -> f64

Current estimate of the barrier the chain is failing to cross.

fn new(dim: usize, theta: f64) -> Self

The law in dim dimensions at design point theta.

fn observe_rejection(&mut self, uphill: f64)

Records an uphill step the chain declined, which estimates the barrier.

Only rejections carry the information. An accepted uphill step was already affordable and says nothing about what the chain cannot cross.

fn temperature(&mut self, gap: f64, remaining: usize) -> f64

Temperature for a chain gap above its incumbent with remaining left.

struct DepthAllocator

Thompson sampling over arms by the depth they reach, not by whether they are accepted.

The Beta-Bernoulli allocator above is rewarded with improved || accept. Beating the run’s best is rare – at 98 points a run registers about five such events in ten thousand hops – so the reward is carried almost entirely by acceptance, and acceptance does not separate a move that produces deep structures from one that is merely plausible. Measured, that is how a twin arm survives on a system it does not suit: it is accepted readily, never switched off, and takes draws from the arm the system needs.

Depth is dense and informative at once. Every hop yields a number, and its magnitude says how close the arm brought the chain to the best it knows.

Each arm carries a Normal-Gamma posterior over that reward with unknown mean and unknown precision, so no scale has to be supplied and a system whose energies run in hundreds is handled the same as one running in tens. A draw is taken from the posterior predictive, which is Student-t, and the best draw wins.

draws: Vec<usize>

Draws per arm, for reporting.

Implementations

impl DepthAllocator

Functions

fn arms(&self) -> usize

Number of arms.

fn means(&self) -> Vec<f64>

Posterior mean reward per arm, so a run can report what it learned.

fn new(n_arms: usize) -> Self

An allocator over n_arms, uninformative until fed.

fn select<R: Rng + ?Sized>(&self, rng: &mut R) -> usize

Draws an arm by Thompson sampling on the posterior predictive.

fn update(&mut self, arm: usize, reward: f64)

Records the depth an arm reached.

The conjugate Normal-Gamma update for one observation.

struct FlooredThompson

Discounted Beta-Bernoulli allocation with a decaying uniform floor.

Each arm carries a Beta posterior over its success probability and is chosen by Thompson sampling. Evidence is discounted, so the allocator tracks a landscape whose best move changes as the search moves through it rather than converging on whatever worked at the start. A uniform floor decaying as 1/sqrt(t) keeps every arm reachable, so no mechanism is starved permanently on early evidence.

discount: f64

Discount applied to all evidence at each update, in (0, 1].

floor_scale: f64

Scale of the exploration floor.

Implementations

impl FlooredThompson

Functions

fn is_empty(&self) -> bool

True when there are no arms.

fn len(&self) -> usize

Arms available.

fn new(n_arms: usize) -> Self

Allocator over n_arms.

fn pulls(&self) -> &[usize]

Times each arm was chosen.

fn rates(&self) -> Vec<f64>

Posterior mean success rate of each arm.

fn select<R: Rng + ?Sized>(&mut self, rng: &mut R) -> usize

Chooses an arm.

fn update(&mut self, arm: usize, success: bool)

Records whether the chosen arm succeeded.

Every arm is discounted, not only the one pulled, so evidence ages with time rather than with how often an arm happens to be selected. Otherwise a starved arm keeps stale evidence indefinitely and never recovers.