Source code for spux.distributions.tensor

# # # # # # # # # # # # # # # # # # # # # # # # # #
# Wrapper class for tensorizing distributions from scipy.stats
# For a review of wrap'able distributions, see the list of univariate distributions at:
# https://docs.scipy.org/doc/scipy/reference/stats.html
#
# Jonas Sukys
# Eawag, Switzerland
# jonas.sukys@eawag.ch
# All rights reserved.
# # # # # # # # # # # # # # # # # # # # # # # # # #

import numpy
import pandas

from .distribution import Distribution
from spux.utils.transforms import rounding

[docs]class Tensor (Distribution): def __init__ (self, distributions, types_of_keys=None): self.distributions = distributions self.labels = list (distributions.keys ()) self.types = {} for key in distributions: if types_of_keys is not None: if key not in types_of_keys: raise ValueError("Fatal. Specified parameter is not in the list.") self.types [key] = types_of_keys [key] if types_of_keys[key][0:3].lower() == 'int' or types_of_keys[key].lower() == 'binary': distributions [key].pdf = rounding (distributions [key].pmf) distributions [key].logpdf = rounding (distributions [key].logpmf) else: self.types [key] = 'float' # evaluate a joint PDF of the tensorized random variables # 'parameters' is assumed to be of a pandas.Series type
[docs] def pdf (self, parameters): """Evaluate the (joint) prob. distr. function of the tensorized, i.e. assuming independence, random variables 'parameters'. 'parameters' are assumed to be of a pandas.Series type """ pdfs = [ self.distributions [label] .pdf (parameter) for label, parameter in parameters.items () if not numpy.isnan (parameter) ] return numpy.prod (pdfs) if len (pdfs) > 0 else 0
# evaluate a joint log-PDF of the tensorized random variables # 'parameters' is assumed to be of a pandas.Series type
[docs] def logpdf (self, parameters): """Evaluate the logarithm of the (joint) prob. distr. function of the tensorized, i.e. assuming independence, random variables 'parameters'. 'parameters' are assumed to be of a pandas.Series type """ logpdfs = [ self.distributions [label] .logpdf (parameter) for label, parameter in parameters.items () if not numpy.isnan (parameter) ] return numpy.sum (logpdfs) if len (logpdfs) > 0 else float ('-inf')
# return marginal PDF for the specified parameter
[docs] def mpdf (self, label, parameter): """Return marginal PDF for the specified parameter.""" return self.distributions [label] .pdf (parameter)
# return marginal log-PDF for the specified parameter
[docs] def logmpdf (self, label, parameter): """Return marginal log-PDF for the specified parameter.""" return self.distributions [label] .logpdf (parameter)
# return intervals for the specified centered probability mass
[docs] def intervals (self, alpha=0.99): """Return intervals for the specified centered probability mass.""" intervals = { label : list (distribution.interval (alpha)) for label, distribution in self.distributions.items () } return intervals
# draw a random vector using the provided random state 'rng'
[docs] def draw (self, rng): """Draw a random vector using the provided random state 'rng'. """ parameters = { label : distribution.rvs (random_state = rng) for label, distribution in self.distributions.items () } return pandas.Series (parameters)