GUIBRUSHR.Retrieval.ExofastMCMC.snooker module¶
Snooker (DE-MCzs) move primitives for the GUIBRUSHR sampler.
This module is a dependency-free (numpy-only) reference implementation of the snooker update of ter Braak and Vrugt (2008), “Differential Evolution Markov Chain with snooker updater and fewer chains”, Stat. Comput. 18(4), 435-446.
It is deliberately isolated from the rest of the retrieval pipeline so it can be unit-tested in isolation and reused verbatim by the production worker (ModelData.parallel_chain). It implements only the snooker-specific maths:
snooker_propose : the line-constrained proposal x_prop = x_i + gamma_s * (zp1 - zp2)
snooker_log_jacobian : the radial Jacobian (d-1)*(log||x_prop-z|| - log||x_i-z||)
The 90% “parallel” DE-MCz move (x_i + gamma*(zR1 - zR2) + e) reuses the existing GUIBRUSHR machinery and is not duplicated here; only its archive draw differs.
Conventions (validated at Gate G1 against the project guide snooker_demc.pdf section 3 Eq. 3, ter Braak and Vrugt 2008, mc3 chain.py and the first author’s demc_zs.r reference):
The archive
Zis a 2D array of shape(M, d): M past+present states, each a parameter vector of lengthd. Draws are uniform over the M rows.gamma_sis dimension-independent and drawn fromUniform(1.2, 2.2)per step (mc3 parity). It is NOT divided by sqrt(d) (that is the parallel-move convention only).There is no additive noise term
eon the snooker move.The Jacobian is always combined in log-space as
(d-1) * dlog||.||; the raw power||.||**(d-1)is never formed (it overflows/underflows for large d).
- GUIBRUSHR.Retrieval.ExofastMCMC.snooker.draw_gamma_s(rng: Generator) float[source]¶
Draw the snooker step scale gamma_s ~ Uniform(1.2, 2.2).
- GUIBRUSHR.Retrieval.ExofastMCMC.snooker.sample_distinct_indices(rng: Generator, n: int, k: int) tuple[int, ...][source]¶
Draw
kdistinct integer indices uniformly from[0, n).- Parameters:
rng – numpy random Generator.
n – archive size (number of rows to choose from).
k – number of distinct indices required.
- Returns:
A tuple of
kdistinct ints.- Raises:
ValueError – if
n < k(not enough states to draw distinct indices).
- GUIBRUSHR.Retrieval.ExofastMCMC.snooker.project_onto_line(point: ndarray, anchor: ndarray, unit_dir: ndarray) ndarray[source]¶
Orthogonal projection of
pointonto the line throughanchor.The line has unit direction
unit_dir. Returns the nearest point on the line, i.e.anchor + <point - anchor, unit_dir> * unit_dir.
- GUIBRUSHR.Retrieval.ExofastMCMC.snooker.snooker_propose(x_i: ndarray, archive: ndarray, rng: Generator, gamma_s: float | None = None) tuple[ndarray, ndarray][source]¶
Generate a snooker proposal for the current state
x_i.Picks an anchor
zand two further statesz1, z2uniformly at random (distinct rows) from the archive, projects the differencez1 - z2onto the line throughx_iandz, and steps along that line. No additive noise term is used.- Parameters:
x_i – current state, shape
(d,).archive – archive
Zof past+present states, shape(M, d)withM >= 3.rng – numpy random Generator.
gamma_s – optional fixed step scale. If None, drawn from Uniform(1.2, 2.2).
- Returns:
(x_prop, z_anchor)wherex_propis the proposed state, shape(d,), andz_anchoris the anchorz(shape(d,)) needed by snooker_log_jacobian for the acceptance correction.- Raises:
ValueError – if the archive has fewer than 3 states.
Note
Mathematically
zp1 - zp2 == <z1 - z2, u> * u(the compact form used here), so the explicit orthogonal projections are not materialised.
- GUIBRUSHR.Retrieval.ExofastMCMC.snooker.snooker_log_jacobian(x_i: ndarray, x_prop: ndarray, z_anchor: ndarray, d: int) float[source]¶
Radial-Jacobian term of the snooker log-acceptance ratio.
Returns
(d - 1) * (log||x_prop - z|| - log||x_i - z||), computed entirely in log-space so that the raw power||.||**(d-1)is never formed.For
d == 1the term is exactly 0 (snooker reduces to plain Metropolis along the line). If the proposal lands on the anchor (or the current state coincides with it) the radius underflows and the move is rejected by returning-inf, matching the fact that the spherical shell has zero volume atz.- Parameters:
x_i – current state, shape
(d,).x_prop – proposed state, shape
(d,).z_anchor – anchor
zreturned by snooker_propose, shape(d,).d – number of free parameters.
- Returns:
The log-Jacobian contribution to
log_alpha;-infto force reject.