# Path: emcee3/pools/default.py
# class DefaultPool(object):
# 
#     def map(self, fn, iterable):
#         return imap(fn, iterable)
# 
# Path: emcee3/model.py
# def is_model(model):
#     return (
#         hasattr(model, "compute_log_probability") and
#         callable(model.compute_log_probability)
#     )
# 
# class SimpleModel(Model):
#     """The simplest modeling interface.
# 
#     This model interface wraps functions describing the components of the
#     model. At a minimum, a function evaluating the log likelihood (up to a
#     constant) must be provided. In this case, the prior function is assumed to
#     be uniform and improper. All functions must have the call structure::
# 
#         log_likelihood(coords, *args)
# 
#     where ``coords`` is a coordinate vector and ``*args`` can be provided
#     using the ``args`` keyword argument. The ``log_likelihood`` and
#     ``log_prior`` functions should return scalars and the ``grad_*`` functions
#     should return ``numpy.array`` objects of the same length as the input
#     ``coords``.
# 
#     Args:
#         log_likelihood (callable): A function that evaluates the log
#             likelihood of the model.
#         log_prior (Optional[callable]): A function that evaluates the log
#             prior of the model. If not provided, this will be assumed to be
#             uniform and improper.
#         grad_log_likelihood (Optional[callable]): A function that evaluates the
#             gradient of the log likelihood of the model. If needed but not
#             provided, this will be evaluated numerically using a first order
#             method.
#         grad_log_prior (Optional[callable]): A function that evaluates the
#             gradient of the log prior of the model. If needed but not
#             provided, this will be evaluated numerically using a first order
#             method.
#         args (Optional[tuple]): Any other arguments to be provided to the
#             probability functions.
# 
#     """
# 
#     def __init__(self,
#                  log_likelihood,
#                  log_prior=None,
#                  grad_log_likelihood=None,
#                  grad_log_prior=None,
#                  args=tuple()):
#         # If no prior function is provided, we'll assume it to be flat and
#         # improper.
#         if log_prior is None:
#             log_prior = default_log_prior_function
#             grad_log_prior = default_grad_log_prior_function
# 
#         self.log_prior_func = log_prior
#         self.log_likelihood_func = log_likelihood
#         self.args = args
# 
#         # By default, numerically compute gradients.
#         if grad_log_prior is None:
#             grad_log_prior = numerical_gradient_1(self.log_prior_func)
#         self.grad_log_prior_func = grad_log_prior
#         if grad_log_likelihood is None:
#             grad_log_likelihood = numerical_gradient_1(
#                 self.log_likelihood_func)
#         self.grad_log_likelihood_func = grad_log_likelihood
# 
#     def compute_log_prior(self, state, **kwargs):
#         state.log_prior = self.log_prior_func(
#             state.coords, *(self.args)
#         )
#         return state
#     compute_log_prior.__doc__ = Model.compute_log_prior.__doc__
# 
#     def compute_grad_log_prior(self, state, **kwargs):
#         state.grad_log_prior = self.grad_log_prior_func(
#             state.coords, *(self.args)
#         )
#         return state
#     compute_grad_log_prior.__doc__ = Model.compute_grad_log_prior.__doc__
# 
#     def compute_log_likelihood(self, state, **kwargs):
#         state.log_likelihood = self.log_likelihood_func(state.coords,
#                                                         *(self.args))
#         return state
#     compute_log_likelihood.__doc__ = Model.compute_log_likelihood.__doc__
# 
#     def compute_grad_log_likelihood(self, state, **kwargs):
#         state.grad_log_likelihood = self.grad_log_likelihood_func(
#             state.coords, *(self.args)
#         )
#         return state
#     compute_grad_log_likelihood.__doc__ = \
#         Model.compute_grad_log_likelihood.__doc__
# 
#     def check_grad(self, coords, **kwargs):
#         """Check the gradients numerically.
# 
#         Args:
#             coords (array): The coordinates.
# 
#         Returns:
#             bool: If the numerical gradients and analytic gradients satisfy
#                 ``numpy.allclose``.
# 
#         """
#         com_g = (
#             self.grad_log_likelihood_func(coords, *(self.args)) +
#             self.grad_log_prior_func(coords, *(self.args))
#         )
#         num_g = numerical_gradient_2(self.get_lnprob, coords, **kwargs)
#         return np.allclose(com_g, num_g)


import numpy as np
from .pools import DefaultPool
from .model import is_model, SimpleModel

        Args:
            walkers (list[State]): A list of walkers states.
            subset: If provided, ``walkers`` only corresponds to the indicated
                subset of the walkers.

        Raises:
            RuntimeError: If an invalid state is accepted.

        """
        if subset is None:
            subset = slice(None)

        for j, s in zip(np.arange(self.nwalkers)[subset], walkers):
            self.acceptance[j] = s.accepted
            if s.accepted:
                self.walkers[j] = s
                if not np.isfinite(s.log_probability):
                    raise RuntimeError("invalid or zero-probability proposal "
                                       "accepted")

    def __getstate__(self):
        # In order to be generally picklable, we need to discard the pool
        # object before trying.
        d = self.__dict__
        d.pop("pool", None)
        return d

    def __setstate__(self, state):
        self.__dict__ = state

# Path: emcee3/pools/default.py
# class DefaultPool(object):
# 
#     def map(self, fn, iterable):
#         return imap(fn, iterable)
# 
# Path: emcee3/model.py
# def is_model(model):
#     return (
#         hasattr(model, "compute_log_probability") and
#         callable(model.compute_log_probability)
#     )
# 
# class SimpleModel(Model):
#     """The simplest modeling interface.
# 
#     This model interface wraps functions describing the components of the
#     model. At a minimum, a function evaluating the log likelihood (up to a
#     constant) must be provided. In this case, the prior function is assumed to
#     be uniform and improper. All functions must have the call structure::
# 
#         log_likelihood(coords, *args)
# 
#     where ``coords`` is a coordinate vector and ``*args`` can be provided
#     using the ``args`` keyword argument. The ``log_likelihood`` and
#     ``log_prior`` functions should return scalars and the ``grad_*`` functions
#     should return ``numpy.array`` objects of the same length as the input
#     ``coords``.
# 
#     Args:
#         log_likelihood (callable): A function that evaluates the log
#             likelihood of the model.
#         log_prior (Optional[callable]): A function that evaluates the log
#             prior of the model. If not provided, this will be assumed to be
#             uniform and improper.
#         grad_log_likelihood (Optional[callable]): A function that evaluates the
#             gradient of the log likelihood of the model. If needed but not
#             provided, this will be evaluated numerically using a first order
#             method.
#         grad_log_prior (Optional[callable]): A function that evaluates the
#             gradient of the log prior of the model. If needed but not
#             provided, this will be evaluated numerically using a first order
#             method.
#         args (Optional[tuple]): Any other arguments to be provided to the
#             probability functions.
# 
#     """
# 
#     def __init__(self,
#                  log_likelihood,
#                  log_prior=None,
#                  grad_log_likelihood=None,
#                  grad_log_prior=None,
#                  args=tuple()):
#         # If no prior function is provided, we'll assume it to be flat and
#         # improper.
#         if log_prior is None:
#             log_prior = default_log_prior_function
#             grad_log_prior = default_grad_log_prior_function
# 
#         self.log_prior_func = log_prior
#         self.log_likelihood_func = log_likelihood
#         self.args = args
# 
#         # By default, numerically compute gradients.
#         if grad_log_prior is None:
#             grad_log_prior = numerical_gradient_1(self.log_prior_func)
#         self.grad_log_prior_func = grad_log_prior
#         if grad_log_likelihood is None:
#             grad_log_likelihood = numerical_gradient_1(
#                 self.log_likelihood_func)
#         self.grad_log_likelihood_func = grad_log_likelihood
# 
#     def compute_log_prior(self, state, **kwargs):
#         state.log_prior = self.log_prior_func(
#             state.coords, *(self.args)
#         )
#         return state
#     compute_log_prior.__doc__ = Model.compute_log_prior.__doc__
# 
#     def compute_grad_log_prior(self, state, **kwargs):
#         state.grad_log_prior = self.grad_log_prior_func(
#             state.coords, *(self.args)
#         )
#         return state
#     compute_grad_log_prior.__doc__ = Model.compute_grad_log_prior.__doc__
# 
#     def compute_log_likelihood(self, state, **kwargs):
#         state.log_likelihood = self.log_likelihood_func(state.coords,
#                                                         *(self.args))
#         return state
#     compute_log_likelihood.__doc__ = Model.compute_log_likelihood.__doc__
# 
#     def compute_grad_log_likelihood(self, state, **kwargs):
#         state.grad_log_likelihood = self.grad_log_likelihood_func(
#             state.coords, *(self.args)
#         )
#         return state
#     compute_grad_log_likelihood.__doc__ = \
#         Model.compute_grad_log_likelihood.__doc__
# 
#     def check_grad(self, coords, **kwargs):
#         """Check the gradients numerically.
# 
#         Args:
#             coords (array): The coordinates.
# 
#         Returns:
#             bool: If the numerical gradients and analytic gradients satisfy
#                 ``numpy.allclose``.
# 
#         """
#         com_g = (
#             self.grad_log_likelihood_func(coords, *(self.args)) +
#             self.grad_log_prior_func(coords, *(self.args))
#         )
#         num_g = numerical_gradient_2(self.get_lnprob, coords, **kwargs)
#         return np.allclose(com_g, num_g)


# Path: emcee3/ensemble.py
import numpy as np
from .pools import DefaultPool
from .model import is_model, SimpleModel


        Args:
            walkers (list[State]): A list of walkers states.
            subset: If provided, ``walkers`` only corresponds to the indicated
                subset of the walkers.

        Raises:
            RuntimeError: If an invalid state is accepted.

        """
        if subset is None:
            subset = slice(None)

        for j, s in zip(np.arange(self.nwalkers)[subset], walkers):
            self.acceptance[j] = s.accepted
            if s.accepted:
                self.walkers[j] = s
                if not np.isfinite(s.log_probability):
                    raise RuntimeError("invalid or zero-probability proposal "
                                       "accepted")

    def __getstate__(self):
        # In order to be generally picklable, we need to discard the pool
        # object before trying.
        d = self.__dict__
        d.pop("pool", None)
        return d

    def __setstate__(self, state):
        self.__dict__ = state

        self.pool = DefaultPool()