CosmoFit.likelihoods

Covariance

A likelihood’s covariance is constant – it never depends on the cosmology – but it is solved against at every single evaluation, so which primitive does that solve is a measurable choice rather than a detail.

Covariance matrix utilities.

Re-exported from data.covariance. The implementation lives in the data package (rather than here) so that data.loader – which needs make_covariance() to build dataset covariance objects – does not have to import the likelihoods package to get it. likelihoods/__init__.py eagerly imports the concrete likelihood classes (CCLikelihood, PantheonLikelihood, …), which themselves import data.loader; if data.loader also imported from likelihoods, that would be a circular import (reproducible any time data.loader – or a module that imports it before likelihoods does – is the first thing imported).

This module is kept so existing from .covariance import ... / from CosmoFit.likelihoods.covariance import ... imports keep working unchanged.

class CosmoFit.likelihoods.covariance.CovarianceBase(n)[source]

Bases: ABC

Abstract covariance class.

abstractmethod solve(vector)[source]

Return C^-1 @ vector.

Needed (in addition to chi2) whenever a likelihood wants to analytically marginalize over a linear nuisance parameter (e.g. the SN absolute magnitude).

property size: int

Matrix dimension.

class CosmoFit.likelihoods.covariance.DenseCovariance(matrix, use_inverse=None)[source]

Bases: CovarianceBase

Full covariance matrix using a Cholesky decomposition.

For a large matrix, solve() does not use the Cholesky factor directly. The covariance here is constant – it never depends on the cosmology – but solve() is called at every single likelihood evaluation, i.e. millions of times over an MCMC run. Under those conditions cho_solve is the wrong primitive:

  • a triangular solve (LAPACK dtrsv) is an inherently sequential recurrence – each element depends on the previous one – so BLAS cannot thread it, and it stays single-core no matter how many cores the machine has;

  • a symmetric mat-vec against a precomputed inverse (dsymv) does the same O(n^2) work with no such dependency chain, so BLAS does thread it, and it vectorizes far better even on one core.

Measured on the bundled Pantheon+ covariance (1624x1624): 1.70 ms per cho_solve vs 0.80 ms per mat-vec single-threaded (2.1x), and 0.18 ms with threaded BLAS (9.1x) – the difference between an MCMC that uses one core and one that uses the whole machine without any multiprocessing at all. It also scales far better across worker processes (7.5x on 8 processes, vs 4.8x).

Forming an explicit inverse is normally poor numerical practice, so it is not done blindly: the inverse is built from the Cholesky factor and then validated against the original matrix (see _try_build_inverse()). If it does not reproduce the identity to near machine precision – an ill-conditioned covariance – it is discarded and solve() falls back to the Cholesky path. For the covariances actually shipped with this library the check passes with ~1e-14 residual (Pantheon+ has condition number ~5e2, i.e. extremely well conditioned), and chi2 agrees with the Cholesky result to all 16 significant digits.

Parameters:
  • matrix (ndarray) – The covariance matrix.

  • use_inverse (bool, optional) – Force the fast inverse path on (True) or off (False). Default (None) enables it for matrices at least _INVERSE_MIN_SIZE on a side, where the speedup is worth the extra n^2 of memory, and only if the validation above passes.

property sigma

Per-point uncertainty, i.e. sqrt of the diagonal.

Off-diagonal (correlation) information is of course lost, so this is only a marginal 1D uncertainty – but it is the standard error-bar convention for plotting individual data points from a dataset whose likelihood otherwise uses the full covariance matrix (e.g. Hubble-diagram or H(z) figures for a dataset with correlated systematics).

property condition_number: float

Matrix condition number.

property is_positive_definite: bool

Check whether the covariance matrix is positive definite.

property uses_inverse: bool

Whether solve() is using the precomputed explicit inverse (fast path) rather than the Cholesky factor.

solve(vector)[source]

Return C^-1 @ vector.

Needed (in addition to chi2) whenever a likelihood wants to analytically marginalize over a linear nuisance parameter (e.g. the SN absolute magnitude).

class CosmoFit.likelihoods.covariance.DiagonalCovariance(sigma)[source]

Bases: CovarianceBase

Diagonal covariance defined from measurement uncertainties.

property is_positive_definite: bool

Diagonal covariance matrices are always positive definite.

property condition_number: float

Condition number of the diagonal covariance matrix.

property shape

Shape of the equivalent covariance matrix.

solve(vector)[source]

Return C^-1 @ vector.

Needed (in addition to chi2) whenever a likelihood wants to analytically marginalize over a linear nuisance parameter (e.g. the SN absolute magnitude).

class CosmoFit.likelihoods.covariance.PrecisionCovariance(precision)[source]

Bases: CovarianceBase

Covariance defined by a precomputed precision (inverse covariance) matrix.

Some public data releases (e.g. DES-SN5YR) ship the precision matrix directly rather than the covariance itself – using it as-is avoids inverting it (to get a covariance for DenseCovariance) only to have every solve() call effectively invert it back via a Cholesky solve; a single matrix-vector product against the precision matrix is both cheaper and avoids that redundant, numerically lossy round trip.

The covariance matrix itself (.matrix, .sigma, …) is only computed lazily, on first access – likelihood evaluation (chi2/solve) never needs it.

property matrix

The covariance matrix itself, computed lazily (and cached) by inverting the precision matrix. Only needed for diagnostics/plotting (sigma, correlation, …), never for solve()/chi2().

property sigma

Per-point uncertainty, i.e. sqrt of the diagonal of the covariance matrix. See DenseCovariance.sigma.

solve(vector)[source]

Return C^-1 @ vector – just the stored precision matrix applied directly, no factorization/inversion needed.

CosmoFit.likelihoods.covariance.make_covariance(*, cov=None, sigma=None, precision=None)[source]

Construct the appropriate covariance object.

Parameters:
  • cov (ndarray, optional) – Full covariance matrix.

  • sigma (ndarray, optional) – Measurement uncertainties.

  • precision (ndarray, optional) – Precision (inverse covariance) matrix, for datasets that ship it directly (e.g. DES-SN5YR) – see PrecisionCovariance.

Returns:

CovarianceBase – Covariance handler.