Source code for surmise.utilities

import warnings
import importlib


[docs] class sampler(object): def __init__(self, logpost_func, draw_func, sampler='metropolis_hastings', **sampler_options): ''' A class used to represent a sampler. .. tip:: To use a new sampler, just drop a new file to the ``utilitiesmethods/`` directory with the required formatting. The sampling methods under surmise can be returned within Python via: surmise.__utilitiesmethods__. Parameters ---------- logpostfunc : function A function call describing the log of the posterior distribution. draw_func : function A function returning a random sample from a prior distribution. sampler : str, optional A string indicating the sampling method to be used. It points to the script located in ``utilitiesmethods/``. The default is 'metropolis_hastings'. sampler_options : dict, optional Dictionary containing options to be passed to the sampler. The default is {}. ''' self.logpost_func = logpost_func self.draw_func = draw_func self.options = sampler_options self.sampler_info = {} self.draw_samples(sampler)
[docs] def draw_samples(self, sampler): ''' Calls "utilitiesmethods.[method].sampler" where [method] is the user option. sampler_info is a dictionary keeping the outputs from the sampler. sampler_info['theta'] is required and keeps the posterior draws to be used in the calibration. If additional outputs from a sampler are needed to be passed to the calibrator, those can also be kept in sampler_info. Parameters ---------- sampler_method : str Name of the sampler. Returns ------- None. ''' # Samplers that could be loaded, but that are research-grade only and # should not be offered through the public interface. # # TODO: This should be removed as part of refactoring the sampler # portion of the public interface (Issue #159). KEY = "expertMode" RESEARCH_SAMPLERS = ["lmc"] if sampler.lower() in RESEARCH_SAMPLERS: if (KEY not in self.options) or (not self.options[KEY]): msg = "{} is included for unofficial research purposes only" raise ValueError(msg.format(sampler)) else: # With the current implementation, expertMode=True could be # added to the calibration arguments with the intent of using a # research-grade calibrator but unintentionally allowing the use # of a research-grade sampler (or vice versa). The refactoring # will hopefully avoid this ambiguity. # # Emit warning to extend a helping hand to the experts. msg = f"Using unofficial research {sampler} sampler" warnings.warn(msg) self.method = importlib.import_module('surmise.utilitiesmethods.' + sampler) # update sampler_info with the output of the sampler self.sampler_info = self.method.sampler(self.logpost_func, self.draw_func, **self.options) if 'theta' not in self.sampler_info.keys(): raise ValueError('A sample from a posterior distribution is required.')