CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-emcee

The Python ensemble sampling toolkit for affine-invariant MCMC

Pending
Overview
Eval results
Files

moves.mddocs/

Proposal Moves

emcee provides a comprehensive collection of proposal move algorithms for generating new walker positions during MCMC sampling. These moves can be used individually or combined in weighted ensembles to optimize sampling performance for different types of problems.

Capabilities

Base Move Classes

Abstract base classes that define the move interface and common functionality.

class Move:
    """Abstract base class for all moves."""
    
    def tune(self, state, accepted):
        """
        Tune move parameters based on acceptance history.
        
        Args:
            state: Current ensemble state
            accepted: Boolean array indicating accepted proposals
        """
    
    def update(self, old_state, new_state, accepted, subset=None):
        """
        Update walker states with accepted proposals.
        
        Args:
            old_state: Current ensemble state
            new_state: Proposed ensemble state
            accepted: Boolean array indicating accepted proposals
            subset: Subset of walkers to update
            
        Returns:
            State: Updated ensemble state
        """

class RedBlueMove(Move):
    """Base class for red-blue ensemble moves."""
    
    def get_proposal(self, s, c, random):
        """
        Generate proposals for red-blue moves.
        
        Args:
            s: Active walker positions
            c: Complementary walker positions
            random: Random number generator
            
        Returns:
            tuple: (proposed_positions, log_proposal_factors)
        """

class MHMove(Move):
    """Base class for Metropolis-Hastings style moves."""
    
    def propose(self, model, state):
        """
        Generate proposal state.
        
        Args:
            model: Model object containing log probability function
            state: Current ensemble state
            
        Returns:
            State: Proposed ensemble state
        """

Stretch Move

The default Goodman & Weare stretch move, highly effective for most problems.

class StretchMove(RedBlueMove):
    def __init__(self, a: float = 2.0):
        """
        Initialize stretch move.
        
        Args:
            a: Stretch scale parameter (default: 2.0)
        """

Walk Move

Simple random walk move for local exploration.

class WalkMove(RedBlueMove):
    def __init__(self, s: float = None):
        """
        Initialize walk move.
        
        Args:
            s: Step size parameter
        """

Differential Evolution Moves

Moves based on differential evolution algorithms for efficient exploration.

class DEMove(RedBlueMove):
    def __init__(self, sigma: float = 1e-5, gamma0: float = None):
        """
        Initialize differential evolution move.
        
        Args:
            sigma: Scaling parameter for random perturbation
            gamma0: Base scaling factor (default: 2.38 / sqrt(2 * ndim))
        """

class DESnookerMove(RedBlueMove):
    def __init__(self, sigma: float = 1e-5, gammas: list = None):
        """
        Initialize differential evolution snooker move.
        
        Args:
            sigma: Scaling parameter
            gammas: List of scaling factors for different move types
        """

Kernel Density Estimation Move

Advanced move using kernel density estimation for proposal generation.

class KDEMove(RedBlueMove):
    def __init__(self, bw_method=None):
        """
        Initialize KDE move.
        
        Args:
            bw_method: Bandwidth selection method for KDE
        """

Gaussian Move

Metropolis-Hastings move with Gaussian proposals.

class GaussianMove(MHMove):
    def __init__(self, cov, mode: str = "vector", factor=None):
        """
        Initialize Gaussian move.
        
        Args:
            cov: Covariance matrix or proposal scale
            mode: Proposal mode ("vector", "random", "sequential")
            factor: Scaling factor for covariance
        """

Generic Metropolis-Hastings Move

Generic MH move for custom proposal functions.

class MHMove(Move):
    def __init__(self, proposal_function):
        """
        Initialize generic MH move.
        
        Args:
            proposal_function: Function generating proposals
        """

Usage Examples

Using Single Moves

import emcee
from emcee import moves
import numpy as np

def log_prob(theta):
    return -0.5 * np.sum(theta**2)

# Use stretch move (default)
sampler = emcee.EnsembleSampler(32, 2, log_prob)

# Use specific move
stretch_move = moves.StretchMove(a=2.5)
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=stretch_move)

# Use DE move
de_move = moves.DEMove(sigma=1e-4)
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=de_move)

Combining Multiple Moves

# List of moves (equal weight)
move_list = [
    moves.StretchMove(),
    moves.DEMove(),
    moves.WalkMove()
]
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=move_list)

# Weighted moves
weighted_moves = [
    (moves.StretchMove(), 0.6),
    (moves.DEMove(), 0.3),
    (moves.WalkMove(), 0.1)
]
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=weighted_moves)

Gaussian Move with Covariance

# Define covariance matrix
cov = np.array([[1.0, 0.5], [0.5, 2.0]])
gaussian_move = moves.GaussianMove(cov)

sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=gaussian_move)

KDE Move for Complex Distributions

# KDE move adapts to the shape of the distribution
kde_move = moves.KDEMove()
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=kde_move)

# Can specify bandwidth method
kde_move = moves.KDEMove(bw_method='scott')
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=kde_move)

Custom Move Tuning

# Move that adapts during sampling
class AdaptiveMove(moves.Move):
    def __init__(self, initial_scale=1.0):
        self.scale = initial_scale
        self.n_accepted = 0
        self.n_total = 0
    
    def tune(self, state, accepted):
        self.n_accepted += np.sum(accepted)
        self.n_total += len(accepted)
        
        # Adjust scale based on acceptance rate
        acceptance_rate = self.n_accepted / self.n_total
        if acceptance_rate > 0.5:
            self.scale *= 1.1
        elif acceptance_rate < 0.2:
            self.scale *= 0.9

# Use with tuning enabled
custom_move = AdaptiveMove()
sampler = emcee.EnsembleSampler(32, 2, log_prob, moves=custom_move)
sampler.run_mcmc(pos, 1000, tune=True)

Move Selection Strategy

# Different strategies for different problem types

# For well-behaved, unimodal distributions
standard_moves = moves.StretchMove(a=2.0)

# For multimodal distributions
multimodal_moves = [
    (moves.StretchMove(), 0.4),
    (moves.DEMove(), 0.4),
    (moves.KDEMove(), 0.2)
]

# For highly correlated parameters
correlated_moves = [
    (moves.StretchMove(), 0.5),
    (moves.DEMove(), 0.3),
    (moves.GaussianMove(cov_matrix), 0.2)
]

# For local exploration
local_moves = moves.WalkMove(s=0.1)

Install with Tessl CLI

npx tessl i tessl/pypi-emcee

docs

autocorr.md

backends.md

ensemble-sampling.md

index.md

moves.md

state.md

tile.json