Source code for chaospy.distributions.collection.beta

"""Beta distribution."""
import numpy
from scipy import special
import chaospy

from ..baseclass import (
    SimpleDistribution,
    LowerUpperDistribution,
    ShiftScaleDistribution,
)


class beta_(SimpleDistribution):
    def __init__(self, a=1, b=1):
        super(beta_, self).__init__(dict(a=a, b=b))

    def _pdf(self, x, a, b):
        out = x ** (a - 1) * (1 - x) ** (b - 1) / special.beta(a, b)
        out = numpy.where(numpy.isfinite(out), out, 0)
        return out

    def _cdf(self, x, a, b):
        return special.btdtr(a, b, x)

    def _ppf(self, qloc, a, b):
        return special.btdtri(a, b, qloc)

    def _mom(self, k, a, b):
        return special.beta(a + k, b) / special.beta(a, b)

    def _ttr(self, n, a, b):
        nab = 2 * n + a + b
        A = ((a - 1) ** 2 - (b - 1) ** 2) * 0.5 / (
            nab * (nab - 2) + (nab == 0) + (nab == 2)
        ) + 0.5
        B1 = a * b * 1.0 / ((a + b + 1) * (a + b) ** 2)
        B2 = (
            (n + a - 1)
            * (n + b - 1)
            * n
            * (n + a + b - 2.0)
            / ((nab - 1) * (nab - 3) * (nab - 2) ** 2 + 2.0 * ((n == 0) + (n == 1)))
        )
        B = numpy.where((n == 0) + (n == 1), B1, B2)
        return A, B

    def _lower(self, a, b):
        return 0.0

    def _upper(self, a, b):
        return 1.0


[docs]class Beta(LowerUpperDistribution): R""" Beta Probability Distribution. Args: alpha (float, Distribution): First shape parameter, alpha > 0 beta (float, Distribution): Second shape parameter, b > 0 lower (float, Distribution): Lower threshold upper (float, Distribution): Upper threshold Examples: >>> distribution = chaospy.Beta(1.5, 3.5) >>> distribution Beta(1.5, 3.5) >>> uloc = numpy.linspace(0, 1, 6) >>> uloc array([0. , 0.2, 0.4, 0.6, 0.8, 1. ]) >>> xloc = distribution.inv(uloc) >>> xloc.round(3) array([0. , 0.126, 0.222, 0.326, 0.464, 1. ]) >>> numpy.allclose(distribution.fwd(xloc), uloc) True >>> distribution.pdf(xloc).round(3) array([0. , 2.066, 2.051, 1.734, 1.168, 0. ]) >>> distribution.sample(4).round(3) array([0.358, 0.083, 0.651, 0.263]) >>> distribution.mom(1).round(4) 0.3 >>> distribution.ttr([0, 1, 2, 3]).round(4) array([[0.3 , 0.4143, 0.4524, 0.4697], [0.035 , 0.035 , 0.0478, 0.0535]]) """
[docs] def __init__(self, alpha, beta, lower=0, upper=1): super(Beta, self).__init__( dist=beta_(alpha, beta), lower=lower, upper=upper, repr_args=[alpha, beta], )
[docs]class ArcSinus(LowerUpperDistribution): """ Generalized Arc-sinus distribution Args: shape (float, Distribution): Shape parameter where 0.5 is the default non-generalized case. Defined on the interval ``[0, 1]``. lower (float, Distribution): Lower threshold upper (float, Distribution): Upper threshold Examples: >>> distribution = chaospy.ArcSinus(0.5) >>> distribution ArcSinus(0.5) >>> uloc = numpy.linspace(0, 1, 6) >>> uloc array([0. , 0.2, 0.4, 0.6, 0.8, 1. ]) >>> xloc = distribution.inv(uloc) >>> xloc.round(3) array([0. , 0.095, 0.345, 0.655, 0.905, 1. ]) >>> numpy.allclose(distribution.fwd(xloc), uloc) True >>> distribution.pdf(xloc).round(3) array([0. , 1.083, 0.669, 0.669, 1.083, 0. ]) >>> distribution.sample(4).round(3) array([0.732, 0.032, 0.994, 0.472]) >>> distribution.mom(1).round(4) 0.5 >>> distribution.ttr([0, 1, 2, 3]).round(4) array([[0.5 , 0.5 , 0.5 , 0.5 ], [0.125 , 0.125 , 0.0625, 0.0625]]) """
[docs] def __init__(self, shape=0.5, lower=0, upper=1): super(ArcSinus, self).__init__( dist=beta_(shape, 1 - shape), lower=lower, upper=upper, repr_args=[shape], )
[docs]class PowerLaw(LowerUpperDistribution): """ Powerlaw distribution Args: shape (float, Distribution): Shape parameter lower (float, Distribution): Location of lower threshold upper (float, Distribution): Location of upper threshold Examples: >>> distribution = chaospy.PowerLaw(0.8) >>> distribution PowerLaw(0.8) >>> uloc = numpy.linspace(0, 1, 6) >>> uloc array([0. , 0.2, 0.4, 0.6, 0.8, 1. ]) >>> xloc = distribution.inv(uloc) >>> xloc.round(3) array([0. , 0.134, 0.318, 0.528, 0.757, 1. ]) >>> numpy.allclose(distribution.fwd(xloc), uloc) True >>> distribution.pdf(xloc).round(3) array([0. , 1.196, 1.006, 0.909, 0.846, 0.8 ]) >>> distribution.sample(4).round(3) array([0.588, 0.067, 0.938, 0.402]) >>> distribution.mom(1).round(4) 0.4444 >>> distribution.ttr([0, 1, 2, 3]).round(4) array([[0.4444, 0.5029, 0.5009, 0.5004], [0.0882, 0.0882, 0.0668, 0.0643]]) """
[docs] def __init__(self, shape=1, lower=0, upper=1): super(PowerLaw, self).__init__( dist=beta_(shape, 1), lower=lower, upper=upper, repr_args=[shape], )
[docs]class Wigner(ShiftScaleDistribution): """ Wigner (semi-circle) distribution Args: radius (float, Distribution): Radius of the semi-circle (scale) shift (float, Distribution): Location of the circle origin (location) Examples: >>> distribution = chaospy.Wigner(1.5) >>> distribution Wigner(1.5) >>> uloc = numpy.linspace(0, 1, 6) >>> uloc array([0. , 0.2, 0.4, 0.6, 0.8, 1. ]) >>> xloc = distribution.inv(uloc) >>> xloc.round(3) array([-1.5 , -0.738, -0.237, 0.237, 0.738, 1.5 ]) >>> numpy.allclose(distribution.fwd(xloc), uloc) True >>> distribution.pdf(xloc).round(3) array([0. , 0.37 , 0.419, 0.419, 0.37 , 0. ]) >>> distribution.sample(4).round(3) array([ 0.366, -0.983, 1.209, -0.042]) >>> distribution.mom(1).round(4) 0.0 >>> distribution.ttr([0, 1, 2, 3]).round(4) array([[0. , 0. , 0. , 0. ], [0.5625, 0.5625, 0.5625, 0.5625]]) """
[docs] def __init__(self, radius=1, shift=0): super(Wigner, self).__init__( dist=beta_(1.5, 1.5), scale=2 * radius, shift=shift - radius ) self._repr_args = [radius] + chaospy.format_repr_kwargs(shift=(shift, 0))
[docs]class PERT(Beta): r""" Program Evaluation and Review Technique (PERT) Distribution. Defined by its mean:: \mu = \frac{lower + gamma*mode + upper}{2 + gamma} Normal PERT for `gamma=4`. Other values results in the so called modified-PERT distribution. Args: lower (float): The lower bounds for the distribution. mode (float, Distribution): The mode of the distribution. upper (float): The upper bounds for the distribution. gamma (flat, Distribution): Modify the PERT distribution to make more emphasis on the distribution mode instead of the distribution tails. Examples: >>> distribution = chaospy.PERT(-1, 0, 1) >>> distribution PERT(-1, 0, 1) >>> uloc = numpy.linspace(0, 1, 6) >>> uloc array([0. , 0.2, 0.4, 0.6, 0.8, 1. ]) >>> xloc = distribution.inv(uloc) >>> xloc.round(3) array([-1. , -0.347, -0.107, 0.107, 0.347, 1. ]) >>> numpy.allclose(distribution.fwd(xloc), uloc) True >>> distribution.pdf(xloc).round(3) array([0. , 0.726, 0.916, 0.916, 0.726, 0. ]) >>> distribution.sample(4).round(3) array([ 0.167, -0.479, 0.622, -0.019]) >>> distribution.mom(1).round(4) 0.0 >>> distribution.ttr([0, 1, 2, 3]).round(4) array([[0. , 0. , 0. , 0. ], [0.1429, 0.1429, 0.1905, 0.2121]]) """
[docs] def __init__(self, lower, mode, upper, gamma=4): mu = (lower + 4 * mode + upper) / 6.0 alpha = 1 + gamma * (mu - lower) / (upper - lower) beta = 1 + gamma * (upper - mu) / (upper - lower) LowerUpperDistribution.__init__( self, dist=beta_(alpha, beta), lower=lower, upper=upper, ) self._repr_args = [lower, mode, upper] self._repr_args += chaospy.format_repr_kwargs(gamma=(gamma, 4))