예제 #1
0
    def __init__(self,
                 minimum,
                 maximum,
                 name=None,
                 latex_label=None,
                 unit=None,
                 boundary=None):
        """Log-Uniform prior with bounds

        Parameters
        ----------
        minimum: float
            See superclass
        maximum: float
            See superclass
        name: str
            See superclass
        latex_label: str
            See superclass
        unit: str
            See superclass
        boundary: str
            See superclass
        """
        super(LogUniform, self).__init__(name=name,
                                         latex_label=latex_label,
                                         unit=unit,
                                         minimum=minimum,
                                         maximum=maximum,
                                         alpha=-1,
                                         boundary=boundary)
        if self.minimum <= 0:
            logger.warning(
                'You specified a uniform-in-log prior with minimum={}'.format(
                    self.minimum))
예제 #2
0
    def sample(self, size=1, **kwargs):
        """
        Draw a sample from the prior.

        Parameters
        ----------
        size: int, float (defaults to 1)
            number of samples to draw
        kwargs: dict
            kwargs passed to the dist.sample method
        Returns
        -------
        float:
            A sample from the prior paramter.
        """

        if self.name in self.dist.sampled_parameters:
            logger.warning("You have already drawn a sample from parameter "
                           "'{}'. The same sample will be "
                           "returned".format(self.name))

        if len(self.dist.current_sample) == 0:
            # generate a sample
            self.dist.sample(size=size, **kwargs)

        sample = self.dist.current_sample[self.name]

        if self.name not in self.dist.sampled_parameters:
            self.dist.sampled_parameters.append(self.name)

        if len(self.dist.sampled_parameters) == len(self.dist):
            # reset samples
            self.dist.reset_sampled()
        self.least_recently_sampled = sample
        return sample
예제 #3
0
파일: dict.py 프로젝트: k-ship/bilby
 def from_dictionary(self, dictionary):
     eval_dict = dict(inf=np.inf)
     for key, val in iteritems(dictionary):
         if isinstance(val, Prior):
             continue
         elif isinstance(val, (int, float)):
             dictionary[key] = DeltaFunction(peak=val)
         elif isinstance(val, str):
             cls = val.split('(')[0]
             args = '('.join(val.split('(')[1:])[:-1]
             try:
                 dictionary[key] = DeltaFunction(peak=float(cls))
                 logger.debug("{} converted to DeltaFunction prior".format(key))
                 continue
             except ValueError:
                 pass
             if "." in cls:
                 module = '.'.join(cls.split('.')[:-1])
                 cls = cls.split('.')[-1]
             else:
                 module = __name__.replace(
                     '.' + os.path.basename(__file__).replace('.py', ''), ''
                 )
             cls = getattr(import_module(module), cls, cls)
             if key.lower() in ["conversion_function", "condition_func"]:
                 setattr(self, key, cls)
             elif isinstance(cls, str):
                 if "(" in val:
                     raise TypeError("Unable to parse prior class {}".format(cls))
                 else:
                     continue
             elif (cls.__name__ in ['MultivariateGaussianDist',
                                    'MultivariateNormalDist']):
                 if key not in eval_dict:
                     eval_dict[key] = eval(val, None, eval_dict)
             elif (cls.__name__ in ['MultivariateGaussian',
                                    'MultivariateNormal']):
                 dictionary[key] = eval(val, None, eval_dict)
             else:
                 try:
                     dictionary[key] = cls.from_repr(args)
                 except TypeError as e:
                     raise TypeError(
                         "Unable to parse prior, bad entry: {} "
                         "= {}. Error message {}".format(key, val, e)
                     )
         elif isinstance(val, dict):
             logger.warning(
                 'Cannot convert {} into a prior object. '
                 'Leaving as dictionary.'.format(key))
         else:
             raise TypeError(
                 "Unable to parse prior, bad entry: {} "
                 "= {} of type {}".format(key, val, type(val))
             )
     self.update(dictionary)
예제 #4
0
 def from_dictionary(self, dictionary):
     for key, val in iteritems(dictionary):
         if isinstance(val, str):
             try:
                 prior = eval(val)
                 if isinstance(prior, (Prior, float, int, str)):
                     val = prior
             except (NameError, SyntaxError, TypeError):
                 logger.debug(
                     "Failed to load dictionary value {} correctly".format(
                         key))
                 pass
         elif isinstance(val, dict):
             logger.warning('Cannot convert {} into a prior object. '
                            'Leaving as dictionary.'.format(key))
         self[key] = val
예제 #5
0
    def fill_priors(self, likelihood, default_priors_file=None):
        """
        Fill dictionary of priors based on required parameters of likelihood

        Any floats in prior will be converted to delta function prior. Any
        required, non-specified parameters will use the default.

        Note: if `likelihood` has `non_standard_sampling_parameter_keys`, then
        this will set-up default priors for those as well.

        Parameters
        ----------
        likelihood: bilby.likelihood.GravitationalWaveTransient instance
            Used to infer the set of parameters to fill the prior with
        default_priors_file: str, optional
            If given, a file containing the default priors.


        Returns
        -------
        prior: dict
            The filled prior dictionary

        """

        self.convert_floats_to_delta_functions()

        missing_keys = set(likelihood.parameters) - set(self.keys())

        for missing_key in missing_keys:
            if not self.test_redundancy(missing_key):
                default_prior = create_default_prior(missing_key,
                                                     default_priors_file)
                if default_prior is None:
                    set_val = likelihood.parameters[missing_key]
                    logger.warning(
                        "Parameter {} has no default prior and is set to {}, this"
                        " will not be sampled and may cause an error.".format(
                            missing_key, set_val))
                else:
                    self[missing_key] = default_prior

        for key in self:
            self.test_redundancy(key)
예제 #6
0
파일: dict.py 프로젝트: k-ship/bilby
    def test_has_redundant_keys(self):
        """
        Test whether there are redundant keys in self.

        Return
        ------
        bool: Whether there are redundancies or not
        """
        redundant = False
        for key in self:
            if isinstance(self[key], Constraint):
                continue
            temp = self.copy()
            del temp[key]
            if temp.test_redundancy(key, disable_logging=True):
                logger.warning('{} is a redundant key in this {}.'
                               .format(key, self.__class__.__name__))
                redundant = True
        return redundant
예제 #7
0
    def __init__(self,
                 file_name,
                 minimum=None,
                 maximum=None,
                 name=None,
                 latex_label=None,
                 unit=None,
                 boundary=None):
        """Creates an interpolated prior function from arrays of xx and yy=p(xx) extracted from a file

        Parameters
        ----------
        file_name: str
            Name of the file containing the xx and yy arrays
        minimum: float
            See superclass
        maximum: float
            See superclass
        name: str
            See superclass
        latex_label: str
            See superclass
        unit: str
            See superclass
        boundary: str
            See superclass

        """
        try:
            self.id = file_name
            xx, yy = np.genfromtxt(self.id).T
            super(FromFile, self).__init__(xx=xx,
                                           yy=yy,
                                           minimum=minimum,
                                           maximum=maximum,
                                           name=name,
                                           latex_label=latex_label,
                                           unit=unit,
                                           boundary=boundary)
        except IOError:
            logger.warning("Can't load {}.".format(self.id))
            logger.warning("Format should be:")
            logger.warning(r"x\tp(x)")
예제 #8
0
    def __init__(self,
                 posteriors,
                 hyper_prior,
                 sampling_prior=None,
                 ln_evidences=None,
                 max_samples=1e100,
                 selection_function=lambda args: 1,
                 conversion_function=lambda args: (args, None),
                 cupy=True):
        """
        Parameters
        ----------
        posteriors: list
            An list of pandas data frames of samples sets of samples.
            Each set may have a different size.
            These can contain a `prior` column containing the original prior
            values.
        hyper_prior: `bilby.hyper.model.Model`
            The population model, this can alternatively be a function.
        sampling_prior: `bilby.hyper.model.Model` *DEPRECATED*
            The sampling prior, this can alternatively be a function.
        ln_evidences: list, optional
            Log evidences for single runs to ensure proper normalisation
            of the hyperparameter likelihood. If not provided, the original
            evidences will be set to 0. This produces a Bayes factor between
            the sampling power_prior and the hyperparameterised model.
        selection_function: func
            Function which evaluates your population selection function.
        conversion_function: func
            Function which converts a dictionary of sampled parameter to a
            dictionary of parameters of the population model.
        max_samples: int, optional
            Maximum number of samples to use from each set.
        cupy: bool
            If True and a compatible CUDA environment is available,
            cupy will be used for performance.
            Note: this requires setting up your hyper_prior properly.
        """
        if cupy and not CUPY_LOADED:
            logger.warning('Cannot import cupy, falling back to numpy.')

        self.samples_per_posterior = max_samples
        self.data = self.resample_posteriors(posteriors,
                                             max_samples=max_samples)

        if not isinstance(hyper_prior, Model):
            hyper_prior = Model([hyper_prior])
        self.hyper_prior = hyper_prior
        Likelihood.__init__(self, hyper_prior.parameters)

        if sampling_prior is not None:
            logger.warning('Passing a sampling_prior is deprecated. This '
                           'should be passed as a column in the posteriors.')
            if not isinstance(sampling_prior, Model):
                sampling_prior = Model([sampling_prior])
            self.sampling_prior = sampling_prior.prob(self.data)
        elif 'prior' in self.data:
            self.sampling_prior = self.data.pop('prior')
        else:
            logger.info('No prior values provided, defaulting to 1.')
            self.sampling_prior = 1

        if ln_evidences is not None:
            self.total_noise_evidence = np.sum(ln_evidences)
        else:
            self.total_noise_evidence = np.nan

        self.conversion_function = conversion_function
        self.selection_function = selection_function

        self.n_posteriors = len(posteriors)
        self.samples_factor =\
            - self.n_posteriors * np.log(self.samples_per_posterior)
예제 #9
0
파일: dict.py 프로젝트: k-ship/bilby
 def __init__(self, dictionary=None, filename=None):
     """ DEPRECATED: USE PriorDict INSTEAD"""
     logger.warning("The name 'PriorSet' is deprecated use 'PriorDict' instead")
     super(PriorSet, self).__init__(dictionary, filename)
예제 #10
0
    def __init__(
            self,
            posteriors,
            hyper_prior,
            sampling_prior=None,
            ln_evidences=None,
            max_samples=1e100,
            selection_function=lambda args: 1,
            conversion_function=lambda args: (args, None),
            cupy=True,
    ):
        """
        Parameters
        ----------
        posteriors: list
            An list of pandas data frames of samples sets of samples.
            Each set may have a different size.
            These can contain a `prior` column containing the original prior
            values.
        hyper_prior: `bilby.hyper.model.Model`
            The population model, this can alternatively be a function.
        sampling_prior: array-like *DEPRECATED*
            The sampling prior, this can alternatively be a function.
            THIS WILL BE REMOVED IN THE NEXT RELEASE.
        ln_evidences: list, optional
            Log evidences for single runs to ensure proper normalisation
            of the hyperparameter likelihood. If not provided, the original
            evidences will be set to 0. This produces a Bayes factor between
            the sampling power_prior and the hyperparameterised model.
        selection_function: func
            Function which evaluates your population selection function.
        conversion_function: func
            Function which converts a dictionary of sampled parameter to a
            dictionary of parameters of the population model.
        max_samples: int, optional
            Maximum number of samples to use from each set.
        cupy: bool
            If True and a compatible CUDA environment is available,
            cupy will be used for performance.
            Note: this requires setting up your hyper_prior properly.
        """
        if cupy and not CUPY_LOADED:
            logger.warning("Cannot import cupy, falling back to numpy.")

        self.samples_per_posterior = max_samples
        self.data = self.resample_posteriors(posteriors,
                                             max_samples=max_samples)

        if isinstance(hyper_prior, types.FunctionType):
            hyper_prior = Model([hyper_prior])
        elif not (hasattr(hyper_prior, 'parameters')
                  and callable(getattr(hyper_prior, 'prob'))):
            raise AttributeError(
                "hyper_prior must either be a function, "
                "or a class with attribute 'parameters' and method 'prob'")
        self.hyper_prior = hyper_prior
        Likelihood.__init__(self, hyper_prior.parameters)

        if sampling_prior is not None:
            raise ValueError(
                "Passing a sampling_prior is deprecated and will be removed "
                "in the next release. This should be passed as a 'prior' "
                "column in the posteriors.")
        elif "prior" in self.data:
            self.sampling_prior = self.data.pop("prior")
        else:
            logger.info("No prior values provided, defaulting to 1.")
            self.sampling_prior = 1

        if ln_evidences is not None:
            self.total_noise_evidence = np.sum(ln_evidences)
        else:
            self.total_noise_evidence = np.nan

        self.conversion_function = conversion_function
        self.selection_function = selection_function

        self.n_posteriors = len(posteriors)
예제 #11
0
    def __init__(self, names, nmodes=1, mus=None, sigmas=None, corrcoefs=None,
                 covs=None, weights=None, bounds=None):
        """
        A class defining a multi-variate Gaussian, allowing multiple modes for
        a Gaussian mixture model.

        Note: if using a multivariate Gaussian prior, with bounds, this can
        lead to biases in the marginal likelihood estimate and posterior
        estimate for nested samplers routines that rely on sampling from a unit
        hypercube and having a prior transform, e.g., nestle, dynesty and
        MultiNest.

        Parameters
        ----------
        names: list
            A list of the parameter names in the multivariate Gaussian. The
            listed parameters must have the same order that they appear in
            the lists of means, standard deviations, and the correlation
            coefficient, or covariance, matrices.
        nmodes: int
            The number of modes for the mixture model. This defaults to 1,
            which will be checked against the shape of the other inputs.
        mus: array_like
            A list of lists of means of each mode in a multivariate Gaussian
            mixture model. A single list can be given for a single mode. If
            this is None then means at zero will be assumed.
        sigmas: array_like
            A list of lists of the standard deviations of each mode of the
            multivariate Gaussian. If supplying a correlation coefficient
            matrix rather than a covariance matrix these values must be given.
            If this is None unit variances will be assumed.
        corrcoefs: array
            A list of square matrices containing the correlation coefficients
            of the parameters for each mode. If this is None it will be assumed
            that the parameters are uncorrelated.
        covs: array
            A list of square matrices containing the covariance matrix of the
            multivariate Gaussian.
        weights: list
            A list of weights (relative probabilities) for each mode of the
            multivariate Gaussian. This will default to equal weights for each
            mode.
        bounds: list
            A list of bounds on each parameter. The defaults are for bounds at
            +/- infinity.
        """
        super(MultivariateGaussianDist, self).__init__(names=names, bounds=bounds)
        for name in self.names:
            bound = self.bounds[name]
            if bound[0] != -np.inf or bound[1] != np.inf:
                logger.warning("If using bounded ranges on the multivariate "
                               "Gaussian this will lead to biased posteriors "
                               "for nested sampling routines that require "
                               "a prior transform.")
        self.distname = 'mvg'
        self.mus = []
        self.covs = []
        self.corrcoefs = []
        self.sigmas = []
        self.weights = []
        self.eigvalues = []
        self.eigvectors = []
        self.sqeigvalues = []  # square root of the eigenvalues
        self.mvn = []  # list of multivariate normal distributions

        # put values in lists if required
        if nmodes == 1:
            if mus is not None:
                if len(np.shape(mus)) == 1:
                    mus = [mus]
                elif len(np.shape(mus)) == 0:
                    raise ValueError("Must supply a list of means")
            if sigmas is not None:
                if len(np.shape(sigmas)) == 1:
                    sigmas = [sigmas]
                elif len(np.shape(sigmas)) == 0:
                    raise ValueError("Must supply a list of standard "
                                     "deviations")
            if covs is not None:
                if isinstance(covs, np.ndarray):
                    covs = [covs]
                elif isinstance(covs, list):
                    if len(np.shape(covs)) == 2:
                        covs = [np.array(covs)]
                    elif len(np.shape(covs)) != 3:
                        raise TypeError("List of covariances the wrong shape")
                else:
                    raise TypeError("Must pass a list of covariances")
            if corrcoefs is not None:
                if isinstance(corrcoefs, np.ndarray):
                    corrcoefs = [corrcoefs]
                elif isinstance(corrcoefs, list):
                    if len(np.shape(corrcoefs)) == 2:
                        corrcoefs = [np.array(corrcoefs)]
                    elif len(np.shape(corrcoefs)) != 3:
                        raise TypeError("List of correlation coefficients the wrong shape")
                elif not isinstance(corrcoefs, list):
                    raise TypeError("Must pass a list of correlation "
                                    "coefficients")
            if weights is not None:
                if isinstance(weights, (int, float)):
                    weights = [weights]
                elif isinstance(weights, list):
                    if len(weights) != 1:
                        raise ValueError("Wrong number of weights given")

        for val in [mus, sigmas, covs, corrcoefs, weights]:
            if val is not None and not isinstance(val, list):
                raise TypeError("Value must be a list")
            else:
                if val is not None and len(val) != nmodes:
                    raise ValueError("Wrong number of modes given")

        # add the modes
        self.nmodes = 0
        for i in range(nmodes):
            mu = mus[i] if mus is not None else None
            sigma = sigmas[i] if sigmas is not None else None
            corrcoef = corrcoefs[i] if corrcoefs is not None else None
            cov = covs[i] if covs is not None else None
            weight = weights[i] if weights is not None else 1.

            self.add_mode(mu, sigma, corrcoef, cov, weight)
예제 #12
0
파일: joint.py 프로젝트: yi-fan-wang/bilby
    def __init__(self, names, bounds=None):
        """
        A class defining JointPriorDist that will be overwritten with child
        classes defining the joint prior distribtuions between given parameters,


        Parameters
        ----------
        names: list (required)
            A list of the parameter names in the JointPriorDist. The
            listed parameters must have the same order that they appear in
            the lists of statistical parameters that may be passed in child class
        bounds: list (optional)
            A list of bounds on each parameter. The defaults are for bounds at
            +/- infinity.
        """
        self.distname = 'joint_dist'
        if not isinstance(names, list):
            self.names = [names]
        else:
            self.names = names

        self.num_vars = len(self.names)

        # set the bounds for each parameter
        if isinstance(bounds, list):
            if len(bounds) != len(self):
                raise ValueError("Wrong number of parameter bounds")

            # check bounds
            for bound in bounds:
                if isinstance(bounds, (list, tuple, np.ndarray)):
                    if len(bound) != 2:
                        raise ValueError("Bounds must contain an upper and "
                                         "lower value.")
                    else:
                        if bound[1] <= bound[0]:
                            raise ValueError("Bounds are not properly set")
                else:
                    raise TypeError("Bound must be a list")

                logger.warning("If using bounded ranges on the multivariate "
                               "Gaussian this will lead to biased posteriors "
                               "for nested sampling routines that require "
                               "a prior transform.")
        else:
            bounds = [(-np.inf, np.inf) for _ in self.names]
        self.bounds = {name: val for name, val in zip(self.names, bounds)}

        self._current_sample = {}  # initialise empty sample
        self._uncorrelated = None
        self._current_lnprob = None

        # a dictionary of the parameters as requested by the prior
        self.requested_parameters = dict()
        self.reset_request()

        # a dictionary of the rescaled parameters
        self.rescale_parameters = dict()
        self.reset_rescale()

        # a list of sampled parameters
        self.reset_sampled()