cofi.utils.ReducedLikelihood#

class cofi.utils.ReducedLikelihood(data: ndarray, forward_func: Callable, fwd_kwargs: dict | None = None, G: ndarray | None = None, Cd_ref: ndarray | None = None, case: str = 'none', nu: float = 4.0, s: float = 1.0, eps: float = 1e-154, kernel=None, n_params: int | None = None)[source]#

Reduced likelihood for various data covariance cases.

This class implements reduced likelihood functions for different assumptions about the data covariance structure:

  • ‘none’: Fixed covariance (standard Gaussian likelihood)

  • ‘scaled’: Scaled reference covariance

  • ‘kernel’: Profiled amplitude with parameterized kernel covariance

  • ‘kernel_full’: Explicit amplitude with parameterized kernel covariance

  • ‘spherical’: Spherical covariance (diagonal with same variance)

  • ‘diag’: Diagonal covariance with Student-t likelihood (robust)

  • ‘diag_legacy’: Diagonal covariance (legacy, numerically unstable near zero)

  • ‘full’: Full covariance matrix estimation

Parameters:
  • data (np.ndarray) – The observed data vector of shape (n_data,)

  • forward_func (Callable) – A callable that takes model parameters and returns predicted data of shape (n_data,). Should accept **fwd_kwargs if provided.

  • fwd_kwargs (dict, optional) – Keyword arguments to pass to forward_func

  • G (Optional[np.ndarray], default=None) – Jacobian matrix of shape (n_data, n_params). Required for gradient() and hessian() but not for log_likelihood(). Must be updated before each evaluation for non-linear problems.

  • Cd_ref (Optional[np.ndarray], default=None) – Reference covariance matrix. Required for ‘scaled’ case. For ‘none’ case: if not provided, defaults to identity matrix (assumes uncorrelated, unit-variance noise). Not used for ‘spherical’, ‘diag’, ‘diag_legacy’, or ‘full’ cases.

  • kernel (optional) – Kernel instance (e.g. SquaredExponentialKernel). Required for case='kernel'. Must expose n_params, evaluate(eta), derivative(eta), and second_derivative(eta) methods.

  • case (str, default='none') – The covariance case: ‘none’, ‘scaled’, ‘kernel’, ‘kernel_full’, ‘spherical’, ‘diag’, ‘diag_legacy’, or ‘full’. The 'kernel_full' case is like 'kernel' but with explicit phi = log(sigma_d) as a parameter instead of profiling sigma_d out. Model vector: [m_phys, phi, eta].

  • nu (float, default=4.0) – Degrees of freedom for Student-t likelihood (used in ‘diag’ case). Smaller values (e.g., 3-5) give heavier tails and more robustness to outliers. Larger values approach Gaussian behavior.

  • s (float, default=1.0) – Scale parameter for Student-t likelihood (used in ‘diag’ case). Controls the width of the distribution. Should be set to approximate the expected noise standard deviation (e.g., via a quick least-squares prefit).

  • eps (float, default=1e-154) – Small number for numerical stability

  • n_params (int, optional) – Number of physical model parameters (excluding kernel hyperparameters). When G is provided, this is inferred from G.shape[1]. When G=None, provide this to enable model shape validation for log_likelihood() without computing the Jacobian. If both G and n_params are provided, they must be consistent (G.shape[1] == n_params).

Raises:

ValueError – If Cd_ref is not provided for ‘scaled’ case If kernel is not provided for ‘kernel’ case If case is not one of the supported options If G is not set when calling gradient() or hessian()

Examples

>>> import numpy as np
>>> from cofi.utils import ReducedLikelihood
>>>
>>> # Define data and forward function
>>> data = np.array([1.0, 2.0, 3.0])
>>> def forward_func(m):
...     return np.array([m[0], m[1], m[0] + m[1]])  # Linear forward model
>>>
>>> # Jacobian matrix (can be computed separately)
>>> G = np.array([[1, 0], [0, 1], [1, 1]])
>>>
>>> # Create likelihood with spherical covariance assumption
>>> likelihood = ReducedLikelihood(
...     data=data,
...     forward_func=forward_func,
...     G=G,
...     case='spherical'
... )
>>>
>>> # Evaluate at a model
>>> model = np.array([1.5, 2.5])
>>> log_p = likelihood.log_likelihood(model)
>>> grad = likelihood.gradient(model)
>>> hess = likelihood.hessian(model)
>>>
>>> # For non-linear problems, update G before each evaluation
>>> new_model = np.array([2.0, 3.0])
>>> # Compute new Jacobian (e.g., using finite differences)
>>> G_new = compute_jacobian(new_model)  # User-defined
>>> likelihood.G = G_new
>>> log_p_new = likelihood.log_likelihood(new_model)

Derivative-free optimization (no Jacobian needed):

>>> # For Nelder-Mead or other derivative-free methods,
>>> # only log_likelihood() is needed — no G required.
>>> likelihood = ReducedLikelihood(
...     data=data,
...     forward_func=forward_func,
...     case='spherical',
...     n_params=2,  # number of model parameters
... )
>>> log_p = likelihood.log_likelihood(model)  # Works without G

Reference Details

__call__(model: ndarray) float#

A class instance itself can also be called as a function.

It works exactly the same as log_likelihood.

In other words, the following two usages are exactly the same:

>>> my_likelihood = GaussianLikelihood(data, forward_func)
>>> log_p = my_likelihood(np.array([1,2,3]))                    # usage 1
>>> log_p = my_likelihood.log_likelihood(np.array([1,2,3]))     # usage 2
Parameters:

model (np.ndarray) – The model parameters to evaluate

Returns:

The log-likelihood value

Return type:

float

get_ml_cov(model: ndarray) ndarray | None[source]#

Evaluate the covariance matrix at given model parameters.

This method does not require the Jacobian matrix G to be set.

gradient(model: ndarray) ndarray[source]#

Evaluate the gradient at given model parameters.

Requires the Jacobian matrix G to be set. If G=None, raises ValueError with guidance on how to proceed.

hessian(model: ndarray) ndarray[source]#

Evaluate the hessian at given model parameters.

Requires the Jacobian matrix G to be set. If G=None, raises ValueError with guidance on how to proceed.

log_likelihood(model: ndarray) float[source]#

Evaluate the log-likelihood at given model parameters.

This method does not require the Jacobian matrix G to be set.

G#

Jacobian matrix of shape (n_data, n_params).

model_shape#

Return the model shape.

model_size#

The number of unknowns that current likelihood function accepts.

Returns:

The total number of model parameters

Return type:

Number

back to top