Source code for cuqi.legacy.sampler._conjugate_approx

from cuqi.distribution import Posterior, LMRF, Gamma
import numpy as np
import scipy as sp

[docs] class ConjugateApprox: # TODO: Subclass from Sampler once updated """ Approximate Conjugate sampler Sampler for sampling a posterior distribution where the likelihood and prior can be approximated by a conjugate pair. Currently supported pairs are: - (LMRF, Gamma): Approximated by (Gaussian, Gamma) For more information on conjugate pairs, see https://en.wikipedia.org/wiki/Conjugate_prior. """
[docs] def __init__(self, target: Posterior): if not isinstance(target.likelihood.distribution, LMRF): raise ValueError("Conjugate sampler only works with Laplace diff likelihood function") if not isinstance(target.prior, Gamma): raise ValueError("Conjugate sampler only works with Gamma prior") self.target = target
[docs] def step(self, x=None): # Extract variables # Here we approximate the Laplace diff with a Gaussian # Extract diff_op from target likelihood D = self.target.likelihood.distribution._diff_op n = D.shape[0] # Gaussian approximation of LMRF prior as function of x_k # See Uribe et al. (2022) for details # Current has a zero mean assumption on likelihood! TODO beta=1e-5 def Lk_fun(x_k): dd = 1/np.sqrt((D @ x_k)**2 + beta*np.ones(n)) W = sp.sparse.diags(dd) return W.sqrt() @ D x = self.target.likelihood.data #x d = len(x) #d Lx = Lk_fun(x)@x #Lx alpha = self.target.prior.shape #alpha beta = self.target.prior.rate #beta # Create Gamma distribution and sample dist = Gamma(shape=d+alpha, rate=np.linalg.norm(Lx)**2+beta) return dist.sample()