Skip to content

Sampler

The Sampler class is the main interface to Tempest. It implements the Persistent Sampling algorithm for Bayesian inference.

Overview

The sampler manages the entire PS workflow:

  1. Initialization from prior samples
  2. Iterative tempering towards the posterior
  3. MCMC mutation with persistent proposals
  4. Evidence estimation

Class Reference

Sampler

Public API facade for Tempest sampler.

All configuration and algorithm logic is delegated to internal components: - SamplerConfig: validates and stores configuration - SamplerCore: executes the sampling algorithm - StateManager: manages current and historical state

Source code in tempest/sampler.py
class Sampler:
    """
    Public API facade for Tempest sampler.

    All configuration and algorithm logic is delegated to internal components:
    - SamplerConfig: validates and stores configuration
    - SamplerCore: executes the sampling algorithm
    - StateManager: manages current and historical state
    """

    def __init__(
        self,
        prior_transform: callable,
        log_likelihood: callable,
        n_dim: int,
        n_particles: Optional[int] = None,
        ess_ratio: float = 2.0,
        volume_variation: Optional[float] = None,
        log_likelihood_args: Optional[list] = None,
        log_likelihood_kwargs: Optional[dict] = None,
        vectorize: bool = False,
        blobs_dtype: Optional[str] = None,
        periodic: Optional[list] = None,
        reflective: Optional[list] = None,
        pool: Optional[Union[int, object]] = None,
        clustering: bool = True,
        normalize: bool = True,
        cluster_every: int = 1,
        split_threshold: float = 1.0,
        n_max_clusters: Optional[int] = None,
        sample: str = "tpcn",
        n_steps: Optional[int] = None,
        n_max_steps: Optional[int] = None,
        resample: str = "mult",
        output_dir: Optional[str] = None,
        output_label: Optional[str] = None,
        random_state: Optional[int] = None,
    ):
        """
        Initialize Tempest sampler.

        Parameters are validated and stored in SamplerConfig, then delegated
        to SamplerCore for execution.

        Parameters
        ----------
        prior_transform : callable
            Function transforming unit hypercube samples [0,1] to prior parameter space.
        log_likelihood : callable
            Function computing log-likelihood for given parameter values.
        n_dim : int
            Number of dimensions/parameters in the problem.
        n_particles : int, optional
            Number of particles (active samples) per iteration. When None (default),
            automatically set to 2 * n_dim.
        ess_ratio : float, optional
            Target ESS ratio (ESS / n_particles) for ESS mode (default: 2.0).
            The actual target ESS is ess_ratio * n_particles. Used when volume_variation=None.
        volume_variation : float, optional
            Target coefficient of variation for volume to enable dynamic mode (default: None).
            When None, uses ESS-only mode. When a positive float, uses dynamic mode which
            searches for beta where volume variation equals this value after finding beta_upper
            where ESS = n_particles * ess_ratio. This is the CV of sqrt(det(Cov)),
            measuring the variation of the confidence ellipsoid volume.
            Lower values enforce more uniform coverage. Must be positive when not None.
        log_likelihood_args : list, optional
            Positional arguments to pass to log_likelihood function.
        log_likelihood_kwargs : dict, optional
            Keyword arguments to pass to log_likelihood function.
        vectorize : bool, optional
            If True, likelihood function accepts batched inputs (n_samples, n_dim).
            Default is False.
        blobs_dtype : str, optional
            NumPy dtype string for auxiliary data returned by likelihood.
        periodic : list[int], optional
            List of parameter indices with periodic boundary conditions.
        reflective : list[int], optional
            List of parameter indices with reflective boundary conditions.
        pool : int or object, optional
            Parallelization pool. Can be number of processes or Pool object.
        clustering : bool, optional
            Enable hierarchical Gaussian mixture clustering. Default is True.
        normalize : bool, optional
            Normalize clusters during training. Default is True.
        cluster_every : int, optional
            Train clusterer every N iterations. Default is 1.
        split_threshold : float, optional
            Threshold for splitting clusters. Default is 1.0.
        n_max_clusters : int, optional
            Maximum number of clusters. None means no limit.
        sample : str, optional
            MCMC proposal method: 'tpcn' or 'rwm'. Default is 'tpcn'.
        n_steps : int, optional
            Base MCMC steps per dimension at optimal acceptance rate of 23.4%.
            Actual steps adapt as: n_steps_0 * n_dim * (0.234/acceptance_rate) * (sigma_0/sigma)**2.
            Default is 5.
        n_max_steps : int, optional
            Maximum MCMC steps per dimension. The actual maximum is n_max_steps * n_dim.
            Default is 20 × n_steps.
        resample : str, optional
            Resampling method: 'mult' or 'syst'. Default is 'mult'.
        output_dir : str, optional
            Output directory for state files. Default is 'states'.
        output_label : str, optional
            Label prefix for output files. Default is 'ps'.
        random_state : int, optional
            Random seed for reproducibility.
        """
        # Wrap likelihood function
        wrapped_likelihood = FunctionWrapper(
            log_likelihood, log_likelihood_args, log_likelihood_kwargs
        )

        # Create validated configuration
        config = SamplerConfig(
            prior_transform=prior_transform,
            log_likelihood=wrapped_likelihood,
            n_dim=n_dim,
            n_particles=n_particles,
            ess_ratio=ess_ratio,
            volume_variation=volume_variation,
            log_likelihood_args=log_likelihood_args,
            log_likelihood_kwargs=log_likelihood_kwargs,
            vectorize=vectorize,
            blobs_dtype=blobs_dtype,
            periodic=periodic,
            reflective=reflective,
            pool=pool,
            clustering=clustering,
            normalize=normalize,
            cluster_every=cluster_every,
            split_threshold=split_threshold,
            n_max_clusters=n_max_clusters,
            sample=sample,
            n_steps=n_steps,
            n_max_steps=n_max_steps,
            resample=resample,
            output_dir=output_dir,
            output_label=output_label,
            random_state=random_state,
        )

        # Create state manager
        state = StateManager(n_dim)

        # Create internal coordinator
        self._core = SamplerCore(config, state)

        # Expose state for backward compatibility (tests access sampler.state)
        self.state = state

    def run(
        self,
        n_total: int = 4096,
        progress: bool = True,
        resume_state_path: Union[str, Path, None] = None,
        save_every: Optional[int] = None,
    ):
        """
        Run Persistent Sampling.

        Parameters
        ----------
        n_total : int
            The total number of effectively independent samples to be
            collected (default is ``n_total=4096``).
        progress : bool
            If True, print progress bar (default is ``progress=True``).
        resume_state_path : str or Path or None
            Path of state file used to resume a run. Default is ``None`` in which case
            the sampler does not load any previously saved states.
        save_every : int or None
            Argument which determines how often (i.e. every how many iterations) ``Tempest`` saves
            state files to the ``output_dir`` directory. Default is ``None`` in which case no state
            files are stored during the run.
        """
        return self._core.run_sampling(
            n_total=n_total,
            progress=progress,
            resume_state_path=resume_state_path,
            save_every=save_every,
        )

    def sample(self, save_every: Optional[int] = None, t0: int = 0) -> dict:
        """
        Perform a single iteration of the PS algorithm.

        Parameters
        ----------
        save_every : int or None
            Argument which determines how often (i.e. every how many iterations) ``Tempest`` saves
            state files to the ``output_dir`` directory. Default is ``None`` in which case no state
            files are stored during the run.
        t0 : int
            The starting iteration index, used for determining when to save states.
            Default is ``0``.

        Returns
        -------
        state : dict
            Dictionary containing the current state of the particles.
        """
        return self._core.execute_iteration(save_every=save_every, t0=t0)

    def posterior(
        self,
        resample: bool = False,
        return_blobs: bool = False,
        trim_importance_weights: bool = True,
        return_logw: bool = False,
        ess_trim: float = 0.99,
        bins_trim: int = 1000,
    ) -> tuple:
        """
        Return posterior samples.

        Parameters
        ----------
        resample : bool
            If True, resample particles (default is ``resample=False``).
        return_blobs : bool
            If True, return auxiliary data from likelihood (default is ``return_blobs=False``).
        trim_importance_weights : bool
            If True, trim importance weights (default is ``trim_importance_weights=True``).
        return_logw : bool
            If True, return log importance weights (default is ``return_logw=False``).
        ess_trim : float
            Effective sample size threshold for trimming (default is ``ess_trim=0.99``).
        bins_trim : int
            Number of bins for trimming (default is ``bins_trim=1000``).

        Returns
        -------
        x : np.ndarray
            Physical coordinates of posterior samples.
        weights : np.ndarray
            Importance weights.
        logl : np.ndarray
            Log-likelihood values.
        blobs : np.ndarray (optional)
            Auxiliary data if return_blobs=True.
        logw : np.ndarray (optional)
            Log importance weights if return_logw=True.
        """
        return self._core.compute_posterior(
            resample=resample,
            return_blobs=return_blobs,
            trim_importance_weights=trim_importance_weights,
            return_logw=return_logw,
            ess_trim=ess_trim,
            bins_trim=bins_trim,
        )

    def evidence(self) -> tuple[float, Optional[float]]:
        """
        Return log evidence estimate and error.

        Returns
        -------
        logz : float
            Log evidence estimate.
        logz_err : float or None
            Error estimate (currently None, for future use).
        """
        return self._core.compute_evidence()

    def save_state(self, path: Union[str, Path]):
        """
        Save sampler state to file.

        Parameters
        ----------
        path : str or Path
            Path where state will be saved.
        """
        self._core.save_sampler_state(Path(path))

    def load_state(self, path: Union[str, Path]):
        """
        Load sampler state from file.

        Parameters
        ----------
        path : str or Path
            Path to state file.
        """
        self._core.load_sampler_state(Path(path))

    def __getstate__(self):
        """Get state for pickling (for backward compatibility)."""
        state = self.__dict__.copy()
        # Remove pool-related attributes that can't be pickled
        if "_core" in state and hasattr(state["_core"], "pool"):
            del state["_core"]
        return state

    def results(self):
        """Return results (backward compatibility)."""
        return self.state.compute_results()

    # Property accessors
    @property
    def n_dim(self) -> int:
        """Number of dimensions."""
        return self._core.config.n_dim

    @property
    def n_particles(self) -> int:
        """Number of particles."""
        return self._core.config.n_particles

    @property
    def ess_ratio(self) -> float:
        """Target ESS ratio."""
        return self._core.config.ess_ratio

    @property
    def volume_variation(self) -> Optional[float]:
        """Target coefficient of variation for volume. None for ESS-only mode."""
        return self._core.config.volume_variation

    @property
    def n_steps(self) -> int:
        """Base MCMC steps per dimension at optimal acceptance rate."""
        return self._core.config.n_steps

    @property
    def n_max_steps(self) -> int:
        """Maximum number of MCMC steps."""
        return self._core.config.n_max_steps

    @property
    def n_total(self) -> Optional[int]:
        """Total effective samples target."""
        return getattr(self._core, "n_total", None)

    @property
    def resample(self) -> str:
        """Resampling method (mult or syst)."""
        return self._core.config.resample

    @property
    def clustering(self) -> bool:
        """Whether clustering is enabled."""
        return self._core.config.clustering

    @property
    def vectorize(self) -> bool:
        """Whether likelihood is vectorized."""
        return self._core.config.vectorize

    @property
    def output_dir(self) -> Path:
        """Output directory for state files."""
        return self._core.config.output_dir

    @property
    def output_label(self) -> str:
        """Label for output files."""
        return self._core.config.output_label

    @property
    def random_state(self) -> Optional[int]:
        """Random seed."""
        return self._core.config.random_state

    @property
    def periodic(self) -> Optional[list]:
        """Periodic boundary condition indices."""
        return self._core.config.periodic

    @property
    def reflective(self) -> Optional[list]:
        """Reflective boundary condition indices."""
        return self._core.config.reflective

    @property
    def beta(self) -> float:
        """Current inverse temperature."""
        return self.state.get_current("beta")

    @property
    def logz(self) -> float:
        """Current log evidence estimate."""
        return self.state.get_current("logz")

    @property
    def ess(self) -> float:
        """Current effective sample size."""
        return self.state.get_current("ess")

    @property
    def cv(self) -> Optional[float]:
        """Current volume variation (coefficient of variation). None if not yet computed."""
        return self.state.get_current("cv")

__init__

__init__(prior_transform: callable, log_likelihood: callable, n_dim: int, n_particles: Optional[int] = None, ess_ratio: float = 2.0, volume_variation: Optional[float] = None, log_likelihood_args: Optional[list] = None, log_likelihood_kwargs: Optional[dict] = None, vectorize: bool = False, blobs_dtype: Optional[str] = None, periodic: Optional[list] = None, reflective: Optional[list] = None, pool: Optional[Union[int, object]] = None, clustering: bool = True, normalize: bool = True, cluster_every: int = 1, split_threshold: float = 1.0, n_max_clusters: Optional[int] = None, sample: str = 'tpcn', n_steps: Optional[int] = None, n_max_steps: Optional[int] = None, resample: str = 'mult', output_dir: Optional[str] = None, output_label: Optional[str] = None, random_state: Optional[int] = None)

Initialize Tempest sampler.

Parameters are validated and stored in SamplerConfig, then delegated to SamplerCore for execution.

Parameters:

Name Type Description Default
prior_transform callable

Function transforming unit hypercube samples [0,1] to prior parameter space.

required
log_likelihood callable

Function computing log-likelihood for given parameter values.

required
n_dim int

Number of dimensions/parameters in the problem.

required
n_particles int

Number of particles (active samples) per iteration. When None (default), automatically set to 2 * n_dim.

None
ess_ratio float

Target ESS ratio (ESS / n_particles) for ESS mode (default: 2.0). The actual target ESS is ess_ratio * n_particles. Used when volume_variation=None.

2.0
volume_variation float

Target coefficient of variation for volume to enable dynamic mode (default: None). When None, uses ESS-only mode. When a positive float, uses dynamic mode which searches for beta where volume variation equals this value after finding beta_upper where ESS = n_particles * ess_ratio. This is the CV of sqrt(det(Cov)), measuring the variation of the confidence ellipsoid volume. Lower values enforce more uniform coverage. Must be positive when not None.

None
log_likelihood_args list

Positional arguments to pass to log_likelihood function.

None
log_likelihood_kwargs dict

Keyword arguments to pass to log_likelihood function.

None
vectorize bool

If True, likelihood function accepts batched inputs (n_samples, n_dim). Default is False.

False
blobs_dtype str

NumPy dtype string for auxiliary data returned by likelihood.

None
periodic list[int]

List of parameter indices with periodic boundary conditions.

None
reflective list[int]

List of parameter indices with reflective boundary conditions.

None
pool int or object

Parallelization pool. Can be number of processes or Pool object.

None
clustering bool

Enable hierarchical Gaussian mixture clustering. Default is True.

True
normalize bool

Normalize clusters during training. Default is True.

True
cluster_every int

Train clusterer every N iterations. Default is 1.

1
split_threshold float

Threshold for splitting clusters. Default is 1.0.

1.0
n_max_clusters int

Maximum number of clusters. None means no limit.

None
sample str

MCMC proposal method: 'tpcn' or 'rwm'. Default is 'tpcn'.

'tpcn'
n_steps int

Base MCMC steps per dimension at optimal acceptance rate of 23.4%. Actual steps adapt as: n_steps_0 * n_dim * (0.234/acceptance_rate) * (sigma_0/sigma)**2. Default is 5.

None
n_max_steps int

Maximum MCMC steps per dimension. The actual maximum is n_max_steps * n_dim. Default is 20 × n_steps.

None
resample str

Resampling method: 'mult' or 'syst'. Default is 'mult'.

'mult'
output_dir str

Output directory for state files. Default is 'states'.

None
output_label str

Label prefix for output files. Default is 'ps'.

None
random_state int

Random seed for reproducibility.

None
Source code in tempest/sampler.py
def __init__(
    self,
    prior_transform: callable,
    log_likelihood: callable,
    n_dim: int,
    n_particles: Optional[int] = None,
    ess_ratio: float = 2.0,
    volume_variation: Optional[float] = None,
    log_likelihood_args: Optional[list] = None,
    log_likelihood_kwargs: Optional[dict] = None,
    vectorize: bool = False,
    blobs_dtype: Optional[str] = None,
    periodic: Optional[list] = None,
    reflective: Optional[list] = None,
    pool: Optional[Union[int, object]] = None,
    clustering: bool = True,
    normalize: bool = True,
    cluster_every: int = 1,
    split_threshold: float = 1.0,
    n_max_clusters: Optional[int] = None,
    sample: str = "tpcn",
    n_steps: Optional[int] = None,
    n_max_steps: Optional[int] = None,
    resample: str = "mult",
    output_dir: Optional[str] = None,
    output_label: Optional[str] = None,
    random_state: Optional[int] = None,
):
    """
    Initialize Tempest sampler.

    Parameters are validated and stored in SamplerConfig, then delegated
    to SamplerCore for execution.

    Parameters
    ----------
    prior_transform : callable
        Function transforming unit hypercube samples [0,1] to prior parameter space.
    log_likelihood : callable
        Function computing log-likelihood for given parameter values.
    n_dim : int
        Number of dimensions/parameters in the problem.
    n_particles : int, optional
        Number of particles (active samples) per iteration. When None (default),
        automatically set to 2 * n_dim.
    ess_ratio : float, optional
        Target ESS ratio (ESS / n_particles) for ESS mode (default: 2.0).
        The actual target ESS is ess_ratio * n_particles. Used when volume_variation=None.
    volume_variation : float, optional
        Target coefficient of variation for volume to enable dynamic mode (default: None).
        When None, uses ESS-only mode. When a positive float, uses dynamic mode which
        searches for beta where volume variation equals this value after finding beta_upper
        where ESS = n_particles * ess_ratio. This is the CV of sqrt(det(Cov)),
        measuring the variation of the confidence ellipsoid volume.
        Lower values enforce more uniform coverage. Must be positive when not None.
    log_likelihood_args : list, optional
        Positional arguments to pass to log_likelihood function.
    log_likelihood_kwargs : dict, optional
        Keyword arguments to pass to log_likelihood function.
    vectorize : bool, optional
        If True, likelihood function accepts batched inputs (n_samples, n_dim).
        Default is False.
    blobs_dtype : str, optional
        NumPy dtype string for auxiliary data returned by likelihood.
    periodic : list[int], optional
        List of parameter indices with periodic boundary conditions.
    reflective : list[int], optional
        List of parameter indices with reflective boundary conditions.
    pool : int or object, optional
        Parallelization pool. Can be number of processes or Pool object.
    clustering : bool, optional
        Enable hierarchical Gaussian mixture clustering. Default is True.
    normalize : bool, optional
        Normalize clusters during training. Default is True.
    cluster_every : int, optional
        Train clusterer every N iterations. Default is 1.
    split_threshold : float, optional
        Threshold for splitting clusters. Default is 1.0.
    n_max_clusters : int, optional
        Maximum number of clusters. None means no limit.
    sample : str, optional
        MCMC proposal method: 'tpcn' or 'rwm'. Default is 'tpcn'.
    n_steps : int, optional
        Base MCMC steps per dimension at optimal acceptance rate of 23.4%.
        Actual steps adapt as: n_steps_0 * n_dim * (0.234/acceptance_rate) * (sigma_0/sigma)**2.
        Default is 5.
    n_max_steps : int, optional
        Maximum MCMC steps per dimension. The actual maximum is n_max_steps * n_dim.
        Default is 20 × n_steps.
    resample : str, optional
        Resampling method: 'mult' or 'syst'. Default is 'mult'.
    output_dir : str, optional
        Output directory for state files. Default is 'states'.
    output_label : str, optional
        Label prefix for output files. Default is 'ps'.
    random_state : int, optional
        Random seed for reproducibility.
    """
    # Wrap likelihood function
    wrapped_likelihood = FunctionWrapper(
        log_likelihood, log_likelihood_args, log_likelihood_kwargs
    )

    # Create validated configuration
    config = SamplerConfig(
        prior_transform=prior_transform,
        log_likelihood=wrapped_likelihood,
        n_dim=n_dim,
        n_particles=n_particles,
        ess_ratio=ess_ratio,
        volume_variation=volume_variation,
        log_likelihood_args=log_likelihood_args,
        log_likelihood_kwargs=log_likelihood_kwargs,
        vectorize=vectorize,
        blobs_dtype=blobs_dtype,
        periodic=periodic,
        reflective=reflective,
        pool=pool,
        clustering=clustering,
        normalize=normalize,
        cluster_every=cluster_every,
        split_threshold=split_threshold,
        n_max_clusters=n_max_clusters,
        sample=sample,
        n_steps=n_steps,
        n_max_steps=n_max_steps,
        resample=resample,
        output_dir=output_dir,
        output_label=output_label,
        random_state=random_state,
    )

    # Create state manager
    state = StateManager(n_dim)

    # Create internal coordinator
    self._core = SamplerCore(config, state)

    # Expose state for backward compatibility (tests access sampler.state)
    self.state = state

run

run(n_total: int = 4096, progress: bool = True, resume_state_path: Union[str, Path, None] = None, save_every: Optional[int] = None)

Run Persistent Sampling.

Parameters:

Name Type Description Default
n_total int

The total number of effectively independent samples to be collected (default is n_total=4096).

4096
progress bool

If True, print progress bar (default is progress=True).

True
resume_state_path str or Path or None

Path of state file used to resume a run. Default is None in which case the sampler does not load any previously saved states.

None
save_every int or None

Argument which determines how often (i.e. every how many iterations) Tempest saves state files to the output_dir directory. Default is None in which case no state files are stored during the run.

None
Source code in tempest/sampler.py
def run(
    self,
    n_total: int = 4096,
    progress: bool = True,
    resume_state_path: Union[str, Path, None] = None,
    save_every: Optional[int] = None,
):
    """
    Run Persistent Sampling.

    Parameters
    ----------
    n_total : int
        The total number of effectively independent samples to be
        collected (default is ``n_total=4096``).
    progress : bool
        If True, print progress bar (default is ``progress=True``).
    resume_state_path : str or Path or None
        Path of state file used to resume a run. Default is ``None`` in which case
        the sampler does not load any previously saved states.
    save_every : int or None
        Argument which determines how often (i.e. every how many iterations) ``Tempest`` saves
        state files to the ``output_dir`` directory. Default is ``None`` in which case no state
        files are stored during the run.
    """
    return self._core.run_sampling(
        n_total=n_total,
        progress=progress,
        resume_state_path=resume_state_path,
        save_every=save_every,
    )

sample

sample(save_every: Optional[int] = None, t0: int = 0) -> dict

Perform a single iteration of the PS algorithm.

Parameters:

Name Type Description Default
save_every int or None

Argument which determines how often (i.e. every how many iterations) Tempest saves state files to the output_dir directory. Default is None in which case no state files are stored during the run.

None
t0 int

The starting iteration index, used for determining when to save states. Default is 0.

0

Returns:

Name Type Description
state dict

Dictionary containing the current state of the particles.

Source code in tempest/sampler.py
def sample(self, save_every: Optional[int] = None, t0: int = 0) -> dict:
    """
    Perform a single iteration of the PS algorithm.

    Parameters
    ----------
    save_every : int or None
        Argument which determines how often (i.e. every how many iterations) ``Tempest`` saves
        state files to the ``output_dir`` directory. Default is ``None`` in which case no state
        files are stored during the run.
    t0 : int
        The starting iteration index, used for determining when to save states.
        Default is ``0``.

    Returns
    -------
    state : dict
        Dictionary containing the current state of the particles.
    """
    return self._core.execute_iteration(save_every=save_every, t0=t0)

posterior

posterior(resample: bool = False, return_blobs: bool = False, trim_importance_weights: bool = True, return_logw: bool = False, ess_trim: float = 0.99, bins_trim: int = 1000) -> tuple

Return posterior samples.

Parameters:

Name Type Description Default
resample bool

If True, resample particles (default is resample=False).

False
return_blobs bool

If True, return auxiliary data from likelihood (default is return_blobs=False).

False
trim_importance_weights bool

If True, trim importance weights (default is trim_importance_weights=True).

True
return_logw bool

If True, return log importance weights (default is return_logw=False).

False
ess_trim float

Effective sample size threshold for trimming (default is ess_trim=0.99).

0.99
bins_trim int

Number of bins for trimming (default is bins_trim=1000).

1000

Returns:

Name Type Description
x ndarray

Physical coordinates of posterior samples.

weights ndarray

Importance weights.

logl ndarray

Log-likelihood values.

blobs ndarray(optional)

Auxiliary data if return_blobs=True.

logw ndarray(optional)

Log importance weights if return_logw=True.

Source code in tempest/sampler.py
def posterior(
    self,
    resample: bool = False,
    return_blobs: bool = False,
    trim_importance_weights: bool = True,
    return_logw: bool = False,
    ess_trim: float = 0.99,
    bins_trim: int = 1000,
) -> tuple:
    """
    Return posterior samples.

    Parameters
    ----------
    resample : bool
        If True, resample particles (default is ``resample=False``).
    return_blobs : bool
        If True, return auxiliary data from likelihood (default is ``return_blobs=False``).
    trim_importance_weights : bool
        If True, trim importance weights (default is ``trim_importance_weights=True``).
    return_logw : bool
        If True, return log importance weights (default is ``return_logw=False``).
    ess_trim : float
        Effective sample size threshold for trimming (default is ``ess_trim=0.99``).
    bins_trim : int
        Number of bins for trimming (default is ``bins_trim=1000``).

    Returns
    -------
    x : np.ndarray
        Physical coordinates of posterior samples.
    weights : np.ndarray
        Importance weights.
    logl : np.ndarray
        Log-likelihood values.
    blobs : np.ndarray (optional)
        Auxiliary data if return_blobs=True.
    logw : np.ndarray (optional)
        Log importance weights if return_logw=True.
    """
    return self._core.compute_posterior(
        resample=resample,
        return_blobs=return_blobs,
        trim_importance_weights=trim_importance_weights,
        return_logw=return_logw,
        ess_trim=ess_trim,
        bins_trim=bins_trim,
    )

evidence

evidence() -> tuple[float, Optional[float]]

Return log evidence estimate and error.

Returns:

Name Type Description
logz float

Log evidence estimate.

logz_err float or None

Error estimate (currently None, for future use).

Source code in tempest/sampler.py
def evidence(self) -> tuple[float, Optional[float]]:
    """
    Return log evidence estimate and error.

    Returns
    -------
    logz : float
        Log evidence estimate.
    logz_err : float or None
        Error estimate (currently None, for future use).
    """
    return self._core.compute_evidence()

results

results()

Return results (backward compatibility).

Source code in tempest/sampler.py
def results(self):
    """Return results (backward compatibility)."""
    return self.state.compute_results()

save_state

save_state(path: Union[str, Path])

Save sampler state to file.

Parameters:

Name Type Description Default
path str or Path

Path where state will be saved.

required
Source code in tempest/sampler.py
def save_state(self, path: Union[str, Path]):
    """
    Save sampler state to file.

    Parameters
    ----------
    path : str or Path
        Path where state will be saved.
    """
    self._core.save_sampler_state(Path(path))

load_state

load_state(path: Union[str, Path])

Load sampler state from file.

Parameters:

Name Type Description Default
path str or Path

Path to state file.

required
Source code in tempest/sampler.py
def load_state(self, path: Union[str, Path]):
    """
    Load sampler state from file.

    Parameters
    ----------
    path : str or Path
        Path to state file.
    """
    self._core.load_sampler_state(Path(path))

Quick Reference

Creating a Sampler

import tempest as tp
import numpy as np

n_dim = 5

def prior_transform(u):
    return 20 * u - 10  # U(-10, 10)

def log_likelihood(x):
    return -0.5 * np.sum(x**2)

sampler = tp.Sampler(
    prior_transform=prior_transform,
    log_likelihood=log_likelihood,
    n_dim=n_dim,
    n_effective=512,
)

Key Parameters

Parameter Type Default Description
prior_transform callable - Prior distribution or transform function
log_likelihood callable - Log-likelihood function
n_dim int - Number of dimensions
n_particles Optional[int] None Number of particles per iteration. None (default) computes as 2 * n_dim.
ess_ratio float 2.0 Target ESS ratio (ESS / n_particles). Target ESS = ess_ratio * n_particles.
volume_variation Optional[float] None Target coefficient of variation for volume. None for ESS-only mode.
vectorize bool False Vectorized likelihood evaluation
pool Pool/int None Parallelization pool
clustering bool True Enable hierarchical clustering

Properties

Property Type Description
beta float Current inverse temperature
logz float Current log evidence estimate
ess float Current effective sample size
cv Optional[float] Current volume variation (coefficient of variation of sqrt(det(Cov))). None if not yet computed.

Running the Sampler

sampler.run(
    n_total=4096,      # Target independent samples
    progress=True,      # Show progress bar
    save_every=10,      # Checkpoint frequency
)

Extracting Results

# Weighted posterior samples
samples, weights, logl = sampler.posterior()

# Evidence estimate
logz, logz_err = sampler.evidence()

# Full results dictionary
results = sampler.results

Examples

Basic Usage

import numpy as np
import tempest as tp

n_dim = 5

def prior_transform(u):
    return 20 * u - 10

def log_likelihood(x):
    return -0.5 * np.sum(x**2)

sampler = tp.Sampler(
    prior_transform=prior_transform,
    log_likelihood=log_likelihood,
    n_dim=n_dim,
)
sampler.run(n_total=4096)

samples, weights, logl = sampler.posterior()

With Parallelization

sampler = tp.Sampler(
    prior_transform=prior_transform,
    log_likelihood=log_likelihood,
    n_dim=n_dim,
    pool=8,  # 8 processes
    # n_active is optional - automatically set to n_effective // 2 = 256
    # For optimal load balancing: n_active=256 (evenly divisible by 8)
)

Resuming from Checkpoint

sampler = tp.Sampler(
    prior_transform=prior_transform,
    log_likelihood=log_likelihood,
    n_dim=n_dim,
)
sampler.run(
    n_total=8192,
    resume_state_path="states/ps_100.state",
)