Source code for romtools.workflows.parameters

import abc
import numpy as np
from scipy.stats import qmc
from scipy.stats import norm
from scipy.stats import triang
from scipy.stats import rv_continuous

[docs] class Parameter(abc.ABC): '''Abstract implementation'''
[docs] @abc.abstractmethod def get_name(self) -> str: ''' Returns parameter name '''
[docs] @abc.abstractmethod def get_dimensionality(self) -> int: ''' Returns dimensionality of parameter for vector quantities. Returns 1 for scalar parameters '''
[docs] @abc.abstractmethod def scale_samples(self, uniform_dist_samples) -> np.array: ''' Generates samples from the desired distribution given a set of samples from a uniform distribution on (0,1) uniform_dist_samples should be of shape (number_of_samples, self.get_dimensionality()) Returns np.array of the same shape '''
########################################## # Concrete Parameter Classes ##########################################
[docs] class UniformParameter(Parameter): ''' Uniformly distributed floating point ''' def __init__(self, parameter_name: str, lower_bound: float = 0, upper_bound: float = 1): self._parameter_name = parameter_name try: assert len(lower_bound) == len(upper_bound) self._dimension = len(lower_bound) except TypeError: self._dimension = 1 self._lower_bound = lower_bound self._upper_bound = upper_bound
[docs] def get_name(self) -> str: return self._parameter_name
[docs] def get_dimensionality(self) -> int: return self._dimension
[docs] def scale_samples(self, uniform_dist_samples: np.array) -> np.array: assert uniform_dist_samples.shape[1] == self.get_dimensionality() return qmc.scale(uniform_dist_samples, self._lower_bound, self._upper_bound)
[docs] class StringParameter(Parameter): ''' Constant string-valued parameter ''' def __init__(self, parameter_name: str, value): self._parameter_name = parameter_name self._parameter_value = value
[docs] def get_name(self) -> str: return self._parameter_name
[docs] def get_dimensionality(self) -> int: return 1
[docs] def scale_samples(self, uniform_dist_samples: np.array) -> np.array: assert uniform_dist_samples.shape[1] == self.get_dimensionality() number_of_samples = uniform_dist_samples.shape[0] return np.array([[self._parameter_value]] * number_of_samples)
[docs] class GaussianParameter(Parameter): ''' Normally distributed parameter ''' def __init__(self, parameter_name: str, mean: float = 0, std: float = 1): self._parameter_name = parameter_name try: assert len(mean) == len(std) self._dimension = len(mean) except TypeError: self._dimension = 1 self._mean = mean self._std = std
[docs] def get_name(self) -> str: return self._parameter_name
[docs] def get_dimensionality(self) -> int: return self._dimension
[docs] def scale_samples(self, uniform_dist_samples: np.array) -> np.array: assert uniform_dist_samples.shape[1] == self.get_dimensionality() return norm.ppf(uniform_dist_samples, loc=self._mean, scale=self._std)
[docs] class TriangularParameter(Parameter): ''' Random parameter with a triangular distribution ''' def __init__(self, parameter_name: str, lower_bound: float = -1, peak: float = 0, upper_bound: float = 1): self._parameter_name = parameter_name try: assert len(lower_bound) == len(peak) assert len(lower_bound) == len(upper_bound) self._dimension = len(lower_bound) except TypeError: self._dimension = 1 self._loc = lower_bound self._scale = np.array(upper_bound) - np.array(lower_bound) self._c = (np.array(peak) - np.array(lower_bound))/(self._scale)
[docs] def get_name(self) -> str: return self._parameter_name
[docs] def get_dimensionality(self) -> int: return self._dimension
[docs] def scale_samples(self, uniform_dist_samples: np.array) -> np.array: assert uniform_dist_samples.shape[1] == self.get_dimensionality() return triang.ppf(uniform_dist_samples, loc=self._loc, scale=self._scale, c=self._c)
[docs] class ScipyDistributionParameter(Parameter): ''' Random parameter with distribution described by a scipy.stats.rv_continuous object ''' def __init__(self, parameter_name: str, distribution: rv_continuous, **kwargs): self._parameter_name = parameter_name self._dist_obj = distribution self._kwargs = kwargs try: self._dimension = len(kwargs['loc']) except TypeError: self._dimension = 1
[docs] def get_name(self) -> str: return self._parameter_name
[docs] def get_dimensionality(self) -> int: return self._dimension
[docs] def scale_samples(self, uniform_dist_samples: np.array) -> np.array: assert uniform_dist_samples.shape[1] == self.get_dimensionality() return self._dist_obj.ppf(uniform_dist_samples, **self._kwargs)