Skip to main content

Custom Monte Carlo moves for icet/mchammer.

Project description

mchammer-moves

Custom Monte Carlo trial moves for icet/mchammer. The Move base class defines a sampler-agnostic proposal contract; ensemble adapters consume moves and handle acceptance, bookkeeping, and data-container integration for canonical and Wang-Landau sampling, without modification of the mchammer source or downstream wrappers such as mchammer-pt.

The package provides:

  • a Move abstract base class for user-defined trial moves;
  • five built-in moves:
    • PairSwap — the standard canonical two-site swap;
    • MultiPairSwapk site-disjoint pair swaps applied as one atomic proposal; useful when single-pair swaps are kinetically blocked between adjacent minima in deep basins;
    • CyclicShift — single-step shift of the species pattern along a user-supplied index cycle, with periodic boundaries within the cycle; useful for row or ring translations on chain-like or ring-like sublattices;
    • CyclicReflection — long-range reflection of the species pattern along an index cycle around a randomly-chosen pivot; complements CyclicShift's nearest-neighbour shifts by enabling species to hop across a chain in a single accepted move;
    • IndexSetSwap — swaps occupations between two equal-length index sets drawn uniformly from a user-supplied list of groups; a generic primitive for chain-, motif-, or layer-swap moves;
    • SitePermutation — applies a caller-supplied permutation of site occupations, drawn uniformly from a list of operations, with an unconditional forward/inverse direction draw; covers reflections (e.g. across a <100> plane), point inversion, and proper or improper rotations of any order;
  • CustomCanonicalEnsemble, a drop-in replacement for mchammer.ensembles.CanonicalEnsemble that draws moves from a user-supplied weighted list and tracks per-move acceptance;
  • CustomWangLandauEnsemble, a drop-in replacement for mchammer.ensembles.WangLandauEnsemble with the same weighted-move dispatch, plus per-move window-vs-WL rejection classification;
  • MoveDispatcher, the shared weighted-selection and per-move bookkeeping engine used by both ensemble adapters.

Installation

pip install mchammer-moves

For development, clone the repository and install editable with the test and lint tooling:

pip install -e ".[dev]"

Quick start

structure, ce, and cycles below are placeholders for your atoms object, cluster expansion, and chain definitions respectively; the package contains no system-specific geometry, so you supply them yourself.

from mchammer.calculators import ClusterExpansionCalculator
from mchammer_moves import CustomCanonicalEnsemble, CyclicShift, PairSwap

calc = ClusterExpansionCalculator(structure, ce)

ensemble = CustomCanonicalEnsemble(
    structure=structure,
    calculator=calc,
    temperature=600.0,
    moves=[
        (PairSwap(sublattice_index=0), 1.0),
        (CyclicShift(cycles=cycles), 0.05),
    ],
)
ensemble.run(10_000)

print(ensemble.acceptance_rates())

Use with mchammer-pt

mchammer-pt (v0.2+) accepts a custom ensemble class via its native ensemble_cls= parameter, with constructor arguments forwarded via ensemble_kwargs=:

from mchammer_pt import CanonicalParallelTempering
from mchammer_moves import CustomCanonicalEnsemble, CyclicShift, PairSwap

with CanonicalParallelTempering.process_pool(
    cluster_expansion=ce,
    atoms=initial_structure,
    temperatures=temperatures,
    block_size=block_size,
    random_seed=42,
    ensemble_cls=CustomCanonicalEnsemble,
    ensemble_kwargs={
        "moves": [
            (PairSwap(sublattice_index=anion_sl), 1.0),
            (CyclicShift(cycles=cycles), 0.05),
        ],
    },
) as pt:
    history = pt.run(n_cycles=N_CYCLES)

Per-move acceptance and null-proposal rates are recorded into each replica's mchammer.BaseDataContainer at every ensemble_data_write_interval as <move>_acceptance_rate and <move>_null_rate columns, so they survive the ProcessPool boundary and are recoverable from the HDF5 bundle written by mchammer-pt without observer forwarding. The two are tracked separately: a move that returns None (e.g. a PairSwap on a single-species sublattice, a MultiPairSwap on a sublattice with fewer than k of one species, an IndexSetSwap whose drawn pair already holds identical occupations) increments the null counter rather than the rejection counter, so null_rate distinguishes a structurally-infeasible move (null_rate ≈ 1) from a low-temperature trapped chain (acceptance_rate ≈ 0, null_rate ≈ 0).

For multiprocess runs, CustomCanonicalEnsemble and every Move subclass must be importable by fully qualified name in spawn workers (i.e. defined in .py module files, not in __main__ or notebook cells). mchammer-pt's ProcessPool rejects interactive-__main__ and function-local classes up-front.

Use with Wang-Landau

CustomWangLandauEnsemble accepts the same moves list as CustomCanonicalEnsemble and forwards all other parameters to WangLandauEnsemble:

from mchammer.calculators import ClusterExpansionCalculator
from mchammer_moves import CustomWangLandauEnsemble, PairSwap

calc = ClusterExpansionCalculator(structure, ce)

mc = CustomWangLandauEnsemble(
    structure=structure,
    calculator=calc,
    energy_spacing=0.1,
    moves=[
        (PairSwap(sublattice_index=0), 1.0),
    ],
    energy_limit_left=-100.0,
    energy_limit_right=-90.0,
)
mc.run(1_000_000)

print(mc.acceptance_rates())
print(mc.rejection_breakdown())

Per-move acceptance, null, window-rejection, and WL-rejection rates are recorded into the WangLandauDataContainer at every ensemble_data_write_interval as <move>_acceptance_rate, <move>_null_rate, <move>_window_rejection_rate, and <move>_wl_rejection_rate columns. The rejection_breakdown() method provides cumulative window-vs-WL rejection counts for interactive use.

<move>_acceptance_rate and <move>_null_rate use total proposals (accepted + rejected + null) as the denominator. <move>_window_rejection_rate and <move>_wl_rejection_rate use classified in-window rejections as the denominator — they do not share a denominator with the first two columns and do not sum with them to any fixed value.

Rejection classification is only performed once the walker has reached the energy window. Pre-window search-phase rejections are counted in the aggregate MoveStats.rejected counter but not broken down further.

Constructing cycles for CyclicShift

CyclicShift expects a list of cycles, where each cycle is a list of site indices in the order along which species are to be shifted. Cycles may have any length and may differ in length from one another; the move treats each cycle as periodic in itself (the last site wraps to the first). The supplied indices are opaque labels — there is no requirement that they correspond to physically collinear sites.

The package contains no system-specific geometry. Cycle construction is the caller's responsibility. The recipe for a typical anion-ordered ReO3-type supercell, where each cycle corresponds to a one-dimensional chain of anion sites, is:

  1. Identify a single-axis chain of anion sites — for example, all sites of the form (i, 0, 0), (i, 0, 1), …, (i, 0, N-1) along the z axis at (x=i, y=0) — and list their flat site indices in geometric order.
  2. Repeat for each starting (x, y) to obtain the full set of z-cycles.
  3. Repeat the procedure for x-cycles and y-cycles if your problem has chain ordering along multiple axes.
  4. Pass the combined list to CyclicShift(cycles=...).

For NbO2F at 6×6×6, the relevant cycles are anion chains along each cubic axis (108 cycles per axis, 324 cycles total). See the integration script in the data_NbO2F project for a concrete construction.

Detailed balance

All built-in moves have proposal probabilities that depend only on lattice geometry and composition, not on the current configuration:

  • PairSwap: at fixed canonical composition, the number of distinct-species pairs on a sublattice is composition-invariant, so the probability of selecting any specific pair is symmetric in the forward and reverse directions.
  • MultiPairSwap: each pair is drawn by picking site 1 uniformly from the non-used sublattice sites and site 2 uniformly from the non-used sites of differing species. Summed over the k! orderings of the same site-disjoint pair-set, the forward and reverse proposal probabilities are equal: composition is invariant under any valid swap, and the dependence on already-used sites cancels by symmetry between the two directions.
  • CyclicShift: a cycle and direction are chosen uniformly at random. The reverse of a +1 shift along cycle c is a -1 shift along the same cycle, with the same selection probability.
  • CyclicReflection: a cycle and integer pivot are chosen uniformly at random. Cyclic reflection is an involution, so the reverse of a reflection along (c, p) is the same reflection along (c, p), with the same selection probability.
  • IndexSetSwap: an unordered pair of index sets is drawn uniformly from C(N, 2) distinct pairs. Selection probability depends only on the fixed list of index sets, not on the configuration, so P(A → B) = P(B → A) directly. The optional require_matching_composition filter (off by default) does not break this: swapping any pair only exchanges the two groups' contents, so the multiset of compositions held across the groups is invariant under the move, and a pair filtered out in one direction is also filtered out in the other.
  • SitePermutation: an operation is drawn uniformly from the fixed list, then applied forward or inverted, each with probability one half. The applied-permutation multiset is closed under inversion with equal weights, so P(A → B) = P(B → A) for any permutation.

Standard Metropolis acceptance therefore satisfies detailed balance for any weighted combination of these moves. A symmetry test that empirically verifies this property is provided in the test suite for each move and should be the first thing you run when adding a new move.

For Wang-Landau sampling, CustomWangLandauEnsemble replaces the Metropolis criterion with the WL entropy-based acceptance condition inherited from WangLandauEnsemble. The symmetric-proposal property of each move still holds, so the WL algorithm's convergence guarantees are preserved for any weighted combination of the built-in moves.

Running tests

pip install -e ".[dev]"
pytest -q

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mchammer_moves-0.6.1.tar.gz (53.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mchammer_moves-0.6.1-py3-none-any.whl (34.7 kB view details)

Uploaded Python 3

File details

Details for the file mchammer_moves-0.6.1.tar.gz.

File metadata

  • Download URL: mchammer_moves-0.6.1.tar.gz
  • Upload date:
  • Size: 53.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mchammer_moves-0.6.1.tar.gz
Algorithm Hash digest
SHA256 812d2f188802475882eaf9e93c169c224647bcc062872c6b61437ad523721fb2
MD5 73298b4dadd98bf2c05feb426bf63801
BLAKE2b-256 4716822047541d248d99f66258f9080201a51b2b48ccbef1c26bb260d84e281c

See more details on using hashes here.

Provenance

The following attestation bundles were made for mchammer_moves-0.6.1.tar.gz:

Publisher: publish.yml on bjmorgan/mchammer-moves

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mchammer_moves-0.6.1-py3-none-any.whl.

File metadata

  • Download URL: mchammer_moves-0.6.1-py3-none-any.whl
  • Upload date:
  • Size: 34.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mchammer_moves-0.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6d0540e9366aa9373a6086726427ce351d9c5de3a68431297ae0cc05c29392c6
MD5 2689640b3ae316448b00c711f08976ff
BLAKE2b-256 c57e40a15cac50e770b0041dde7f0c987bbd57b95f2a12297ffe801fe3586d05

See more details on using hashes here.

Provenance

The following attestation bundles were made for mchammer_moves-0.6.1-py3-none-any.whl:

Publisher: publish.yml on bjmorgan/mchammer-moves

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page