Source code for ultranest.simbase.minisbi.nested

"""Helpers for using nested sampling on top of an auxiliary distribution."""

import numpy as np
import torch

from .logistic import (kuma_logistic_cdf_vec, kuma_logistic_icdf_vec,
                       kuma_logistic_logpdf_vec)


[docs] def get_distribution_parameters(model, observed_data): """Query neural network model for Kumaraswamy-logistic distribution parameters. Parameters ---------- model : torch.nn.Module A trained neural posterior estimator that returns the tuple ``(loc, scale, a, b)`` when called with an input tensor. observed_data : array_like The observed data to condition on. Will be converted to a ``torch.float32`` tensor and given a batch dimension of 1. Returns ------- dict A dictionary with keys ``'loc'``, ``'scale'``, ``'a'``, and ``'b'``, each mapping to a Python list of floats representing the corresponding distribution parameter for each dimension. """ # Query the network once to get the distribution parameters x_t = torch.tensor(observed_data, dtype=torch.float32).unsqueeze(0) with torch.no_grad(): loc, scale, a, b = model(x_t) # Store as numpy arrays, shape (n_params,) return dict( loc=loc.squeeze(0).numpy().tolist(), scale=scale.squeeze(0).numpy().tolist(), a=a.squeeze(0).numpy().tolist(), b=b.squeeze(0).numpy().tolist() )
[docs] class KLPTransform: """Coordinate transform for a Kumaraswamy-logistic distribution (KLP). Provides mappings between nested-sampler unit-cube coordinates ``t`` and prior unit-cube coordinates ``u``, along with the associated log Jacobian and CDF evaluation. Parameters ---------- loc : array_like Location parameters of the Kumaraswamy-logistic distribution, shape ``(n_params,)``. scale : array_like Scale parameters of the Kumaraswamy-logistic distribution, shape ``(n_params,)``. a : array_like First shape parameters of the Kumaraswamy distribution, shape ``(n_params,)``. b : array_like Second shape parameters of the Kumaraswamy distribution, shape ``(n_params,)``. """ def __init__(self, loc, scale, a, b): """Initialise.""" self.loc = np.array(loc) self.scale = np.array(scale) self.a = np.array(a) self.b = np.array(b)
[docs] def transform(self, t): """Map unit-cube coordinates ``t`` to prior unit-cube coordinates ``u`` via inverse CDF. Parameters ---------- t : np.ndarray Uniformly distributed sample from the nested sampler, shape ``(n_params,)``. Returns ------- u : np.ndarray Corresponding unit-cube coordinates of shape ``(n_params,)`` and dtype ``float32``; pass to ``prior_transform`` to get physical parameters. """ u = kuma_logistic_icdf_vec(t, self.loc, self.scale, self.a, self.b) return u.astype(np.float32)
[docs] def log_jacobian(self, t): """Compute log-Jacobian. This is for the transform ``t -> u``, equal to the log-density of the KLP distribution at ``u = transform(t)``. Add this value to the true log-likelihood when passing to the nested sampler so that the sampler correctly targets the posterior. Parameters ---------- t : np.ndarray Nested-sampler unit-cube coordinates, shape ``(n_params,)``. Returns ------- log_q : float ``log q(u(t) | x_obs)`` -- always finite. """ u = self.transform(t) return kuma_logistic_logpdf_vec(u, self.loc, self.scale, self.a, self.b)
[docs] def cdf(self, u): """Evaluate the CDF. Parameters ---------- u : np.ndarray Prior unit-cube coordinates, shape ``(n_params,)``. Returns ------- t : np.ndarray Nested-sampler unit-cube coordinates corresponding to ``u``, shape ``(n_params,)``. """ return kuma_logistic_cdf_vec(u, self.loc, self.scale, self.a, self.b)
[docs] def logpdf(self, u): """Evaluate log-density. This is used by importance sampling to compute the log proposal density ``log q(u | x_obs)`` for each sample drawn from the NPE approximate posterior. Parameters ---------- u : np.ndarray Prior unit-cube coordinates, shape ``(n_params,)``. Returns ------- log_q : float Sum of log-densities across all dimensions, ``sum_i log q(u_i | x_obs)``. """ return kuma_logistic_logpdf_vec(u, self.loc, self.scale, self.a, self.b)