Пример #1
0
def test_constant_expected():
    """Test if polynomial constant behave as expected."""
    distribution = chaospy.J(chaospy.Uniform(-1.2, 1.2),
                             chaospy.Uniform(-2.0, 2.0))
    const = chaospy.polynomial(7.)
    assert chaospy.E(const, distribution[0]) == const
    assert chaospy.E(const, distribution) == const
    assert chaospy.Var(const, distribution) == 0.
Пример #2
0
def orth_ttr(order,
             dist,
             normed=False,
             graded=True,
             reverse=True,
             retall=False,
             cross_truncation=1.,
             sort=None,
             **kws):
    """
    Create orthogonal polynomial expansion from three terms recursion formula.

    Args:
        order (int):
            Order of polynomial expansion.
        dist (Dist):
            Distribution space where polynomials are orthogonal If dist.ttr
            exists, it will be used. Must be stochastically independent.
        normed (bool):
            If True orthonormal polynomials will be used.
        graded (bool):
            Graded sorting, meaning the indices are always sorted by the index
            sum. E.g. ``q0**2*q1**2*q2**2`` has an exponent sum of 6, and will
            therefore be consider larger than both ``q0**2*q1*q2``,
            ``q0*q1**2*q2`` and ``q0*q1*q2**2``, which all have exponent sum of
            5.
        reverse (bool):
            Reverse lexicographical sorting meaning that ``q0*q1**3`` is
            considered bigger than ``q0**3*q1``, instead of the opposite.
        retall (bool):
            If true return numerical stabilized norms as well. Roughly the same
            as ``cp.E(orth**2, dist)``.
        cross_truncation (float):
            Use hyperbolic cross truncation scheme to reduce the number of
            terms in expansion. only include terms where the exponents ``K``
            satisfied the equation
            ``order >= sum(K**(1/cross_truncation))**cross_truncation``.

    Returns:
        (chaospy.poly.ndpoly, numpy.ndarray):
            Orthogonal polynomial expansion. Norms of the orthogonal
            expansion on the form ``E(orth**2, dist)``. Calculated using
            recurrence coefficients for stability.

    Examples:
        >>> distribution = chaospy.Normal()
        >>> expansion, norms = chaospy.orth_ttr(4, distribution, retall=True)
        >>> expansion.round(4)
        polynomial([1.0, q0, q0**2-1.0, q0**3-3.0*q0, q0**4-6.0*q0**2+3.0])
        >>> norms
        array([ 1.,  1.,  2.,  6., 24.])
    """
    logger = logging.getLogger(__name__)
    if sort is not None:
        logger.warning("deprecation warning: 'sort' argument is deprecated; "
                       "use 'graded' and/or 'reverse' instead")
        graded = "G" in sort.upper()
        reverse = "R" not in sort.upper()

    try:
        _, polynomials, norms, = chaospy.quadrature.recurrence.analytical_stieljes(
            numpy.max(order), dist, normed=normed)
    except NotImplementedError:
        abscissas, weights = chaospy.quadrature.generate_quadrature(
            int(10000**(1 / len(dist))), dist, rule="fejer")
        _, polynomials, norms, = chaospy.quadrature.recurrence.discretized_stieltjes(
            numpy.max(order), abscissas, weights, normed=normed)

    polynomials = polynomials.reshape((len(dist), numpy.max(order) + 1))

    order = numpy.array(order)
    indices = numpoly.glexindex(start=0,
                                stop=order + 1,
                                dimensions=len(dist),
                                graded=graded,
                                reverse=reverse,
                                cross_truncation=cross_truncation)
    if len(dist) > 1:
        polynomials = chaospy.poly.prod(
            chaospy.polynomial(
                [poly[idx] for poly, idx in zip(polynomials, indices.T)]), 0)
        norms = numpy.prod(
            [norms_[idx] for norms_, idx in zip(norms, indices.T)], 0)
    else:
        polynomials = polynomials.flatten()
        norms = norms.flatten()

    if retall:
        return polynomials, norms
    return polynomials
Пример #3
0
def orth_gs(order,
            dist,
            normed=False,
            graded=True,
            reverse=True,
            retall=False,
            cross_truncation=1.,
            **kws):
    """
    Gram-Schmidt process for generating orthogonal polynomials.

    Args:
        order (int, numpoly.ndpoly):
            The upper polynomial order. Alternative a custom polynomial basis
            can be used.
        dist (Dist):
            Weighting distribution(s) defining orthogonality.
        normed (bool):
            If True orthonormal polynomials will be used instead of monic.
        graded (bool):
            Graded sorting, meaning the indices are always sorted by the index
            sum. E.g. ``q0**2*q1**2*q2**2`` has an exponent sum of 6, and will
            therefore be consider larger than both ``q0**2*q1*q2``,
            ``q0*q1**2*q2`` and ``q0*q1*q2**2``, which all have exponent sum of
            5.
        reverse (bool):
            Reverse lexicographical sorting meaning that ``q0*q1**3`` is
            considered bigger than ``q0**3*q1``, instead of the opposite.
        retall (bool):
            If true return numerical stabilized norms as well. Roughly the same
            as ``cp.E(orth**2, dist)``.
        cross_truncation (float):
            Use hyperbolic cross truncation scheme to reduce the number of
            terms in expansion.

    Returns:
        (chapspy.poly.ndpoly):
            The orthogonal polynomial expansion.

    Examples:
        >>> distribution = chaospy.J(chaospy.Normal(), chaospy.Normal())
        >>> polynomials, norms = chaospy.orth_gs(2, distribution, retall=True)
        >>> polynomials.round(10)
        polynomial([1.0, q1, q0, q1**2-1.0, q0*q1, q0**2-1.0])
        >>> norms.round(10)
        array([1., 1., 1., 2., 1., 2.])
        >>> polynomials = chaospy.orth_gs(2, distribution, normed=True)
        >>> polynomials.round(3)
        polynomial([1.0, q1, q0, 0.707*q1**2-0.707, q0*q1, 0.707*q0**2-0.707])

    """
    logger = logging.getLogger(__name__)
    dim = len(dist)

    if isinstance(order, int):
        if order == 0:
            return numpoly.polynomial(1)
        basis = numpoly.monomial(
            0,
            order + 1,
            names=numpoly.variable(2).names,
            graded=graded,
            reverse=reverse,
            cross_truncation=cross_truncation,
        )
    else:
        basis = order

    basis = list(basis)

    polynomials = [basis[0]]

    norms = [1.]
    for idx in range(1, len(basis)):

        # orthogonalize polynomial:
        for idy in range(idx):
            orth = chaospy.E(basis[idx] * polynomials[idy], dist, **kws)
            basis[idx] = basis[idx] - polynomials[idy] * orth / norms[idy]

        norms_ = chaospy.E(basis[idx]**2, dist, **kws)
        if norms_ <= 0:
            logger.warning("Warning: Polynomial cutoff at term %d", idx)
            break

        norms.append(1. if normed else norms_)
        basis[idx] = basis[idx] / numpy.sqrt(norms_) if normed else basis[idx]
        polynomials.append(basis[idx])

    polynomials = chaospy.polynomial(polynomials).flatten()
    if retall:
        norms = numpy.array(norms)
        return polynomials, norms
    return polynomials
Пример #4
0
def orth_ttr(order,
             dist,
             normed=False,
             graded=True,
             reverse=True,
             retall=False,
             cross_truncation=1.):
    """
    Create orthogonal polynomial expansion from three terms recurrence formula.

    Args:
        order (int):
            Order of polynomial expansion.
        dist (Distribution):
            Distribution space where polynomials are orthogonal If dist.ttr
            exists, it will be used. Must be stochastically independent.
        normed (bool):
            If True orthonormal polynomials will be used.
        graded (bool):
            Graded sorting, meaning the indices are always sorted by the index
            sum. E.g. ``q0**2*q1**2*q2**2`` has an exponent sum of 6, and will
            therefore be consider larger than both ``q0**2*q1*q2``,
            ``q0*q1**2*q2`` and ``q0*q1*q2**2``, which all have exponent sum of
            5.
        reverse (bool):
            Reverse lexicographical sorting meaning that ``q0*q1**3`` is
            considered bigger than ``q0**3*q1``, instead of the opposite.
        retall (bool):
            If true return numerical stabilized norms as well. Roughly the same
            as ``cp.E(orth**2, dist)``.
        cross_truncation (float):
            Use hyperbolic cross truncation scheme to reduce the number of
            terms in expansion. only include terms where the exponents ``K``
            satisfied the equation
            ``order >= sum(K**(1/cross_truncation))**cross_truncation``.

    Returns:
        (numpoly.ndpoly, numpy.ndarray):
            Orthogonal polynomial expansion. Norms of the orthogonal
            expansion on the form ``E(orth**2, dist)``. Calculated using
            recurrence coefficients for stability.

    Examples:
        >>> distribution = chaospy.J(chaospy.Normal(), chaospy.Normal())
        >>> polynomials, norms = chaospy.orth_ttr(2, distribution, retall=True)
        >>> polynomials.round(10)
        polynomial([1.0, q1, q0, q1**2-1.0, q0*q1, q0**2-1.0])
        >>> norms.round(10)
        array([1., 1., 1., 2., 1., 2.])
        >>> polynomials = chaospy.orth_ttr(2, distribution, normed=True)
        >>> polynomials.round(3)
        polynomial([1.0, q1, q0, 0.707*q1**2-0.707, q0*q1, 0.707*q0**2-0.707])

    """
    _, polynomials, norms, = chaospy.stieltjes(numpy.max(order), dist)
    if normed:
        polynomials = numpoly.true_divide(polynomials, numpy.sqrt(norms))
        norms[:] = 1.

    polynomials = polynomials.reshape((len(dist), numpy.max(order) + 1))

    order = numpy.array(order)
    indices = numpoly.glexindex(start=0,
                                stop=order + 1,
                                dimensions=len(dist),
                                graded=graded,
                                reverse=reverse,
                                cross_truncation=cross_truncation)
    if len(dist) > 1:
        polynomials = numpoly.prod(
            chaospy.polynomial(
                [poly[idx] for poly, idx in zip(polynomials, indices.T)]), 0)
        norms = numpy.prod(
            [norms_[idx] for norms_, idx in zip(norms, indices.T)], 0)
    else:
        polynomials = polynomials.flatten()
        norms = norms.flatten()

    if retall:
        return polynomials, norms
    return polynomials
Пример #5
0
def test_poly_linearcomb():

    x, y = xy = cp.variable(2)
    mul1 = xy * np.eye(2)
    mul2 = cp.polynomial([[x, 0], [0, y]])
    assert np.all(mul1 == mul2)
Пример #6
0
def test_poly_matrix():
    XYZ = cp.variable(3)
    XYYZ = cp.polynomial([XYZ[:2], XYZ[1:]])
    assert str(XYYZ) == "[[q0 q1]\n [q1 q2]]"
    assert XYYZ.shape == (2, 2)
Пример #7
0
def test_poly_composit():
    X, Y, Z = cp.variable(3)
    ZYX = cp.polynomial([Z, Y, X])
    assert str(ZYX) == "[q2 q1 q0]"
Пример #8
0
def orth_ttr(order,
             dist,
             normed=False,
             sort="G",
             retall=False,
             cross_truncation=1.,
             **kws):
    """
    Create orthogonal polynomial expansion from three terms recursion formula.

    Args:
        order (int):
            Order of polynomial expansion.
        dist (Dist):
            Distribution space where polynomials are orthogonal If dist.ttr
            exists, it will be used. Must be stochastically independent.
        normed (bool):
            If True orthonormal polynomials will be used.
        sort (str):
            Polynomial sorting. Same as in basis.
        retall (bool):
            If true return numerical stabilized norms as well. Roughly the same
            as ``cp.E(orth**2, dist)``.
        cross_truncation (float):
            Use hyperbolic cross truncation scheme to reduce the number of
            terms in expansion. only include terms where the exponents ``K``
            satisfied the equation
            ``order >= sum(K**(1/cross_truncation))**cross_truncation``.

    Returns:
        (chaospy.poly.ndpoly, numpy.ndarray):
            Orthogonal polynomial expansion and norms of the orthogonal
            expansion on the form ``E(orth**2, dist)``. Calculated using
            recurrence coefficients for stability.

    Examples:
        >>> Z = chaospy.Normal()
        >>> chaospy.orth_ttr(4, Z).round(4)
        polynomial([1.0, q0, -1.0+q0**2, -3.0*q0+q0**3, 3.0-6.0*q0**2+q0**4])
    """
    try:
        _, polynomials, norms, = chaospy.quadrature.recurrence.analytical_stieljes(
            numpy.max(order), dist, normed=normed)
    except NotImplementedError:
        abscissas, weights = chaospy.quadrature.generate_quadrature(
            int(10000**(1 / len(dist))), dist, rule="fejer")
        _, polynomials, norms, = chaospy.quadrature.recurrence.discretized_stieltjes(
            numpy.max(order), abscissas, weights, normed=normed)

    polynomials = polynomials.reshape((len(dist), numpy.max(order) + 1))

    order = numpy.array(order)
    indices = numpoly.bindex(start=0,
                             stop=order + 1,
                             dimensions=len(dist),
                             ordering=sort,
                             cross_truncation=cross_truncation)
    if len(dist) > 1:
        polynomials = chaospy.poly.prod(
            chaospy.polynomial(
                [poly[idx] for poly, idx in zip(polynomials, indices.T)]), 0)
        norms = numpy.prod(
            [norms_[idx] for norms_, idx in zip(norms, indices.T)], 0)
    else:
        polynomials = polynomials.flatten()

    if retall:
        return polynomials, norms
    return polynomials