Source code for lenstronomy.Sampling.Samplers.base_nested_sampler

__author__ = "aymgal, johannesulf"

import lenstronomy.Util.sampling_util as utils
import numpy as np

__all__ = ["NestedSampler"]


[docs] class NestedSampler(object): """Base class for nested samplers."""
[docs] def __init__( self, likelihood_module, prior_type, prior_means, prior_sigmas, width_scale, sigma_scale, ): """ :param likelihood_module: likelihood_module like in likelihood.py (should be callable) :param prior_type: 'uniform' of 'gaussian', for converting the unit hypercube to param cube :param prior_means: if prior_type is 'gaussian', mean for each param :param prior_sigmas: if prior_type is 'gaussian', std dev for each param :param width_scale: scale the widths of the parameters space by this factor :param sigma_scale: if prior_type is 'gaussian', scale the gaussian sigma by this factor """ self._ll = likelihood_module self.n_dims, self.param_names = self._ll.param.num_param() lowers, uppers = self._ll.param_limits if width_scale < 1: self.lowers, self.uppers = utils.scale_limits(lowers, uppers, width_scale) else: self.lowers, self.uppers = lowers, uppers if prior_type == "gaussian": if prior_means is None or prior_sigmas is None: raise ValueError( "For gaussian prior type, means and sigmas are required" ) self.means, self.sigmas = prior_means, prior_sigmas * sigma_scale self.lowers, self.uppers = lowers, uppers elif prior_type != "uniform": raise ValueError("Sampling type {} not supported".format(prior_type)) self.prior_type = prior_type self._has_warned = False
[docs] def prior(self, u, *args): """Compute the mapping between the unit cube and parameter cube. :param u: unit hypercube, sampled by the algorithm :return: hypercube in parameter space """ # MultiNest passes its own type. Make a copy of the original and create # a Python version. u_orig = u u = np.array([u[i] for i in range(self.n_dims)]) if self.prior_type == "gaussian": p = utils.cube2args_gaussian( u, self.lowers, self.uppers, self.means, self.sigmas, self.n_dims, copy=True, ) elif self.prior_type == "uniform": p = utils.cube2args_uniform( u, self.lowers, self.uppers, self.n_dims, copy=True ) else: raise ValueError( 'prior type %s not supported! Chose "gaussian" or "uniform".' ) # MultiNest expects that we modify the origal array instead of # returning the transformed parameters. for i in range(self.n_dims): # But for PolyChord, this is read-only. try: u_orig[i] = p[i] except ValueError: pass return p
[docs] def log_likelihood(self, p, *args): """Compute the log-likelihood given list of parameters. :param x: parameter values :return: log-likelihood (from the likelihood module) """ # MultiNest passes its own type. p = np.array([p[i] for i in range(self.n_dims)]) log_l = self._ll(p) if not np.isfinite(log_l): if not self._has_warned: print("WARNING : logL is not finite : return very low value instead") log_l = -1e15 self._has_warned = True return float(log_l)
[docs] def run(self, kwargs_run): """Run the nested sampling algorithm.""" raise NotImplementedError("Method not be implemented in base class")