Source code for perfectns.likelihoods

#!/usr/bin/env python
"""
Classes representing spherically symmetric likelihoods.

Each likelihood class must contain a member function giving the log likelihood
as a function of the radial coordinate r = |theta| and the number of dimensions

    def logl_given_r(self, r, n_dim):
        ...

The number of dimensions is not stored in this class but in the
PerfectNSSettings object to ensure it is the same for the likelihood and the
prior.

Likelihood classes may also optionally contain the inverse function

    def r_given_logl(self, logl, n_dim):
        ...

(although this is not needed to generate nested sampling runs). Another
optional function is the analytic value of the log evidence for some
given prior and dimension, which is useful for checking results:

    def logz_analytic(self, prior, n_dim):
        ...
"""

import numpy as np
import perfectns.maths_functions as mf


[docs]class Gaussian(object): """Spherically symmetric Gaussian likelihood.""" def __init__(self, likelihood_scale=1.0): """Store Gaussian likelihood's sigma.""" self.likelihood_scale = likelihood_scale
[docs] def logl_given_r(self, r, n_dim): """ Get loglikelihood values for input radial coordinates. Parameters ---------- r: float or numpy array Radial coordinates. n_dim: int Number of dimensions. Returns ------- logl: same type and size as r Loglikelihood values. """ return mf.log_gaussian_given_r(r, self.likelihood_scale, n_dim)
# Optional functions
[docs] def r_given_logl(self, logl, n_dim): """ Get the radial coordinates corresponding to the input loglikelihood values. Parameters ---------- logl: float or numpy array Loglikelihood values. n_dim: int Number of dimensions. Returns ------- r: same type and size as logl Radial coordinates. """ return mf.r_given_log_gaussian(logl, self.likelihood_scale, n_dim)
[docs] def logz_analytic(self, prior, n_dim): """ Returns analytic value of the log evidence for the input prior and dimension if it is available. If not set up for this prior an AssertionError is thrown (this is caught in functions which check analytical values where they are available). Parameters ---------- prior: object n_dim: int Number of dimensions. Returns ------- float Analytic value of log Z for this likelihood given the prior and number of dimensions. """ assert type(prior).__name__ in ['Uniform', 'Gaussian'], \ ('No logz_analytic set up for ' + type(self).__name__ + ' likelihoods and ' + type(prior).__name__ + ' priors.') if type(prior).__name__ == 'Uniform': # logZ = -log volume of uniform prior + correction for truncation logvol = mf.nsphere_logvol(n_dim, radius=prior.prior_scale) # To find how much of the likelihood's mass lies within the uniform # prior we can reuse the gaussian_logx_given_r function which is # used for Gaussian priors. return -logvol + mf.gaussian_logx_given_r(prior.prior_scale, self.likelihood_scale, n_dim) else: assert type(prior).__name__ == 'Gaussian' # See 'Products and convolutions of Gaussian probability density # functions' (P Bromiley, 2003) page 3 for a derivation of this # result return (-n_dim / 2.) * np.log(2 * np.pi * (self.likelihood_scale ** 2 + prior.prior_scale ** 2))
[docs]class ExpPower(object): """ Spherically symmetric exponential power likelihood. When power=1, this is the same as the Gaussian likelihood. """ def __init__(self, likelihood_scale=1, power=2): """Save the likelihood scale and power.""" self.likelihood_scale = likelihood_scale self.power = power
[docs] def logl_given_r(self, r, n_dim): """ Get loglikelihood values for input radial coordinates. Parameters ---------- r: float or numpy array Radial coordinates. n_dim: int Number of dimensions. Returns ------- logl: same type and size as r Loglikelihood values. """ return mf.log_exp_power_given_r(r, self.likelihood_scale, n_dim, b=self.power)
# Optional functions
[docs] def r_given_logl(self, logl, n_dim): """ Get the radial coordinates corresponding to the input loglikelihood values. Parameters ---------- logl: float or numpy array Loglikelihood values. n_dim: int Number of dimensions. Returns ------- r: same type and size as logl Radial coordinates. """ return mf.r_given_log_exp_power(logl, self.likelihood_scale, n_dim, b=self.power)
[docs]class Cauchy(object): """Spherically symmetric Cauchy likelihood.""" def __init__(self, likelihood_scale=1): """Save the likelihood scale.""" self.likelihood_scale = likelihood_scale
[docs] def logl_given_r(self, r, n_dim): """ Get loglikelihood values for input radial coordinates. Parameters ---------- r: float or numpy array Radial coordinates. n_dim: int Number of dimensions. Returns ------- logl: same type and size as r Loglikelihood values. """ return mf.log_cauchy_given_r(r, self.likelihood_scale, n_dim)
# Optional functions
[docs] def r_given_logl(self, logl, n_dim): """ Get the radial coordinates corresponding to the input loglikelihood values. Parameters ---------- logl: float or numpy array Loglikelihood values. n_dim: int Number of dimensions. Returns ------- r: same type and size as logl Radial coordinates. """ return mf.r_given_log_cauchy(logl, self.likelihood_scale, n_dim)