Likelihoods

Input: specifying likelihoods to explore

Likelihoods are specified under the likelihood block, together with their options:

likelihood:
  [likelihood 1]:
     [option 1]: [value 1]
     [...]
  [likelihood 2]:
     [option 1]: [value 1]
     [...]

Likelihood parameters are specified within the params block, as explained in Parameters and priors.

cobaya comes with a number of internal general and cosmological likelihoods. You can define your external ones too with simple Python functions, as explained below.

External likelihoods: how to quickly define your own

External likelihoods are defined as:

likelihood:
  # Simple way (does not admit additional options)
  my_lik_1: [definition]
  # Alternative way (can also take speeds, etc)
  my_lik_1:
    external: [definition]
    speed: [...]
    [more options]

The [definition] follows the exact same rules as external priors, so check out that section for the details.

The only difference with external priors is that external likelihoods can provide derived parameters. This can only be achieved using a def’ed function (as opposed to a lambda one. To do that:

  1. In your function definition, define a keyword argument _derived with a list of derived parameter names as the default value.
  2. Inside the function, assume that you have been passed a dictionary through the keyword _derived and update it with the derived parameter values corresponding to the input files.

For an application, check out the advanced example.

If your external likelihood needs the products of a theory code:

  1. In your function definition, define a keyword argument _theory with a default value stating the needs of your theory code, i.e. the argument that will be passed to the needs method of the theory code, to let it know what needs to be computed at every iteration.
  2. At runtime, the current theory code instance will be passed through that keyword, so you can use it to invoke the methods that return the necessary producs.

For an application, check out Creating your own cosmological likelihood.

Note

Obviously, _derived and _theory are reserved parameter names that you cannot use as arguments in your likelihood definition, except for the purposes explained above.

Internal likelihoods: code conventions and defaults

Internal likelihoods are defined inside the likelihoods directory of the source tree. Each has its own directory, named as itself, containing at least three files:

  • A trivial __init__.py file containing a single line: from [name] import [name], where name is the name of the likelihood, and it’s folder.

  • A [name].py file, containing the particular class definition of the likelihood, inheriting from the Likelihood class (see below).

  • A [name].yaml file containing allowed options for the likelihood and the default experimental model:

    # Default options
    likelihood:
      [name]:
        [option 1]: [value 1]
        [...]
    
    # Experimental model
    params:
      [param 1]:
        prior:
          [prior info]
        [label, ref, etc.]
    prior:
      [prior 1]: [definition]
    

    The options and parameters defined in this file are the only ones recognized by the likelihood, and they are loaded automatically with their default values (options) and priors (parameters) by simply mentioning the likelihood in the input file, where one can re-define any of those options with a different prior, value, etc (see Changing and redefining parameters; inheritance). The same parameter may be defined by different likelihoods; in those cases, it needs to have the same default information (prior, label, etc.) in the defaults file of all the likelihoods using it.

  • An optional [name].bibtex file containing bibtex references associated to the likelihood, if relevant.

Note

Actually, there are some user-defined options that are common to all likelihoods and do not need to be specified in the defaults [name].yaml file, such as the computational speed of the likelihood (see Taking advantage of a speed hierarchy).

Implementing your own internal likelihood

Even if defining likelihoods with simple Python functions is easy, you may want to create a new internal-like likelihood to incorporate to your fork of cobaya, or to suggest us to include it in the main source.

Since cobaya was created to be flexible, creating your own likelihood is very easy: simply create a folder with its name under likelihoods in the source tree and follow the conventions explained above for internal likelihoods. Options defined in the [name].yaml are automatically accessible as attributes of your likelihood class at runtime.

You only need to specify one, or at most four, functions (see the Likelihood class documentation below):

  • A logp method taking a dictionary of (sampled) parameter values and returning a log-likelihood.
  • An (optional) initialize method preparing any computation, importing any necessary code, etc.
  • An (optional) add_theory method specifying the requests from the theory code, if it applies.
  • An (optional) close method doing whatever needs to be done at the end of the sampling (e.g. releasing memory).

You can use the Gaussian mixtures likelihood as a guide. If your likelihood needs a cosmological code, just define one in the input file and you can automatically access it as an attribute of your class: [your_likelihood].theory. Use the Planck likelihood as a guide to create your own cosmological likelihood.

Note

_theory and _derived are reserved parameter names: you cannot use them as options in your defaults file!

Likelihood module

Synopsis:Prototype likelihood and likelihood manager
Author:Jesus Torrado

This module defines the main Likelihood class, from which every likelihood inherits, and the LikelihoodCollection class, which groups and manages all the individual likelihoods and is the actual instance passed to the sampler.

Likelihood class

class likelihood.Likelihood(info, modules=None, timing=None)

Likelihood class prototype.

initialize()

Initializes the specifics of this likelihood. Note that at this point we know the `self.input_params` and the self.output_params.

add_theory()

Performs any necessary initialization on the theory side, e.g. requests observables

logp(**params_values)

Computes and returns the log likelihood value. Takes as keyword arguments the parameter values. To get the derived parameters, pass a _derived keyword with an empty dictionary.

close()

Finalizes the likelihood, if something needs to be done.

marginal(directions=None, params_values=None)

(For analytic likelihoods only.) Computes the marginal likelihood. If nothing is specified, returns the total marginal likelihood. If some directions are specified (as a list, tuple or array), returns the marginal likelihood pdf over those directions evaluated at the given parameter values.

d()

Dimension of the input vector.

NB: Different from dimensionality of the sampling problem, e.g. this may include fixed input parameters.

LikelihoodCollection class

class likelihood.LikelihoodCollection(info_likelihood, parameterization, info_theory=None, modules=None, timing=None)

Likelihood manager: Initializes the theory code and the experimental likelihoods.

logps(input_params, _derived=None, cached=True)

Computes observables and returns the (log) likelihoods separately. It takes a list of input parameter values, in the same order as they appear in the OrderedDictionary of the LikelihoodCollection. To compute the derived parameters, it takes an optional keyword _derived as an empty list, which is then populated with the derived parameter values.

logp(input_params, _derived=None, cached=True)

Computes observables and returns the (log) likelihood. It takes a list of sampled parameter values, in the same order as they appear in the OrderedDictionary of the LikelihoodCollection. To compute the derived parameters, it takes an optional keyword _derived as an empty list, which is then populated with the derived parameter values.