Source code for rexfw.statistics.logged_quantities

'''
Logable (?) quantities
'''

from collections import OrderedDict


[docs]class LoggedQuantity(object): def __init__(self, origins, stats_fields, name, variable_name=None): ''' Base class representing sampling quantities which can be tracked by :class:`.Statistics` instances and written by :class:`.AbstractStatisticsWriter` instances :param origins: list of object (mostly, replica) names which give rise to this quantity; e.g., replica1 and replica2 for the acceptance rate for swaps between those two replicas :type origins: list of str :param stats_fields: the attribute names that will be looked up in small sampling statistics objects to calculate the value of the quantity :type stats_fields: list of str :param str name: the name of the logged quantity, e.g., 'accepance rate' :param str variable_name: the name of the sampled variable associated with this quantity ''' self._values = OrderedDict() self._default_value = None self.step = None self.origins = origins self.stats_fields = stats_fields self.name = name self.variable_name = variable_name def __getitem__(self, step): ''' Gets the value for the logged quantity for a given step :return: a value of the logged quantity :rtype: depends on the quantity ''' return self.values[str(step)] if step != -1 else self.current_value @property def values(self): ''' Returns all stored values of the logged quantity ''' return self._values @property def current_value(self): ''' Returns the current (last) value of the logged quantity ''' if len(self.values) > 0: return self.values[next(reversed(self.values))] else: return self._default_value
[docs] def _get_value(self, stats): ''' Retrieves a value for the logged quantity from a small sampling statistics object :param stats: dict of the form {variable_name: SamplingStats} :type stats: dict ''' pass
[docs] def update(self, step, stats): ''' Stores sampling statistics for a given step :param int step: the sampling step during which the statistics in stats where created :param stats: dict of the form {variable_name: SamplingStats} :type stats: dict ''' self._values.update(**{str(step): self._get_value(stats)})
[docs]class SamplerStepsize(LoggedQuantity): def __init__(self, replica, variable_name): ''' Logged quantity which tracks MCMC sampler step sizes :param str replica: the name of the replica in which the sampler with these step sizes lives :param str variable_name: the name of the sampling variable associated with the step size ''' super(SamplerStepsize, self).__init__([replica], ['stepsize'], 'stepsize', variable_name)
[docs] def _get_value(self, stats): return stats[self.variable_name].stepsize
def __repr__(self): return '{} {} {}: {}'.format(self.origins[0], self.variable_name, self.name,self.current_value)
[docs]class REWorks(LoggedQuantity): def __init__(self, replica1, replica2): ''' Keeps track of works expended during replica exchange swap trajectories :param str replica1: name of first involved replica :param str replica2: name of second involved replica ''' import numpy super(REWorks, self).__init__([replica1, replica2], ['works'], 'works') self._default_value = numpy.array([0.0,0.0])
[docs] def _get_value(self, stats): return stats.works
def __repr__(self): return '{} {} <> {}: {}'.format(self.name, self.origins[0], self.origins[1], self.current_value)
[docs]class REHeats(LoggedQuantity): def __init__(self, replica1, replica2): ''' Keeps track of heats produced during replica exchange swap trajectories :param str replica1: name of first involved replica :param str replica2: name of second involved replica ''' import numpy super(REHeats, self).__init__([replica1, replica2], ['heats'], 'heats') self._default_value = numpy.array([0.0,0.0])
[docs] def _get_value(self, stats): return stats.heats
def __repr__(self): return '{} {} <> {}: {}'.format(self.name, self.origins[0], self.origins[1], self.current_value)