mod movekernel

module movekernel

The move-kernel trait: temperature-indexed proposal sampling. The move-kernel trait of the IISE manuscript: Move : S x R_>0 -> Delta(S).

Functions

fn reflect_coord(x: f64, lo: f64, hi: f64) -> f64

Folds a single coordinate into [lo, hi] by mirror reflection across the two walls (a triangle wave of period 2 (hi - lo)). Reflection is a volume-preserving involution per wall, so wrapping a symmetric base kernel in it keeps the proposal symmetric: q(x -> y) = q(y -> x). The Metropolis test therefore still targets the box-restricted Gibbs measure with no Hastings correction (manuscript law L1 holds for the reflected proposal).

fn reflect_into_box(x: ArrayView1<f64>, bounds: &Bounds<f64>) -> Array1<f64>

Mirror-reflects every coordinate of x into bounds (see reflect_coord). Use this in place of boundary clipping for a symmetric random-walk proposal: clipping piles mass on the boundary and breaks the q(x -> y) = q(y -> x) symmetry that the Metropolis test relies on, while reflection keeps it.

fn supports_box<T: Float>(_b: &BoxConstrained<T>) -> bool

True iff the kernel is safe to use directly with the supplied box-constrained neighborhood. Always false for the unbounded kernels shipped here.

fn supports_continuous(_dim: usize) -> bool

Marker witness: Gaussian, Cauchy, and TsallisVisit all have full-R^n support, so they are safe with ContinuousR_n but escape BoxConstrained without clipping (use Reflected to fold them into a box). These free functions let the proptest sweep witness L2 structurally without redefining the trait.

fn supports_r_n(_n: &ContinuousR_n) -> bool

True iff ContinuousR_n is the matching neighborhood. Used by the proptest sweep as the structural witness for L2 on unconstrained kernels.

Traits

trait MoveKernel<T: Float>

A temperature-indexed proposal kernel.

IISE manuscript law L2 requires supp(Move(i, T)) subseteq Neigh(i). Implementors override supports_in to advertise this constraint for the sampled-validation constructor. The conservative default is false.

Functions

fn propose<R: Rng + ?Sized>(&self, i: ArrayView1<T>, t: T, rng: &mut R) -> Array1<T>

Draws a proposal point from the kernel at temperature t.

fn supports_in<N: Neighborhood<T>>(&self, _n: &N) -> bool

Witnesses L2: returns true iff supp(propose) subseteq n over the implementor’s declared domain. Sampled validation also exercises the proposal behavior. Default false.

Structs and Unions

struct Cauchy

Cauchy proposal: j = i + gamma * c, c_k ~ Cauchy(0, 1) component-wise. Symmetric, heavy-tailed kernel (Szu-Hartley Fast SA). This is the q_v = 2 case of the generalized visiting sampler TsallisVisit: at q_v = 2 the Schuur transform x / |y|^{(q_v-1)/(3-q_v)} reduces to x / |y|, a standard Cauchy drawn independently per coordinate.

gamma: f64

Per-component scale parameter.

Implementations

impl Cauchy

Functions

fn new(gamma: f64) -> Self

Constructs a Cauchy kernel. Asserts gamma > 0.

Traits implemented

impl MoveKernel<f64> for Cauchy
struct Gaussian

Isotropic Gaussian proposal: j = i + sigma * z, z ~ N(0, I).

Component-wise standard normal scaled by sigma. Symmetric kernel.

sigma: f64

Per-component standard deviation.

Implementations

impl Gaussian

Functions

fn new(sigma: f64) -> Self

Constructs a Gaussian kernel. Asserts sigma > 0.

Traits implemented

impl MoveKernel<f64> for Gaussian
struct Reflected<M>

Box-reflecting adapter: wraps an inner move kernel and mirror-reflects each proposed coordinate back into the supplied box. Unlike clipping (which piles probability mass on the boundary and breaks proposal symmetry), reflection keeps the proposal symmetric, so Reflected<M> is safe to pair with [BoxConstrained](crate::neigh::BoxConstrained) and satisfies L1/L2 without a Hastings term whenever the inner kernel M is symmetric (Gaussian, Cauchy, TsallisVisit).

inner: M

Inner symmetric move kernel.

bounds: Bounds<f64>

Box the proposals are reflected into.

Implementations

impl<M> Reflected<M>

Functions

fn new(inner: M, bounds: Bounds<f64>) -> Self

Wraps inner so every proposal is mirror-reflected into bounds.

Traits implemented

impl<M: MoveKernel<f64>> MoveKernel<f64> for Reflected<M>
impl<M: MoveKernel<f64>> sealed::MoveFor<BoxConstrained<f64>> for Reflected<M>
impl<M: MoveKernel<f64>> CertifiedMoveFor<f64, BoxConstrained<f64>> for Reflected<M>
struct ShellRotate

Rotates the outer half of the set against its core.

Packings that share a core differ in how the surface sits on it, so twisting the shell probes that difference in one move.

n_points: usize

Points in the state.

Traits implemented

impl MoveKernel<f64> for ShellRotate
struct SurfaceRelocate

Moves the least-coordinated point onto the surface of the set.

A point in a poor site is what blocks a better packing, and relocating it changes the structure rather than perturbing it. Coordination is counted within neighbour_cutoff, which keeps the kernel independent of the objective: no energy evaluation is spent choosing the point to move.

n_points: usize

Points in the state; the state length must be 3 * n_points.

neighbour_cutoff: f64

Separation below which two points count as neighbours.

Traits implemented

impl MoveKernel<f64> for SurfaceRelocate
struct Symmetrise

Enforces an approximate order-fold rotation about a random axis.

The global minima of the hard cluster sizes are highly symmetric, and a nearly symmetric structure is unreachable by independent displacement because every point has to move together. Pairing each point with the nearest image of the rotated set and pulling the two together moves them in concert, which is what a symmetrisation move is for.

n_points: usize

Points in the state.

orders: Vec<usize>

Rotation orders to draw from, for example [2, 3, 4, 5, 6].

pair_cutoff: f64

Largest separation at which a point and an image are considered partners.

Traits implemented

impl MoveKernel<f64> for Symmetrise
struct TsallisVisit

Generalized (Tsallis) simulated-annealing visiting kernel (doi:10.1016/S0378-4371(96)00271-3), tail index q_v in (1, 3).

Sampled by the Schuur/Xiang transform used by the de-facto-standard GenSA and SciPy dual_annealing implementations: per coordinate, with x_k, y_k ~ N(0, 1) drawn independently, .. code-block:: text

dx_k = sigma(T, q_v) * x_k / |y_k|^{(q_v-1)/(3-q_v)},

where the scale sigma = (factor4_p * T^{1/(q_v-1)} / Gamma(1/(q_v-1) - 1/2))^{(q_v-1)/(3-q_v)} and factor4_p = sqrt(pi) (q_v-1)^{4-q_v} / (2^{(2-q_v)/(q_v-1)} (3-q_v)). Proposals are tail-clipped at +/- TAIL_LIMIT (1e8) to bound the heavy tail, matching SciPy. The 1-D marginal is a q-Gaussian whose T-scaling is T^{1/(3-q_v)}.

Special cases:
  • q_v == 2: per-coordinate Cauchy (x/|y|), the Fast-SA limit.

  • q_v -> 1+: light-tailed (Gaussian) limit.

  • q_v -> 3-: very heavy tail.

q_v: f64

Tsallis visiting index. Practical range: (1, 3).

Implementations

impl TsallisVisit

Functions

fn new(q_v: f64) -> Self

Constructs a Tsallis visit kernel. Asserts 1 < q_v < 3.

Traits implemented

impl MoveKernel<f64> for TsallisVisit