from random import gauss, weibullvariate, uniform
from openmdao.main.interfaces import IUncertainVariable, implements
try:
# as of python2.7, gamma is in the math module (even though docs say it's new as of 3.2)
from math import gamma
except ImportError as err:
import logging
logging.warn("In %s: %r" % (__file__, err))
try:
from scipy.special import gamma
except ImportError as err:
logging.warn("In %s: %r" % (__file__, err))
from openmdao.util.decorators import stub_if_missing_deps
class UncertainDistribution(object):
[docs] """Base class for uncertain variables."""
implements(IUncertainVariable)
default_val_method = 'expected'
def __init__(self, valmethod=None):
self.valmethod = valmethod
def getvalue(self):
[docs] if self.valmethod:
return getattr(self, self.valmethod)()
return getattr(self, self.default_val_method)()
def sample(self):
[docs] raise NotImplementedError('The %s class has no sample() method' % self.__class__.__name__)
def expected(self):
[docs] raise NotImplementedError('The %s class has no expected() method' % self.__class__.__name__)
class NormalDistribution(UncertainDistribution):
[docs] """An UncertainDistribution which represents a quantity with a
normal distribution of uncertainty.
mu: float
mean value
sigma: float
standard deviation
"""
def __init__(self,mu=0., sigma=1.):
super(NormalDistribution,self).__init__()
self.mu = mu
self.sigma = sigma
def sample(self):
[docs] return gauss(self.mu,self.sigma)
def expected(self):
[docs] return self.mu
def __add__(self,other):
return NormalDistribution(mu = self.mu + other, sigma = self.sigma)
def __sub__(self,other):
return NormalDistribution(mu = self.mu - other, sigma = self.sigma)
def __str__(self):
return "NormalDistribution(mu=%s,sigma=%s)"%(self.mu,self.sigma)
#def _adapt_norm_dist(nd):
#return "%f;%f"%(nd.mu,nd.sigma)
#def _convert_norm_dist(nd):
#mu,sigma = map(float, nd.split(';'))
#return NormalDistribution(mu,sigma)
##register the adapter
#sqlite3.register_adapter(NormalDistribution, _adapt_norm_dist)
##register the converter
#sqlite3.register_converter("NormalDistribution", _convert_norm_dist)
class UniformDistribution(UncertainDistribution):
[docs] """An UncertainDistribution which represents a quantity with a
triangular distribution of uncertainty.
min: float
minimum value
max: float
maximum value
mode: float
mode
"""
def __init__(self,max=0.,min=1.,mode=0.5,*args,**kwargs):
super(TriangularDistribution,self).__init__(*args,**kwargs)
self.max = max
self.min = min
self.mode = mode
def sample(self):
[docs] return triangular(self.min,self.max,self.mode)
def expected(self):
[docs] return (self.max+self.mode+self.min)/3.
class WeibullDistribution(UncertainDistribution):
[docs] """An UncertainDistribution which represents a quantity with a
Weibull distribution of uncertainty.
alpha: float
scale parameter
beta: float
shape parameter
"""
def __init__(self,alpha=1.,beta=2.,*args,**kwargs):
super(UniformDistribution,self).__init__(*args,**kwargs)
self.alpha = alpha
self.beta = beta
def sample(self):
[docs] return weibullvariate(self.alpha, self.beta)
def expected(self):
[docs] return self.alpha*gamma(1.+1./self.beta)
if 'gamma' not in globals():
WeibullDistribution = stub_if_missing_deps('scipy', 'math:gamma')(WeibullDistribution)