### Install emcee with pip Source: https://github.com/dfm/emcee/blob/main/docs/user/install.rst Install the stable version of emcee using pip. First upgrades pip, then installs build dependencies, and finally installs emcee. ```bash python -m pip install -U pip pip install -U setuptools setuptools_scm pep517 pip install -U emcee ``` -------------------------------- ### Install emcee from source with setup.py Source: https://github.com/dfm/emcee/blob/main/document/ms.tex Alternative installation method: download the source code from http://dan.iel.fm/emcee, unzip it, and run this command in the unzipped directory. Requires numpy to be installed. ```latex % python setup.py install ``` -------------------------------- ### Install emcee from source Source: https://github.com/dfm/emcee/blob/main/docs/user/install.rst Install the latest development version of emcee from source. Clones the GitHub repository and installs it in editable mode. Requires pip and build dependencies. ```bash python -m pip install -U pip python -m pip install -U setuptools setuptools_scm pep517 git clone https://github.com/dfm/emcee.git cd emcee python -m pip install -e . ``` -------------------------------- ### Install emcee with conda Source: https://github.com/dfm/emcee/blob/main/docs/user/install.rst Install emcee using conda from the conda-forge channel. Updates conda first, then installs emcee. ```bash conda update conda conda install -c conda-forge emcee ``` -------------------------------- ### Install emcee with pip Source: https://github.com/dfm/emcee/blob/main/document/ms.tex Installs the emcee package using pip. Run this command in a UNIX-based system's command line. May require superuser permissions to install for all users. ```latex % pip install emcee ``` -------------------------------- ### Test emcee installation Source: https://github.com/dfm/emcee/blob/main/docs/user/install.rst Run unit and integration tests for emcee. Requires the source code and pytest. Installs pytest and h5py, then runs the test suite from the source root. ```bash python -m pip install -U pytest h5py python -m pytest -v src/emcee/tests ``` -------------------------------- ### MPI output: timing and speedup Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/parallel.ipynb Output of the MPI example showing the measured time and speedup compared to serial execution. ```text MPI took 8.9 seconds 2.4 times faster than serial ``` -------------------------------- ### Initialize walker positions Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/quickstart.ipynb Initialize the starting positions for 32 walkers in a 5-dimensional space, using random values between 0 and 1 for each component. ```python nwalkers = 32 p0 = np.random.rand(nwalkers, ndim) ``` -------------------------------- ### Printed output for named blobs example Source: https://github.com/dfm/emcee/blob/main/docs/user/blobs.rst Output printed by the named blobs example, showing the shapes of the structured blob arrays for both non-flat and flat retrieval. ```python (100, 32) (100, 32) (3200,) (3200,) ``` -------------------------------- ### CPU count output Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/parallel.ipynb Output of the CPU count example showing the number of CPUs on the test machine. ```text 4 CPUs ``` -------------------------------- ### Multiprocessing output: timing and speedup Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/parallel.ipynb Output of the multiprocessing example showing the measured time and speedup compared to serial execution. ```text Multiprocessing took 6.5 seconds 3.3 times faster than serial ``` -------------------------------- ### get_blobs(**kwargs) Source: https://github.com/dfm/emcee/blob/main/docs/user/sampler.rst Get the chain of blobs for each sample in the chain. ```APIDOC ## get_blobs(**kwargs) ### Description Get the chain of blobs for each sample in the chain. ### Method `get_blobs(**kwargs)` ### Parameters - **flat** (Optional[bool]) - Flatten the chain across the ensemble. (default: `False`) - **thin** (Optional[int]) - Take only every `thin` steps from the chain. (default: `1`) - **discard** (Optional[int]) - Discard the first `discard` steps in the chain as burn-in. (default: `0`) ### Returns - The chain of blobs. - Type: array[…, nwalkers] ``` -------------------------------- ### Run production MCMC chain Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/quickstart.ipynb Run the production MCMC chain for 10000 steps starting from the saved state after burn-in. ```python sampler.run_mcmc(state, 10000); ``` -------------------------------- ### Parallelize emcee sampling with multiprocessing Pool Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/parallel.ipynb Use the standard multiprocessing module to parallelize emcee sampling across CPU cores. The example creates a Pool and passes it to EnsembleSampler, then runs MCMC and prints the timing and speedup relative to serial execution. ```python from multiprocessing import Pool with Pool() as pool: sampler = emcee.EnsembleSampler(nwalkers, ndim, log_prob, pool=pool) start = time.time() sampler.run_mcmc(initial, nsteps, progress=True) end = time.time() multi_time = end - start print("Multiprocessing took {0:.1f} seconds".format(multi_time)) print("{0:.1f} times faster than serial".format(serial_time / multi_time)) ``` -------------------------------- ### Set up emcee sampler with HDFBackend Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/monitor.ipynb Defines a log probability function with blobs, initializes walkers, creates an HDFBackend, resets it, and initializes the EnsembleSampler with the backend. ```python import emcee import numpy as np np.random.seed(42) # The definition of the log probability function # We'll also use the "blobs" feature to track the "log prior" for each step def log_prob(theta): log_prior = -0.5 * np.sum((theta - 1.0) ** 2 / 100.0) log_prob = -0.5 * np.sum(theta**2) + log_prior return log_prob, log_prior # Initialize the walkers coords = np.random.randn(32, 5) nwalkers, ndim = coords.shape # Set up the backend # Don't forget to clear it in case the file already exists filename = "tutorial.h5" backend = emcee.backends.HDFBackend(filename) backend.reset(nwalkers, ndim) # Initialize the sampler sampler = emcee.EnsembleSampler(nwalkers, ndim, log_prob, backend=backend) ``` -------------------------------- ### sample(initial_state, log_prob0=None, rstate0=None, blobs0=None, iterations=1, tune=False, skip_initial_state_check=False, thin_by=1, thin=None, store=True, progress=False, progress_kwargs=None) Source: https://github.com/dfm/emcee/blob/main/docs/user/sampler.rst Advances the chain as a generator, yielding the State of the ensemble every thin_by steps. ```APIDOC ## sample(initial_state, log_prob0=None, rstate0=None, blobs0=None, iterations=1, tune=False, skip_initial_state_check=False, thin_by=1, thin=None, store=True, progress=False, progress_kwargs=None) ### Description Advance the chain as a generator. ### Method sample ### Parameters - **initial_state** (State or ndarray[nwalkers, ndim]) - Required - The initial State or positions of the walkers in the parameter space. - **iterations** (Optional[int or NoneType]) - Optional - The number of steps to generate. `None` generates an infinite stream (requires `store=False`). - **tune** (Optional[bool]) - Optional - If `True`, the parameters of some moves will be automatically tuned. - **thin_by** (Optional[int]) - Optional - If you only want to store and yield every `thin_by` samples in the chain, set `thin_by` to an integer greater than 1. When this is set, `iterations * thin_by` proposals will be made. - **store** (Optional[bool]) - Optional - By default, the sampler stores (in memory) the positions and log-probabilities of the samples in the chain. If you are using another method to store the samples to a file or if you don't need to analyze the samples after the fact (for burn-in for example) set `store` to `False`. - **progress** (Optional[bool or str]) - Optional - If `True`, a progress bar will be shown as the sampler progresses. If a string, will select a specific `tqdm` progress bar - most notable is `'notebook'`, which shows a progress bar suitable for Jupyter notebooks. If `False`, no progress bar will be shown. - **progress_kwargs** (Optional[dict]) - Optional - A `dict` of keyword arguments to be passed to the tqdm call. - **skip_initial_state_check** (Optional[bool]) - Optional - If `True`, a check that the initial_state can fully explore the space will be skipped. (default: `False`) ### Yields Every `thin_by` steps, this generator yields the `State` of the ensemble. ``` -------------------------------- ### Get number of CPUs with multiprocessing.cpu_count Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/parallel.ipynb Use multiprocessing.cpu_count() to get the number of available CPU cores and print it. ```python from multiprocessing import cpu_count ncpu = cpu_count() print("{0} CPUs".format(ncpu)) ``` -------------------------------- ### Sample with weighted mixture of DEMove and DESnookerMove Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/moves.ipynb Runs emcee with a weighted mixture of DEMove (80%) and DESnookerMove (20%) to improve autocorrelation time, then prints the autocorrelation time and plots the trace. ```python np.random.seed(93284) sampler = emcee.EnsembleSampler( nwalkers, ndim, logprob, moves=[ (emcee.moves.DEMove(), 0.8), (emcee.moves.DESnookerMove(), 0.2), ], ) sampler.run_mcmc(init, 5000) print( "Autocorrelation time: {0:.2f} steps".format( sampler.get_autocorr_time()[0] ) ) plt.plot(sampler.get_chain()[:, 0, 0], "k", lw=0.5) plt.xlim(0, 5000) plt.ylim(-5.5, 5.5) plt.title("move: [(DEMove, 0.8), (DESnookerMove, 0.2)]", fontsize=14) plt.xlabel("step number") plt.ylabel("x"); ``` -------------------------------- ### Multiprocessing output: progress bar Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/parallel.ipynb Output of the multiprocessing example showing the progress bar during sampling. ```text 100%|██████████| 100/100 [00:06<00:00, 15.65it/s] ``` -------------------------------- ### Run MCMC sampler on multimodal density Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/autocorr.ipynb Sets up an emcee EnsembleSampler with 32 walkers and 3 dimensions, using a log-probability that is a sum of two Gaussian peaks. Runs 500,000 steps with progress bar enabled. ```python import emcee def log_prob(p): return np.logaddexp(-0.5 * np.sum(p**2), -0.5 * np.sum((p - 4.0) ** 2)) sampler = emcee.EnsembleSampler(32, 3, log_prob) sampler.run_mcmc( np.concatenate( (np.random.randn(16, 3), 4.0 + np.random.randn(16, 3)), axis=0 ), 500000, progress=True, ); ``` ```text Output: 100%|██████████| 500000/500000 [10:51<00:00, 767.17it/s] ``` -------------------------------- ### emcee.backends.HDFBackend Source: https://github.com/dfm/emcee/blob/main/docs/user/backends.rst Documentation for the emcee.backends.HDFBackend class, including usage as a reader. ```APIDOC ## HDFBackend (class) ### Description A backend that serializes the chain to a file. It can be used as a reader for existing samplings. ### Usage Example ```python reader = emcee.backends.HDFBackend("chain_filename.h5", read_only=True) flatchain = reader.get_chain(flat=True) ``` ### Parameters - **filename** (str) - Required - The path to the HDF5 file. - **read_only** (bool) - Optional - If `True`, prevents overwriting the samples in the file. ``` -------------------------------- ### Sample with default StretchMove and print autocorrelation time Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/moves.ipynb Runs emcee's EnsembleSampler with the default StretchMove for 5000 steps and prints the autocorrelation time, which is about 40 steps for this problem. ```python import emcee np.random.seed(589403) init = np.random.randn(32, 1) nwalkers, ndim = init.shape sampler0 = emcee.EnsembleSampler(nwalkers, ndim, logprob) sampler0.run_mcmc(init, 5000) print( "Autocorrelation time: {0:.2f} steps".format( sampler0.get_autocorr_time()[0] ) ) ``` -------------------------------- ### Basic emcee sampling from a 5D Gaussian Source: https://github.com/dfm/emcee/blob/main/docs/index.rst Basic usage of emcee to draw samples from a 5-dimensional Gaussian. Defines a log-probability function, initializes an EnsembleSampler with 100 walkers, and runs 10000 steps. ```python import numpy as np import emcee def log_prob(x, ivar): return -0.5 * np.sum(ivar * x ** 2) ndim, nwalkers = 5, 100 ivar = 1. / np.random.rand(ndim) p0 = np.random.randn(nwalkers, ndim) sampler = emcee.EnsembleSampler(nwalkers, ndim, log_prob, args=[ivar]) sampler.run_mcmc(p0, 10000) ``` -------------------------------- ### Configure matplotlib and multiprocessing for parallel sampling Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/parallel.ipynb Sets up inline plotting and forces the 'fork' start method for multiprocessing, which is required for parallel sampling on some systems. ```python %config InlineBackend.figure_format = "retina" from matplotlib import rcParams rcParams["savefig.dpi"] = 100 rcParams["figure.dpi"] = 100 rcParams["font.size"] = 20 import multiprocessing multiprocessing.set_start_method("fork") ``` -------------------------------- ### emcee.backends.Backend Source: https://github.com/dfm/emcee/blob/main/docs/user/backends.rst Documentation for the emcee.backends.Backend class methods and properties. ```APIDOC ## Backend.get_autocorr_time(discard=0, thin=1, **kwargs) ### Description Compute an estimate of the autocorrelation time for each parameter. ### Method `get_autocorr_time` ### Parameters - **discard** (Optional[int]) - Optional - Discard the first `discard` steps in the chain as burn-in. (default: `0`) - **thin** (Optional[int]) - Optional - Use only every `thin` steps from the chain. The returned estimate is multiplied by `thin` so the estimated time is in units of steps, not thinned steps. (default: `1`) - **kwargs** - Optional - Other arguments are passed directly to `emcee.autocorr.integrated_time()`. ### Returns - **array[ndim]** - The integrated autocorrelation time estimate for the chain for each parameter. ``` ```APIDOC ## Backend.get_blobs(**kwargs) ### Description Get the chain of blobs for each sample in the chain. ### Method `get_blobs` ### Parameters - **flat** (Optional[bool]) - Optional - Flatten the chain across the ensemble. (default: `False`) - **thin** (Optional[int]) - Optional - Take only every `thin` steps from the chain. (default: `1`) - **discard** (Optional[int]) - Optional - Discard the first `discard` steps in the chain as burn-in. (default: `0`) ### Returns - **array[..., nwalkers]** - The chain of blobs. ``` ```APIDOC ## Backend.get_chain(**kwargs) ### Description Get the stored chain of MCMC samples. ### Method `get_chain` ### Parameters - **flat** (Optional[bool]) - Optional - Flatten the chain across the ensemble. (default: `False`) - **thin** (Optional[int]) - Optional - Take only every `thin` steps from the chain. (default: `1`) - **discard** (Optional[int]) - Optional - Discard the first `discard` steps in the chain as burn-in. (default: `0`) ### Returns - **array[..., nwalkers, ndim]** - The MCMC samples. ``` ```APIDOC ## Backend.get_last_sample() ### Description Access the most recent sample in the chain. ### Method `get_last_sample` ### Parameters None. ``` ```APIDOC ## Backend.get_log_prob(**kwargs) ### Description Get the chain of log probabilities evaluated at the MCMC samples. ### Method `get_log_prob` ### Parameters - **flat** (Optional[bool]) - Optional - Flatten the chain across the ensemble. (default: `False`) - **thin** (Optional[int]) - Optional - Take only every `thin` steps from the chain. (default: `1`) - **discard** (Optional[int]) - Optional - Discard the first `discard` steps in the chain as burn-in. (default: `0`) ### Returns - **array[..., nwalkers]** - The chain of log probabilities. ``` ```APIDOC ## Backend.grow(ngrow, blobs) ### Description Expand the storage space by some number of samples. ### Method `grow` ### Parameters - **ngrow** (int) - Required - The number of steps to grow the chain. - **blobs** - Required - The current array of blobs. This is used to compute the dtype for the blobs array. ``` ```APIDOC ## Backend.has_blobs() ### Description Returns `True` if the model includes blobs. ### Method `has_blobs` ### Parameters None. ``` ```APIDOC ## Backend.reset(nwalkers, ndim) ### Description Clear the state of the chain and empty the backend. ### Method `reset` ### Parameters - **nwakers** (int) - Required - The size of the ensemble. - **ndim** (int) - Required - The number of dimensions. ``` ```APIDOC ## Backend.save_step(state, accepted) ### Description Save a step to the backend. ### Method `save_step` ### Parameters - **state** (State) - Required - The `State` of the ensemble. - **accepted** (ndarray) - Required - An array of boolean flags indicating whether or not the proposal for each walker was accepted. ``` ```APIDOC ## Backend.shape (property) ### Description The dimensions of the ensemble `(nwalkers, ndim)`. ### Method `shape` (property) ``` -------------------------------- ### run_mcmc(initial_state, nsteps, **kwargs) Source: https://github.com/dfm/emcee/blob/main/docs/user/sampler.rst Iterates sample() for nsteps iterations and returns the result. Other parameters are passed directly to sample(). ```APIDOC ## run_mcmc(initial_state, nsteps, **kwargs) ### Description Iterate `sample()` for `nsteps` iterations and return the result. ### Method run_mcmc ### Parameters - **initial_state** - Required - The initial state or position vector. Can also be `None` to resume from where `run_mcmc` left off the last time it executed. - **nsteps** - Required - The number of steps to run. Other parameters are directly passed to `sample()`. ### Returns This method returns the most recent result from `sample()`. ``` -------------------------------- ### Compute integrated autocorrelation time Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/line.ipynb Estimates the integrated autocorrelation time for each parameter using the sampler's get_autocorr_time method. The output shows that about 40 steps are needed for the chain to forget its starting point. ```python tau = sampler.get_autocorr_time() print(tau) ``` ```text Output: [39.16329084 39.96660169 35.8864348 ] ``` -------------------------------- ### Plot MCMC chain traces Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/line.ipynb Plots the chain values for each parameter as a function of step number to visually inspect convergence and mixing. The walkers start near the maximum likelihood and quickly explore the posterior. ```python fig, axes = plt.subplots(3, figsize=(10, 7), sharex=True) samples = sampler.get_chain() labels = ["m", "b", "log(f)"] for i in range(ndim): ax = axes[i] ax.plot(samples[:, :, i], "k", alpha=0.3) ax.set_xlim(0, len(samples)) ax.set_ylabel(labels[i]) ax.yaxis.set_label_coords(-0.1, 0.5) axes[-1].set_xlabel("step number"); ``` ```text Result:
``` -------------------------------- ### Set up Gaussian hyperparameters Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/quickstart.ipynb Set up the hyperparameters for the Gaussian: the mean vector `means` and the covariance matrix `cov` in 5 dimensions. The covariance is constructed to be symmetric and positive definite. ```python ndim = 5 np.random.seed(42) means = np.random.rand(ndim) cov = 0.5 - np.random.rand(ndim**2).reshape((ndim, ndim)) cov = np.triu(cov) cov += cov.T - np.diag(cov.diagonal()) cov = np.dot(cov, cov) ``` -------------------------------- ### HDFBackend.grow Source: https://github.com/dfm/emcee/blob/main/docs/user/backends.rst Expands the storage space by a given number of samples. ```APIDOC ## HDFBackend.grow(ngrow, blobs) ### Description Expand the storage space by some number of samples. ### Method HDFBackend.grow ### Parameters - **ngrow** (int) - Required - The number of steps to grow the chain. - **blobs** - Required - The current array of blobs. This is used to compute the dtype for the blobs array. ``` -------------------------------- ### Fit celerite GP to estimate autocorrelation time Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/autocorr.ipynb Defines autocorr_ml, which fits a celerite GP (equivalent to a second-order ARMA model) to estimate the autocorrelation time tau for short chains. Requires celerite and autograd installed. Uses scipy.optimize.minimize with jac=True and bounds from the GP. The function returns the maximum likelihood tau estimate. ```python from scipy.optimize import minimize def autocorr_ml(y, thin=1, c=5.0): # Compute the initial estimate of tau using the standard method init = autocorr_new(y, c=c) z = y[:, ::thin] N = z.shape[1] # Build the GP model tau = max(1.0, init / thin) kernel = terms.RealTerm( np.log(0.9 * np.var(z)), -np.log(tau), bounds=[(-5.0, 5.0), (-np.log(N), 0.0)], ) kernel += terms.RealTerm( np.log(0.1 * np.var(z)), -np.log(0.5 * tau), bounds=[(-5.0, 5.0), (-np.log(N), 0.0)], ) gp = celerite.GP(kernel, mean=np.mean(z)) gp.compute(np.arange(z.shape[1])) # Define the objective def nll(p): # Update the GP model gp.set_parameter_vector(p) # Loop over the chains and compute likelihoods v, g = zip(*(gp.grad_log_likelihood(z0, quiet=True) for z0 in z)) # Combine the datasets return -np.sum(v), -np.sum(g, axis=0) # Optimize the model p0 = gp.get_parameter_vector() bounds = gp.get_parameter_bounds() soln = minimize(nll, p0, jac=True, bounds=bounds) gp.set_parameter_vector(soln.x) # Compute the maximum likelihood tau a, c = kernel.coefficients[:2] tau = thin * 2 * np.sum(a / c) / np.sum(a) return tau # Calculate the estimate for a set of different chain lengths ml = np.empty(len(N)) ml[:] = np.nan for j, n in enumerate(N[1:8]): i = j + 1 thin = max(1, int(0.05 * new[i])) ml[i] = autocorr_ml(chain[:, :n], thin=thin) ``` -------------------------------- ### Resume an MCMC run from the last sample Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/monitor.ipynb Resumes a previous MCMC run by creating a new backend without resetting it, then runs additional steps. The output shows the iteration count before and after the additional run. ```python new_backend = emcee.backends.HDFBackend(filename) print("Initial size: {0}".format(new_backend.iteration)) new_sampler = emcee.EnsembleSampler( nwalkers, ndim, log_prob, backend=new_backend ) new_sampler.run_mcmc(None, 100) print("Final size: {0}".format(new_backend.iteration)) ``` ```text Output: Initial size: 5900 Final size: 6000 ``` -------------------------------- ### Generate toy chains with celerite and plot a segment Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/autocorr.ipynb Sets up a celerite model with two real terms, computes the true autocorrelation time analytically, simulates 32 chains of length 2,000,000, and plots a segment of the first three chains. Requires celerite and matplotlib. ```python import numpy as np import matplotlib.pyplot as plt np.random.seed(1234) # Build the celerite model: import celerite from celerite import terms kernel = terms.RealTerm(log_a=0.0, log_c=-6.0) kernel += terms.RealTerm(log_a=0.0, log_c=-2.0) # The true autocorrelation time can be calculated analytically: true_tau = sum(2 * np.exp(t.log_a - t.log_c) for t in kernel.terms) true_tau /= sum(np.exp(t.log_a) for t in kernel.terms) true_tau # Simulate a set of chains: gp = celerite.GP(kernel) t = np.arange(2000000) gp.compute(t) y = gp.sample(size=32) # Let's plot a little segment with a few samples: plt.plot(y[:3, :300].T) plt.xlim(0, 300) plt.xlabel("step number") plt.ylabel("$f$") plt.title("$\\tau_\mathrm{{true}} = {0:.0f}$".format(true_tau), fontsize=14); ``` ```text Result:
``` -------------------------------- ### emcee.moves.KDEMove Source: https://github.com/dfm/emcee/blob/main/docs/user/moves.rst The KDEMove class implements a proposal using a kernel density estimate of the complementary ensemble. ```APIDOC ## emcee.moves.KDEMove ### Description A proposal using a KDE of the complementary ensemble. This is a simplified version of the method used in kombine. If you use this proposal, you should use *a lot* of walkers in your ensemble. ### Class `emcee.moves.KDEMove(bw_method=None, **kwargs)` ### Parameters - **bw_method** - The bandwidth estimation method. See the scipy docs for allowed values. ``` -------------------------------- ### Run MCMC with emcee.EnsembleSampler Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/line.ipynb Initializes 32 walkers in a small Gaussian ball around the maximum likelihood solution and runs 5000 steps of MCMC. The sampler uses the log_probability function and the data (x, y, yerr). ```python import emcee pos = soln.x + 1e-4 * np.random.randn(32, 3) nwalkers, ndim = pos.shape sampler = emcee.EnsembleSampler( nwalkers, ndim, log_probability, args=(x, y, yerr) ) sampler.run_mcmc(pos, 5000, progress=True); ``` ```text Output: 100%|██████████| 5000/5000 [00:07<00:00, 712.03it/s] ``` -------------------------------- ### Run MCMC sampling with convergence monitoring Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/monitor.ipynb Runs the sampler for up to 100,000 steps, checking autocorrelation time every 100 steps and stopping when the chain is longer than 100 times the estimated autocorrelation time and the estimate changes by less than 1%. ```python max_n = 100000 # We'll track how the average autocorrelation time estimate changes index = 0 autocorr = np.empty(max_n) # This will be useful to testing convergence old_tau = np.inf # Now we'll sample for up to max_n steps for sample in sampler.sample(coords, iterations=max_n, progress=True): # Only check convergence every 100 steps if sampler.iteration % 100: continue # Compute the autocorrelation time so far # Using tol=0 means that we'll always get an estimate even # if it isn't trustworthy tau = sampler.get_autocorr_time(tol=0) autocorr[index] = np.mean(tau) index += 1 # Check convergence converged = np.all(tau * 100 < sampler.iteration) converged &= np.all(np.abs(old_tau - tau) / tau < 0.01) if converged: break old_tau = tau ``` -------------------------------- ### Call log_prob with args Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/quickstart.ipynb Demonstrates how the sampler calls the log_prob function with the args parameter. The output shows the log-probability value for the first walker's initial position. ```python log_prob(p0[0], means, cov) ``` ```text Result: -2.596094589085444 ``` -------------------------------- ### MPI parallelization with schwimmbad MPIPool Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/parallel.ipynb Write a script that uses MPI via schwimmbad's MPIPool to parallelize emcee sampling. The script is written to a file and then executed with mpiexec. It includes a log_prob function with a simulated delay and uses the pool to distribute the sampling. ```python with open("script.py", "w") as f: f.write(""" import sys import time import emcee import numpy as np from schwimmbad import MPIPool def log_prob(theta): t = time.time() + np.random.uniform(0.005, 0.008) while True: if time.time() >= t: break return -0.5*np.sum(theta**2) with MPIPool() as pool: if not pool.is_master(): pool.wait() sys.exit(0) np.random.seed(42) initial = np.random.randn(32, 5) nwalkers, ndim = initial.shape nsteps = 100 sampler = emcee.EnsembleSampler(nwalkers, ndim, log_prob, pool=pool) start = time.time() sampler.run_mcmc(initial, nsteps) end = time.time() print(end - start) """) mpi_time = !mpiexec -n {ncpu} python script.py mpi_time = float(mpi_time[0]) print("MPI took {0:.1f} seconds".format(mpi_time)) print("{0:.1f} times faster than serial".format(serial_time / mpi_time)) ``` -------------------------------- ### Read a saved chain with emcee.backends.HDFBackend Source: https://github.com/dfm/emcee/blob/main/docs/user/backends.rst Open an existing HDF5 chain file in read-only mode and retrieve the flattened chain of samples. The read_only argument prevents accidental overwrites of the saved samples. ```python reader = emcee.backends.HDFBackend("chain_filename.h5", read_only=True) flatchain = reader.get_chain(flat=True) ``` -------------------------------- ### Track log prior as a blob with emcee Source: https://github.com/dfm/emcee/blob/main/docs/user/blobs.rst Define a log_prob function that returns the log prior as a blob, run the sampler, and retrieve the blobs with get_blobs(). The blobs are stored as a (nsteps, nwalkers) NumPy array. ```python import emcee import numpy as np def log_prior(params): return -0.5 * np.sum(params**2) def log_like(params): return -0.5 * np.sum((params / 0.1)**2) def log_prob(params): lp = log_prior(params) if not np.isfinite(lp): # log prior is not finite, return -np.inf for log probability # and None for log prior as it won't be used anyway (but we # must use the correct number of return values) return -np.inf, None ll = log_like(params) if not np.isfinite(ll): # log likelihood is not finite, return -np.inf for log # probability and None for log prior (again, this value isn't # used but we have to have the correct number of return values) return -np.inf, None # return log probability (sum of log prior and log likelihood) # and log prior. Log prior will be saved as part of the blobs. return lp + ll, lp coords = np.random.randn(32, 3) nwalkers, ndim = coords.shape sampler = emcee.EnsembleSampler(nwalkers, ndim, log_prob) sampler.run_mcmc(coords, 100) log_prior_samps = sampler.get_blobs() flat_log_prior_samps = sampler.get_blobs(flat=True) print(log_prior_samps.shape) # (100, 32) print(flat_log_prior_samps.shape) # (3200,) ``` -------------------------------- ### Define log_prob_data with data argument and run serial sampler Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/parallel.ipynb Defines a probability function that takes a data argument and simulates work with a time delay. Creates a large dataset and runs an emcee EnsembleSampler serially, printing the time taken. ```python def log_prob_data(theta, data): a = data[0] # Use the data somehow... t = time.time() + np.random.uniform(0.005, 0.008) while True: if time.time() >= t: break return -0.5 * np.sum(theta**2) data = np.random.randn(5000, 200) sampler = emcee.EnsembleSampler(nwalkers, ndim, log_prob_data, args=(data,)) start = time.time() sampler.run_mcmc(initial, nsteps, progress=True) end = time.time() serial_data_time = end - start print("Serial took {0:.1f} seconds".format(serial_data_time)) ``` -------------------------------- ### Run serial MCMC sampling Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/parallel.ipynb Runs the EnsembleSampler serially with 32 walkers and 100 steps, measuring the time taken. ```python import emcee np.random.seed(42) initial = np.random.randn(32, 5) nwalkers, ndim = initial.shape nsteps = 100 sampler = emcee.EnsembleSampler(nwalkers, ndim, log_prob) start = time.time() sampler.run_mcmc(initial, nsteps, progress=True) end = time.time() serial_time = end - start print("Serial took {0:.1f} seconds".format(serial_time)) ``` -------------------------------- ### EnsembleSampler Source: https://github.com/dfm/emcee/blob/main/docs/user/sampler.rst Instantiate an ensemble MCMC sampler. This is the main class for running MCMC sampling with emcee. ```APIDOC ## EnsembleSampler ### Description Instantiate an ensemble MCMC sampler. This is the main class for running MCMC sampling with emcee. ### Constructor `emcee.EnsembleSampler(nwalkers, ndim, log_prob_fn, pool=None, moves=None, args=None, kwargs=None, backend=None, vectorize=False, blobs_dtype=None, parameter_names=None, a=None, postargs=None, threads=None, live_dangerously=None, runtime_sortingfn=None)` ### Parameters - **nwalkers** (int) - Required - The number of walkers in the ensemble. - **ndim** (int) - Required - Number of dimensions in the parameter space. - **log_prob_fn** (callable) - Required - A function that takes a vector in the parameter space as input and returns the natural logarithm of the posterior probability (up to an additive constant) for that position. - **pool** (Optional) - An object with a `map` method that follows the same calling sequence as the built-in `map` function. This is generally used to compute the log-probabilities for the ensemble in parallel. - **moves** (Optional) - This can be a single move object, a list of moves, or a “weighted” list of the form `[(emcee.moves.StretchMove(), 0.1), ...]`. When running, the sampler will randomly select a move from this list (optionally with weights) for each proposal. (default: `StretchMove`) - **args** (Optional) - A list of extra positional arguments for `log_prob_fn`. `log_prob_fn` will be called with the sequence `log_prob_fn(p, *args, **kwargs)`. - **kwargs** (Optional) - A dict of extra keyword arguments for `log_prob_fn`. `log_prob_fn` will be called with the sequence `log_prob_fn(p, *args, **kwargs)`. - **backend** (Optional) - Either a `backends.Backend` or a subclass (like `backends.HDFBackend`) that is used to store and serialize the state of the chain. By default, the chain is stored as a set of numpy arrays in memory, but new backends can be written to support other mediums. - **vectorize** (Optional[bool]) - If `True`, `log_prob_fn` is expected to accept a list of position vectors instead of just one. Note that `pool` will be ignored if this is `True`. (default: `False`) - **parameter_names** (Optional[Union[List[str], Dict[str, List[int]]]]) - Names of individual parameters or groups of parameters. If specified, the `log_prob_fn` will receive a dictionary of parameters, rather than a `np.ndarray`. ### Notes - Deprecated arguments: `a`, `postargs`, `threads`, `live_dangerously`, `runtime_sortingfn` are deprecated. The parameters that control the proposals have been moved to the Moves interface (`a` and `live_dangerously`), and the parameters related to parallelization can now be controlled via the `pool` argument. ``` -------------------------------- ### Run multiprocessing with data argument Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/parallel.ipynb Runs the same sampler using a multiprocessing Pool, passing the data via args, and prints the time and speed comparison to serial. ```python with Pool() as pool: sampler = emcee.EnsembleSampler( nwalkers, ndim, log_prob_data, pool=pool, args=(data,) ) start = time.time() sampler.run_mcmc(initial, nsteps, progress=True) end = time.time() multi_data_time = end - start print("Multiprocessing took {0:.1f} seconds".format(multi_data_time)) print( "{0:.1f} times faster(?) than serial".format( serial_data_time / multi_data_time ) ) ``` -------------------------------- ### acceptance_fraction Source: https://github.com/dfm/emcee/blob/main/docs/user/sampler.rst Property that returns the fraction of proposed steps that were accepted. ```APIDOC ## acceptance_fraction ### Description Property that returns the fraction of proposed steps that were accepted. ### Property `acceptance_fraction` ### Returns - The fraction of proposed steps that were accepted. ``` -------------------------------- ### Print mean acceptance fraction Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/quickstart.ipynb Print the mean acceptance fraction of the ensemble, a diagnostic for sampling quality. The output shows a typical value. ```python print( "Mean acceptance fraction: {0:.3f}".format( np.mean(sampler.acceptance_fraction) ) ) ``` ```text Output: Mean acceptance fraction: 0.552 ``` -------------------------------- ### emcee.moves.WalkMove Source: https://github.com/dfm/emcee/blob/main/docs/user/moves.rst The WalkMove class implements the walk move proposal for ensemble sampling. ```APIDOC ## emcee.moves.WalkMove ### Description A Goodman & Weare (2010) "walk move" with parallelization as described in Foreman-Mackey et al. (2013). ### Class `emcee.moves.WalkMove(s=None, **kwargs)` ### Parameters - **s** (optional) - The number of helper walkers to use. By default it will use all the walkers in the complement. ``` -------------------------------- ### Plot trace for default StretchMove Source: https://github.com/dfm/emcee/blob/main/docs/tutorials/moves.ipynb Plots the chain of the first walker from the default StretchMove run to visualize the slow mixing. ```python plt.plot(sampler0.get_chain()[:, 0, 0], "k", lw=0.5) plt.xlim(0, 5000) plt.ylim(-5.5, 5.5) plt.title("move: StretchMove", fontsize=14) plt.xlabel("step number") plt.ylabel("x"); ```