Problem
Defines the Bayesian inference problem by wrapping the prior and likelihood as plain Python callables.
import mcmckit as mc
problem = mc.Problem(
prior=log_prior,
likelihood=log_likelihood,
param_names=["E", "zeta"],
grad_log_likelihood=grad_ll, # optional, required for MALA
grad_log_prior=grad_lp, # optional, required for MALA
)
Problem
Encapsulates a Bayesian inference problem.
Parameters:
| Name |
Type |
Description |
Default |
prior
|
callable
|
Function theta -> log p(theta). Must return a scalar float.
|
required
|
likelihood
|
callable
|
Function theta -> log p(y | theta). Must return a scalar float.
|
required
|
bounds
|
list of (lo, hi) tuples
|
Hard parameter bounds. Any theta outside bounds returns -inf
without evaluating the prior or likelihood.
|
None
|
param_names
|
list of str
|
Names for each parameter dimension. Used in Result plots/summaries.
|
None
|
grad_log_likelihood
|
callable
|
Function theta -> gradient of log p(y | theta). Returns array of
shape (d,). Used by gradient-based samplers (MALA, HMC). Standard
MH ignores this entirely.
|
None
|
grad_log_prior
|
callable
|
Function theta -> gradient of log p(theta). Returns array of
shape (d,). Used by gradient-based samplers together with
grad_log_likelihood to form the full log-posterior gradient.
|
None
|
Source code in mcmckit/core/problem.py
| class Problem:
"""Encapsulates a Bayesian inference problem.
Parameters
----------
prior : callable
Function theta -> log p(theta). Must return a scalar float.
likelihood : callable
Function theta -> log p(y | theta). Must return a scalar float.
bounds : list of (lo, hi) tuples, optional
Hard parameter bounds. Any theta outside bounds returns -inf
without evaluating the prior or likelihood.
param_names : list of str, optional
Names for each parameter dimension. Used in Result plots/summaries.
grad_log_likelihood : callable, optional
Function theta -> gradient of log p(y | theta). Returns array of
shape (d,). Used by gradient-based samplers (MALA, HMC). Standard
MH ignores this entirely.
grad_log_prior : callable, optional
Function theta -> gradient of log p(theta). Returns array of
shape (d,). Used by gradient-based samplers together with
grad_log_likelihood to form the full log-posterior gradient.
"""
def __init__(
self,
prior,
likelihood,
bounds=None,
param_names=None,
grad_log_likelihood=None,
grad_log_prior=None,
):
self.prior = prior
self.likelihood = likelihood
self.bounds = bounds
self.param_names = param_names
self.grad_log_likelihood = grad_log_likelihood
self.grad_log_prior = grad_log_prior
# ------------------------------------------------------------------
# Core evaluations
# ------------------------------------------------------------------
def log_prior(self, theta):
if self.bounds is not None:
for val, (lo, hi) in zip(theta, self.bounds):
if not (lo <= val <= hi):
return -np.inf
return float(self.prior(theta))
def log_likelihood(self, theta):
return float(self.likelihood(theta))
def log_posterior(self, theta):
lp = self.log_prior(theta)
if not np.isfinite(lp):
return lp
return lp + self.log_likelihood(theta)
# ------------------------------------------------------------------
# Gradient evaluations (only available when callables are provided)
# ------------------------------------------------------------------
@property
def has_grad(self):
"""True if gradients of both prior and likelihood are available."""
return self.grad_log_likelihood is not None and self.grad_log_prior is not None
def grad_log_posterior(self, theta):
"""Gradient of log p(theta | y). Requires has_grad == True."""
if not self.has_grad:
raise RuntimeError(
"Gradient requested but grad_log_likelihood / grad_log_prior "
"were not provided to Problem."
)
return np.asarray(self.grad_log_prior(theta)) + np.asarray(self.grad_log_likelihood(theta))
def log_posterior_and_grad(self, theta):
"""Return (log_posterior, gradient) in a single call."""
return self.log_posterior(theta), self.grad_log_posterior(theta)
|
Attributes
has_grad
property
True if gradients of both prior and likelihood are available.
Methods:
grad_log_posterior
grad_log_posterior(theta)
Gradient of log p(theta | y). Requires has_grad == True.
Source code in mcmckit/core/problem.py
| def grad_log_posterior(self, theta):
"""Gradient of log p(theta | y). Requires has_grad == True."""
if not self.has_grad:
raise RuntimeError(
"Gradient requested but grad_log_likelihood / grad_log_prior "
"were not provided to Problem."
)
return np.asarray(self.grad_log_prior(theta)) + np.asarray(self.grad_log_likelihood(theta))
|
log_posterior_and_grad
log_posterior_and_grad(theta)
Return (log_posterior, gradient) in a single call.
Source code in mcmckit/core/problem.py
| def log_posterior_and_grad(self, theta):
"""Return (log_posterior, gradient) in a single call."""
return self.log_posterior(theta), self.grad_log_posterior(theta)
|