Source code for desilike.samplers.importance

"""Module implementing an importance sampler."""

import numpy as np
from scipy.special import logsumexp

from .base import StaticSampler


[docs] class ImportanceSampler(StaticSampler): """An importance sampler. This class can be used to transform samples from one posterior to another. Alternatively, it can also be used to combine likelihoods from two experiments. """
[docs] def get_samples(self, samples=None): """Get samples on the grid. Parameters ---------- chain : desilike.samples.Chain, optional Input chain that defines the samples. Returns ------- numpy.ndarray of shape (n_samples, n_dim) Grid to be evaluated. """ return np.column_stack([ samples[key].value for key in self.varied_params])
[docs] def run(self, samples, resample=True): """Reweight a sample using importance sampling. Parameters ---------- samples : desilike.samples.Chain Input samples with a corresponding posterior. resample : bool, optional If True, the new weights for the chain will be the ratio of the new and old posterior. Effectively, the new chain will sample the new posterior. If False, the new weights are the product of the old posterior and the new likelihood. Default is True. Returns ------- desilike.samples.Chain Sampler results. """ results = super().run(samples=samples) if resample: log_w = results.logposterior - samples.logposterior else: log_w = (results.logposterior - results[results._logprior] + samples.logposterior) results.aweight = np.exp(log_w - logsumexp(log_w)) return results