Skip to content

Double-Well (φ⁴) Models#

The continuous multimodal case — the one tempering exists for. DoubleWellEBM is the lattice φ⁴ field: at cold β with ferromagnetic couplings the target is bimodal, a single chain mode-collapses into one well, and NRPT round trips are what carry the ± flips into the samples.

The single-site conditional has no closed form, so SliceGibbsConditional performs one slice-sampling transition per site (Neal 2003, the exactly-reversible bounded variant), vectorized over each color class. Slice draws are keyed by iteration so that chain masking stays bit-identical despite data-dependent loop lengths.

Like GaussianEBM, an unbounded state space has no proper β = 0 member, so proper_at_beta_zero = False; pair the target with AnnealedEBM to temper from exactly β = 0.

hamon.models.DoubleWellEBM #

The lattice φ⁴ model:

\[\mathcal{E}(x) = \beta \left( \sum_i \left[ a_i x_i^4 - 2 a_i x_i^2 - h_i x_i \right] + \sum_{(i,j)} c_{ij} x_i x_j \right)\]

— the double well a(x²−1)² with its constant dropped (constants cancel in every energy difference), a per-site tilt h, and pairwise bilinear couplings. With ferromagnetic couplings (c < 0) and cold β the target is bimodal (the ±1 ordered wells): the continuous case NRPT exists for.

Attributes:

  • nodes / edges: :class:~hamon.pgm.GaussianNode\ s and coupled pairs.
  • barrier: per-node well coefficient a > 0 (barrier height at x = 0).
  • lin: per-node tilt h.
  • couplings: per-edge coefficient c.
  • beta: scalar inverse temperature.

See the module docstring for why proper_at_beta_zero is False.

__init__(nodes, edges, barrier: Array, lin: Array, couplings, beta) #

hamon.models.DoubleWellSamplingProgram #

Thin wrapper specializing :class:ModelSamplingProgram to the φ⁴ model.

__init__(ebm: DoubleWellEBM, free_blocks: list, clamped_blocks: list[hamon.block_management.Block], *, width: float = 2.0, max_stepout: int = 8, _gibbs_spec: hamon.block_sampling.BlockGibbsSpec | None = None) #

hamon.models.double_well_init(key: Key[Array, ''], model: DoubleWellEBM, blocks: list[hamon.block_management.Block], batch_shape: tuple[int, ...] = ()) -> list[Array] #

Draw an initial state from the decoupled wells.

Each site picks a well at random (±1) and adds Gaussian jitter at the well's local curvature scale U''(±1) = 8a: x = s + N(0, 1/(β·8a)). Not the target distribution — a sensibly-scaled start, like gaussian_init / hinton_init. Requires β > 0.

hamon.models.SliceGibbsConditional #

Slice-sampling update for sites with quartic-polynomial conditionals.

Accumulates the 1-D conditional energy A x⁴ + B x² + C x per site from :class:PolynomialSelfInteraction (A, B, −C·x contributions and the x₀ anchor), :class:QuadraticSelfInteraction (½·diag into B, −lin into C) and :class:QuadraticPairInteraction (coupling·x_tail into C), then runs one slice-sampling transition per site (Neal 2003): a slice level under log p(x₀), bounded stepping-out (budget max_stepout split uniformly between the two directions — the m-limited variant, exact by construction), then shrinkage until acceptance. The transition leaves the conditional invariant; sites in a color class update independently.

Attributes:

  • width: the stepping-out interval width, in state units. The double well's modes sit at x ≈ ±1, so the default 2.0 spans them.
  • max_stepout: total stepping-out budget m (Neal's limited variant).

Stateless (sampler_state is None throughout), so it works under NRPT's round loop, which resets sampler state each round.

n_keys class-attribute #

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.int(). For floating-point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer iteral.

int('0b100', base=0) 4

__abstractclassvars__ class-attribute #

Build an immutable unordered collection of unique elements.

__abstractmethods__ class-attribute #

Build an immutable unordered collection of unique elements.

__abstractvars__ class-attribute #

Build an immutable unordered collection of unique elements.

__annotations__ class-attribute #

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)

__dataclass_fields__ class-attribute #

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)

__dataclass_params__ class-attribute #
__doc__ class-attribute #

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

__firstlineno__ class-attribute #

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.int(). For floating-point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer iteral.

int('0b100', base=0) 4

__match_args__ class-attribute #

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

__module__ class-attribute #

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

__static_attributes__ class-attribute #

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

max_stepout class-attribute #

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.int(). For floating-point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer iteral.

int('0b100', base=0) 4

width class-attribute #

Convert a string or number to a floating-point number, if possible.

init() -> None #

Initialize the sampler state before sampling begins.

This is called before the first iteration of block sampling, after which the return of this method is superseded by the return from sample.

Returns:

Type Description
None

the initial sampler state to use for the first iteration of block sampling.

__init__(width: float = 2.0, max_stepout: int = 8) -> None #

Initialize self. See help(type(self)) for accurate signature.

sample(key: Key, interactions: list[PyTree], active_flags: list[Array], states: list[list[PyTree[Shaped[Array, 'nodes ?*state'], _State]]], sampler_state: None, output_sd: PyTree[jax.ShapeDtypeStruct]) -> tuple[PyTree[Shaped[Array, 'nodes ?*state'], _State], None] #

Factors and interactions#

hamon.models.PolynomialSelfInteraction #

Per-node quartic polynomial energy quart·x⁴ + quad·x² − lin·x.

All coefficients are energy coefficients with β already folded in (the factor convention shared with the Gaussian stack). Its interaction group is self-anchored (see the module docstring), delivering each site's own pre-sweep value alongside its coefficients.

__abstractclassvars__ class-attribute #

Build an immutable unordered collection of unique elements.

__abstractmethods__ class-attribute #

Build an immutable unordered collection of unique elements.

__abstractvars__ class-attribute #

Build an immutable unordered collection of unique elements.

__annotations__ class-attribute #

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)

__dataclass_fields__ class-attribute #

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs dict(iterable) -> new dictionary initialized as if via: d = {} for k, v in iterable: d[k] = v dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)

__dataclass_params__ class-attribute #
__doc__ class-attribute #

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

__firstlineno__ class-attribute #

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.int(). For floating-point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer iteral.

int('0b100', base=0) 4

__match_args__ class-attribute #

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

__module__ class-attribute #

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

__static_attributes__ class-attribute #

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

__init__(quart: Array, quad: Array, lin: Array) -> None #

Initialize self. See help(type(self)) for accurate signature.

hamon.models.PolynomialSelfEBMFactor #

Batch of single-node quartic terms quart·x⁴ + quad·x² − lin·x.

__init__(node_group: Block, quart: Array, quad: Array, lin: Array) #