Source code for chaospy.distributions.collection.triangle

"""Triangle probability distribution."""
import numpy
from scipy import special, misc

from ..baseclass import SimpleDistribution, LowerUpperDistribution
from .beta import beta_


def _get_triang_param_lb_and_ub(name, value):
    try:
        lb = ub = float(value)
    except:
        if hasattr(value, "lower") and hasattr(value, "upper"):
            lb = value.lower.min()
            ub = value.upper.max()
        else:
            raise ValueError(
                "%s must be either a number or a distribution " % name
                + "with lower and upper bounds; not a '%s' " % type(value).__name__
                + "object"
            )
    return lb, ub


class triangle(SimpleDistribution):
    """Triangle probability distribution."""

    def __init__(self, a=0.5):
        # assert numpy.all(a>=0) and numpy.all(a<=1)
        super(triangle, self).__init__(dict(a=a))

    def _pdf(self, xloc, a):
        return numpy.where(xloc < a, 2 * xloc / a, 2 * (1 - xloc) / (1 - a))

    def _cdf(self, xloc, a):
        return numpy.where(
            xloc < a,
            xloc**2 / (a + (a == 0)),
            (2 * xloc - xloc * xloc - a) / (1 - a + (a == 1)),
        )

    def _ppf(self, qloc, a):
        return numpy.where(
            qloc < a, numpy.sqrt(qloc * a), 1 - numpy.sqrt(1 - a - qloc * (1 - a))
        )

    def _mom(self, k, a):
        a_ = a * (a != 1)
        out = 2 * (1.0 - a_ ** (k + 1)) / ((k + 1) * (k + 2) * (1 - a_))
        return numpy.where(a == 1, 2.0 / (k + 2), out)

    def _lower(self, a):
        return 0.0

    def _upper(self, a):
        return 1.0


[docs]class Triangle(LowerUpperDistribution): """ Triangle Distribution. Must have lower <= midpoint <= upper. Args: lower (float, Distribution): Lower bound midpoint (float, Distribution): Location of the top upper (float, Distribution): Upper bound Examples: >>> distribution = chaospy.Triangle(-1, 0 ,1) >>> distribution Triangle(-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.368, -0.106, 0.106, 0.368, 1. ]) >>> numpy.allclose(distribution.fwd(xloc), uloc) True >>> distribution.pdf(xloc).round(3) array([0. , 0.632, 0.894, 0.894, 0.632, 0. ]) >>> distribution.sample(4).round(3) array([ 0.168, -0.52 , 0.685, -0.018]) >>> distribution.mom(1).round(4) 0.0 >>> distribution = chaospy.Triangle(-1, 2 ,1) Traceback (most recent call last): ValueError: condition not satisfied: `lower <= midpoint <= upper` """
[docs] def __init__(self, lower=-1, midpoint=0, upper=1): repr_args = [lower, midpoint, upper] _, lower_ub = _get_triang_param_lb_and_ub("lower", lower) mid_lb, mid_ub = _get_triang_param_lb_and_ub("midpoint", midpoint) upper_lb, _ = _get_triang_param_lb_and_ub("upper", upper) if not (lower_ub <= mid_lb and mid_ub <= upper_lb): raise ValueError("condition not satisfied: `lower <= midpoint <= upper`") midpoint = (midpoint - lower) * 1.0 / (upper - lower) super(Triangle, self).__init__( dist=triangle(midpoint), lower=lower, upper=upper, ) self._repr_args = repr_args