Пример #1
0
def norm(order, dist, orth=None):

    dim = len(dist)
    try:
        if dim > 1:
            norms = numpy.array([norm(order + 1, D) for D in dist])
            Is = numpoly.bindex(order + 1, dimensions=dim)
            out = numpy.ones(len(Is))

            for i in range(len(Is)):
                index = Is[i]
                for j in range(dim):
                    if index[j]:
                        out[i] *= norms[j, index[j]]
            return out

        K = range(1, order + 1)
        ttr = [1.] + [dist.ttr(k)[1] for k in K]
        return numpy.cumprod(ttr)

    except NotImplementedError:

        if orth is None:
            orth = orth_chol(order, dist)
        return chaospy.descriptives.E(orth**2, dist)
Пример #2
0
def _construct_collection(
        orders,
        dist,
        x_lookup,
        w_lookup,
):
    """Create a collection of {abscissa: weight} key-value pairs."""
    order = numpy.min(orders)
    skew = orders-order

    # Indices and coefficients used in the calculations
    indices = numpoly.bindex(order-len(dist)+1, order+1, dimensions=len(dist))
    coeffs = numpy.sum(indices, -1)
    coeffs = (2*((order-coeffs+1) % 2)-1)*comb(len(dist)-1, order-coeffs)

    collection = defaultdict(float)
    for bidx, coeff in zip(indices+skew, coeffs.tolist()):
        abscissas = [value[idx] for idx, value in zip(bidx, x_lookup)]
        weights = [value[idx] for idx, value in zip(bidx, w_lookup)]
        for abscissa, weight in zip(product(*abscissas), product(*weights)):
            collection[abscissa] += numpy.prod(weight)*coeff

    return collection
Пример #3
0
def lagrange_polynomial(abscissas, sort="G"):
    """
    Create Lagrange polynomials.

    Args:
        abscissas (numpy.ndarray):
            Sample points where the Lagrange polynomials shall be defined.

    Example:
        >>> chaospy.lagrange_polynomial([-10, 10]).round(4)
        polynomial([0.5-0.05*q0, 0.5+0.05*q0])
        >>> chaospy.lagrange_polynomial([-1, 0, 1]).round(4)
        polynomial([-0.5*q0+0.5*q0**2, 1.0-q0**2, 0.5*q0+0.5*q0**2])
        >>> poly = chaospy.lagrange_polynomial([[1, 0, 1], [0, 1, 2]])
        >>> poly.round(4)
        polynomial([0.5-0.5*q1+0.5*q0, 1.0-q0, -0.5+0.5*q1+0.5*q0])
        >>> poly([1, 0, 1], [0, 1, 2]).round(4)
        array([[1., 0., 0.],
               [0., 1., 0.],
               [0., 0., 1.]])
        >>> nodes = numpy.array([[ 0.17,  0.15,  0.17,  0.19],
        ...                      [14.94, 16.69, 16.69, 16.69]])
        >>> poly = chaospy.lagrange_polynomial(nodes)  # doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
            ...
        LinAlgError: Lagrange abscissas resulted in invertible matrix
    """
    abscissas = numpy.asfarray(abscissas)
    if len(abscissas.shape) == 1:
        abscissas = abscissas.reshape(1, abscissas.size)
    dim, size = abscissas.shape

    order = 1
    while chaospy.bertran.terms(order, dim) < size:
        order += 1

    indices = numpoly.bindex(0, order + 1, dimensions=dim,
                             ordering=sort)[:size]
    idx, idy = numpy.mgrid[:size, :size]

    matrix = numpy.prod(abscissas.T[idx]**indices[idy], -1)
    det = numpy.linalg.det(matrix)
    if det == 0:
        raise numpy.linalg.LinAlgError(
            "Lagrange abscissas resulted in invertible matrix")

    vec = chaospy.poly.basis(0, order, dim, sort)[:size]

    coeffs = numpy.zeros((size, size))

    if size == 1:
        out = chaospy.poly.basis(0, 0, dim, sort) * abscissas.item()

    elif size == 2:
        coeffs = numpy.linalg.inv(matrix)
        out = chaospy.poly.sum(vec * (coeffs.T), 1)

    else:
        for i in range(size):
            if i % 2 != 0:
                k = 1
            else:
                k = 0
            for j in range(size):
                if k % 2 == 0:
                    coeffs[i, j] += numpy.linalg.det(matrix[1:, 1:])
                else:
                    if size % 2 == 0:
                        coeffs[i, j] += -numpy.linalg.det(matrix[1:, 1:])
                    else:
                        coeffs[i, j] += numpy.linalg.det(matrix[1:, 1:])
                matrix = numpy.roll(matrix, -1, axis=0)
                k += 1
            matrix = numpy.roll(matrix, -1, axis=1)
        coeffs /= det
        out = chaospy.poly.sum(vec * (coeffs.T), 1)

    return out
Пример #4
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
Пример #5
0
def test_numpoly_bindex():
    assert not numpoly.bindex(0).size
    assert numpy.all(numpoly.bindex(1) == [[0]])
    assert numpy.all(numpoly.bindex(5) == [[0], [1], [2], [3], [4]])
    assert numpy.all(
        numpoly.bindex(2, dimensions=2) == [[0, 0], [0, 1], [1, 0]])
    assert numpy.all(
        numpoly.bindex(start=2, stop=3, dimensions=2) == [[0, 2], [1, 1],
                                                          [2, 0]])
    assert numpy.all(
        numpoly.bindex(start=2, stop=[3, 4], dimensions=2) == [[0, 2], [1, 1],
                                                               [2, 0], [0, 3]])
    assert numpy.all(
        numpoly.bindex(start=[2, 5], stop=[3, 6], dimensions=2) ==
        [[1, 1], [2, 0], [1, 2], [0, 5]])
    assert numpy.all(
        numpoly.bindex(start=2, stop=3, dimensions=2, ordering="I") ==
        [[2, 0], [1, 1], [0, 2]])
    assert numpy.all(
        numpoly.bindex(start=2, stop=4, dimensions=2, cross_truncation=0) ==
        [[0, 2], [2, 0], [0, 3], [3, 0]])
    assert numpy.all(
        numpoly.bindex(start=2, stop=4, dimensions=2, cross_truncation=1) ==
        [[0, 2], [1, 1], [2, 0], [0, 3], [1, 2], [2, 1], [3, 0]])
    assert numpy.all(
        numpoly.bindex(start=2, stop=4, dimensions=2, cross_truncation=2) ==
        [[0, 2], [1, 1], [2, 0], [0, 3], [1, 2], [2, 1], [3, 0], [2, 2]])
    assert numpy.all(
        numpoly.bindex(start=0, stop=2, dimensions=3) ==
        [[0, 0, 0], [0, 0, 1], [0, 1, 0], [1, 0, 0]])