Ejemplo n.º 1
0
def test_symbols():
    assert numpoly.symbols() == X
    assert numpoly.symbols().shape == ()
    assert numpoly.symbols("q0") == X
    assert numpoly.symbols("q0").shape == ()
    assert numpoly.symbols("q0,") == X
    assert numpoly.symbols("q0,").shape == (1, )
    assert numpoly.symbols("q0", asarray=True) == X
    assert numpoly.symbols("q0", asarray=True).shape == (1, )

    assert numpoly.symbols("q:1").names == ("q0", )
    assert numpoly.symbols("q1").names == ("q1", )
Ejemplo n.º 2
0
def setdim(poly, dim=None):
    """
    Adjust the dimensions of a polynomial.

    Output the results into ndpoly object

    Args:
        poly (chaospy.poly.ndpoly):
            Input polynomial
        dim (int):
            The dimensions of the output polynomial. If omitted, increase
            polynomial with one dimension. If the new dim is smaller then
            `poly`'s dimensions, variables with cut components are all cut.

    Examples:
        >>> q0, q1 = chaospy.variable(2)
        >>> poly = q0*q1-q0**2
        >>> chaospy.setdim(poly, 1)
        polynomial(-q0**2)
        >>> chaospy.setdim(poly, 3)
        polynomial(q0*q1-q0**2)
        >>> chaospy.setdim(poly).names
        ('q0', 'q1', 'q2')

    """
    poly = numpoly.polynomial(poly)
    indices = [int(name[1:]) for name in poly.names]
    dim = max(indices) + 2 if dim is None else dim
    poly = poly(**{("q%d" % index): 0 for index in indices if index >= dim})
    _, poly = numpoly.align_indeterminants(numpoly.symbols("q:%d" % dim), poly)
    return poly
Ejemplo n.º 3
0
def orth_chol(order, dist, normed=True, sort="G", cross_truncation=1., **kws):
    """
    Create orthogonal polynomial expansion from Cholesky decomposition.

    Args:
        order (int):
            Order of polynomial expansion
        dist (Dist):
            Distribution space where polynomials are orthogonal
        normed (bool):
            If True orthonormal polynomials will be used instead of monic.
        sort (str):
            Ordering argument passed to poly.basis.  If custom basis is used,
            argument is ignored.
        cross_truncation (float):
            Use hyperbolic cross truncation scheme to reduce the number of
            terms in expansion.

    Examples:
        >>> Z = chaospy.Normal()
        >>> chaospy.orth_chol(3, Z).round(4)
        polynomial([1.0, q0, -0.7071+0.7071*q0**2, -1.2247*q0+0.4082*q0**3])
    """
    dim = len(dist)
    basis = chaospy.poly.basis(
        start=1,
        stop=order,
        dim=dim,
        sort=sort,
        cross_truncation=cross_truncation,
    )
    length = len(basis)

    cholmat = chaospy.chol.gill_king(chaospy.descriptives.Cov(basis, dist))
    cholmat_inv = numpy.linalg.inv(cholmat.T).T
    if not normed:
        diag_mesh = numpy.repeat(numpy.diag(cholmat_inv), len(cholmat_inv))
        cholmat_inv /= diag_mesh.reshape(cholmat_inv.shape)

    coefs = numpy.empty((length + 1, length + 1))

    coefs[1:, 1:] = cholmat_inv
    coefs[0, 0] = 1
    coefs[0, 1:] = 0

    expected = -numpy.sum(
        cholmat_inv * chaospy.descriptives.E(basis, dist, **kws), -1)
    coefs[1:, 0] = expected

    coefs = coefs.T

    out = {}
    out[(0, ) * dim] = coefs[0]
    for idx, key in enumerate(basis.exponents):
        out[tuple(key)] = coefs[idx + 1]

    names = numpoly.symbols("q:%d" % dim)
    polynomials = chaospy.poly.polynomial(out, names=names)

    return polynomials
Ejemplo n.º 4
0
def basis(start, stop=None, dim=1, sort="G", cross_truncation=1.):
    """
    Create an N-dimensional unit polynomial basis.

    Args:
        start (int, numpy.ndarray):
            the minimum polynomial to include. If int is provided, set as
            lowest total order.  If array of int, set as lower order along each
            axis.
        stop (int, numpy.ndarray):
            the maximum shape included. If omitted:
            ``stop <- start; start <- 0`` If int is provided, set as largest
            total order. If array of int, set as largest order along each axis.
        dim (int):
            dim of the basis. Ignored if array is provided in either start or
            stop.
        sort (str):
            The polynomial ordering where the letters ``G``, ``I`` and ``R``
            can be used to set grade, inverse and reverse to the ordering.  For
            ``basis(start=0, stop=2, dim=2, order=order)`` we get:
            ======  ==================
            order   output
            ======  ==================
            ""      [1 y y^2 x xy x^2]
            "G"     [1 y x y^2 xy x^2]
            "I"     [x^2 xy x y^2 y 1]
            "R"     [1 x x^2 y xy y^2]
            "GIR"   [y^2 xy x^2 y x 1]
            ======  ==================
        cross_truncation (float):
            Use hyperbolic cross truncation scheme to reduce the number of
            terms in expansion.

    Returns:
        (chaospy.poly.ndpoly) : Polynomial array.

    Examples:
        >>> chaospy.basis(2, dim=2, sort="GR")
        polynomial([1, q0, q1, q0**2, q0*q1, q1**2])
        >>> chaospy.basis(2, dim=4, sort="GR", cross_truncation=0)
        polynomial([1, q0, q1, q2, q3, q0**2, q1**2, q2**2, q3**2])
        >>> chaospy.basis(2, 2, dim=2, sort="GR", cross_truncation=numpy.inf)
        polynomial([q0**2, q1**2, q0**2*q1, q0*q1**2, q0**2*q1**2])
    """
    if stop is None:
        start, stop = 0, start
    dim = max(numpy.asarray(start).size, numpy.asarray(stop).size, dim)
    return numpoly.monomial(
        start=start,
        stop=numpy.array(stop)+1,
        ordering=sort,
        cross_truncation=cross_truncation,
        names=numpoly.symbols("q:%d" % dim, asarray=True),
    )
Ejemplo n.º 5
0
def test_aspolynomial():
    poly = 2*X-Y+1
    assert poly == numpoly.aspolynomial(poly)
    assert poly == numpoly.aspolynomial(poly, names=XY)
    assert poly == numpoly.aspolynomial(poly.todict(), names=XY)
    assert poly == numpoly.aspolynomial(poly, names=("X", "Y"))
    assert numpy.all(numpoly.symbols("Z:2") == numpoly.aspolynomial(XY, names="Z"))
    assert poly == numpoly.aspolynomial(poly.todict(), names=("X", "Y"))
    assert poly != numpoly.aspolynomial(poly.todict(), names=("Y", "X"))
    assert X == numpoly.aspolynomial(Y, names="X")
    assert poly != numpoly.aspolynomial(poly.todict(), names="X")
    assert isinstance(numpoly.aspolynomial([1, 2, 3]), numpoly.ndpoly)
    assert numpy.all(numpoly.aspolynomial([1, 2, 3]) == [1, 2, 3])
Ejemplo n.º 6
0
def basis(start, stop=None, dim=1, cross_truncation=1., sort="G"):
    """
    Create an N-dimensional unit polynomial basis.

    Args:
        start (int, numpy.ndarray):
            the minimum polynomial to include. If int is provided, set as
            lowest total order.  If array of int, set as lower order along each
            axis.
        stop (int, numpy.ndarray):
            the maximum shape included. If omitted:
            ``stop <- start; start <- 0`` If int is provided, set as largest
            total order. If array of int, set as largest order along each axis.
        dim (int):
            dim of the basis. Ignored if array is provided in either start or
            stop.
        cross_truncation (float):
            Use hyperbolic cross truncation scheme to reduce the number of
            terms in expansion.

    Returns:
        (numpoly.ndpoly) : Polynomial array.

    Examples:
        >>> chaospy.basis(2, dim=2)
        polynomial([1, q1, q0, q1**2, q0*q1, q0**2])
        >>> chaospy.basis(2, dim=4, cross_truncation=0)
        polynomial([1, q3, q2, q1, q0, q3**2, q2**2, q1**2, q0**2])
        >>> chaospy.basis(2, 2, dim=2, cross_truncation=numpy.inf)
        polynomial([q1**2, q0**2, q0*q1**2, q0**2*q1, q0**2*q1**2])

    """
    logger = logging.getLogger(__name__)
    logger.warning("chaospy.basis is deprecated; use chaospy.monomial instead")

    if stop is None:
        start, stop = 0, start
    dim = max(numpy.asarray(start).size, numpy.asarray(stop).size, dim)
    out = numpoly.monomial(
        start=start,
        stop=numpy.array(stop)+1,
        reverse="R" not in sort.upper(),
        graded="G" in sort.upper(),
        cross_truncation=cross_truncation,
        names=numpoly.symbols("q:%d" % dim, asarray=True),
    )
    if "I" in sort.upper():
        out = out[::-1]
    return out
Ejemplo n.º 7
0
def test_aspolynomial():
    poly = 2 * X - Y + 1
    assert poly == numpoly.aspolynomial(poly)
    assert poly == numpoly.aspolynomial(poly, names=XY)
    assert poly == numpoly.aspolynomial(poly.todict(), names=XY)
    assert poly == numpoly.aspolynomial(poly, names=("q0", "q1"))
    with numpoly.global_options(varname_filter=r"\w+",
                                force_number_suffix=False):
        assert numpy.all(
            numpoly.symbols("Z:2") == numpoly.aspolynomial(XY, names="Z"))
    assert poly == numpoly.aspolynomial(poly.todict(), names=("q0", "q1"))
    assert poly != numpoly.aspolynomial(poly.todict(), names=("q1", "q0"))
    assert X == numpoly.aspolynomial(Y, names="q0")
    assert poly != numpoly.aspolynomial(poly.todict(), names="q0")
    assert isinstance(numpoly.aspolynomial([1, 2, 3]), numpoly.ndpoly)
    assert numpy.all(numpoly.aspolynomial([1, 2, 3]) == [1, 2, 3])
Ejemplo n.º 8
0
def test_numpoly_ndpoly():
    poly = numpoly.ndpoly(exponents=[(1, )], shape=(), names="X")
    poly["<"] = 1
    assert poly == X
    poly = numpoly.ndpoly(exponents=[(1, )], shape=(), names=X)
    poly["<"] = 1
    assert poly == X
    poly = numpoly.ndpoly(exponents=[(1, 0), (0, 1)],
                          shape=(),
                          names=("X", "Y"))
    poly["<;"] = 2
    poly[";<"] = 3
    assert poly == 2 * X + 3 * Y
    poly = numpoly.ndpoly(exponents=[(1, 0), (0, 1)], shape=(2, ), names="Q")
    poly["<;"] = [1, 0]
    poly[";<"] = [0, 1]
    assert numpy.all(poly == numpoly.symbols("Q0 Q1"))
Ejemplo n.º 9
0
def variable(dims=1):
    """
    Simple constructor to create single variables to create polynomials.

    Args:
        dims (int):
            Number of dimensions in the array.

    Returns:
        (chaospy.poly.polynomial):
            Polynomial array with unit components in each dimension.

    Examples:
        >>> chaospy.variable()
        polynomial(q0)
        >>> chaospy.variable(3)
        polynomial([q0, q1, q2])
    """
    return numpoly.symbols("q:%d" % dims)
Ejemplo n.º 10
0
def test_ndpoly():
    poly = numpoly.ndpoly(exponents=[(1, )], shape=(), names="q0")
    poly["<"] = 1
    assert poly == X
    poly = numpoly.ndpoly(exponents=[(1, )], shape=(), names=X)
    poly["<"] = 1
    assert poly == X
    poly = numpoly.ndpoly(exponents=[(1, 0), (0, 1)],
                          shape=(),
                          names=("q0", "q1"))
    poly["<;"] = 2
    poly[";<"] = 3
    assert poly == 2 * X + 3 * Y
    with numpoly.global_options(varname_filter=r"Q\d+"):
        poly = numpoly.ndpoly(exponents=[(1, 0), (0, 1)],
                              shape=(2, ),
                              names="Q:2")
        poly["<;"] = [1, 0]
        poly[";<"] = [0, 1]
        assert numpy.all(poly == numpoly.symbols("Q0 Q1"))
Ejemplo n.º 11
0
def test_numpoly_polynomial():
    assert numpoly.polynomial() == 0
    assert numpoly.polynomial({(0, ): 4}) == 4
    assert numpoly.polynomial({(1, ): 5}, names="X") == 5 * X
    assert numpoly.polynomial({
        (0, 1): 2,
        (1, 0): 3
    }, names=("X", "Y")) == 3 * X + 2 * Y
    assert numpy.all(
        numpoly.polynomial({
            (0, 1): [0, 1],
            (1, 0): [1, 0]
        }, names="Q") == numpoly.symbols("Q0 Q1"))
    assert numpoly.polynomial(X) == X
    assert numpoly.polynomial(numpy.array((3, ), dtype=[(";", int)])) == 3
    assert numpoly.polynomial(5.5) == 5.5
    assert numpoly.polynomial(sympy.symbols("X")) == X
    assert numpy.all(numpoly.polynomial([1, 2, 3]) == [1, 2, 3])
    assert numpy.all(numpoly.polynomial([[1, 2], [3, 4]]) == [[1, 2], [3, 4]])
    assert numpy.all(
        numpoly.polynomial(numpy.array([[1, 2], [3, 4]])) == [[1, 2], [3, 4]])
Ejemplo n.º 12
0
def variable(
        dimensions: int = 1,
        asarray: bool = False,
        dtype: numpy.typing.DTypeLike = "i8",
        allocation: Optional[int] = None,
) -> ndpoly:
    """
    Construct variables that can be used to construct polynomials.

    Args:
        dimensions:
            Number of dimensions in the array.
        asarray:
            Enforce output as array even in the case where there is only one
            variable.
        dtype:
            The data type of the polynomial coefficients.
        allocation:
            The maximum number of polynomial exponents. If omitted, use
            length of exponents for allocation.

    Returns:
        Polynomial array with unit components in each dimension.

    Examples:
        >>> numpoly.variable()
        polynomial(q0)
        >>> q0, q1, q2 = numpoly.variable(3)
        >>> q1+1
        polynomial(q1+1)
        >>> numpoly.polynomial([q2**3, q1+q2, 1])
        polynomial([q2**3, q2+q1, 1])

    """
    return numpoly.symbols(
        names=f"{numpoly.get_options()['default_varname']}:{dimensions:d}",
        asarray=asarray,
        dtype=dtype,
        allocation=allocation,
    )
Ejemplo n.º 13
0
def test_polynomial():
    assert numpoly.polynomial() == 0
    assert numpoly.polynomial({(0, ): 4}) == 4
    assert numpoly.polynomial({(1, ): 5}, names="q0") == 5 * X
    assert numpoly.polynomial({
        (0, 1): 2,
        (1, 0): 3
    }, names=("q0", "q1")) == 3 * X + 2 * Y
    with numpoly.global_options(varname_filter=r"\w+"):
        assert numpy.all(
            numpoly.polynomial({
                (0, 1): [0, 1],
                (1, 0): [1, 0]
            }, names="Q") == numpoly.symbols("Q0 Q1"))
    assert numpoly.polynomial(X) == X
    assert numpoly.polynomial(numpy.array((3, ), dtype=[(";", int)])) == 3
    assert numpoly.polynomial(5.5) == 5.5
    assert numpoly.polynomial(sympy.symbols("q0")) == X
    assert numpy.all(numpoly.polynomial([1, 2, 3]) == [1, 2, 3])
    assert numpy.all(numpoly.polynomial([[1, 2], [3, 4]]) == [[1, 2], [3, 4]])
    assert numpy.all(
        numpoly.polynomial(numpy.array([[1, 2], [3, 4]])) == [[1, 2], [3, 4]])
Ejemplo n.º 14
0
def orth_chol(order,
              dist,
              normed=False,
              graded=True,
              reverse=True,
              cross_truncation=1.,
              retall=False,
              **kws):
    """
    Create orthogonal polynomial expansion from Cholesky decomposition.

    Args:
        order (int):
            Order of polynomial expansion
        dist (Dist):
            Distribution space where polynomials are orthogonal
        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.
        cross_truncation (float):
            Use hyperbolic cross truncation scheme to reduce the number of
            terms in expansion.
        retall (bool):
            If true return numerical stabilized norms as well. Roughly the same
            as ``cp.E(orth**2, dist)``.

    Examples:
        >>> distribution = chaospy.Normal()
        >>> expansion, norms = chaospy.orth_chol(3, distribution, retall=True)
        >>> expansion.round(4)
        polynomial([1.0, q0, q0**2-1.0, q0**3-3.0*q0])
        >>> norms
        array([1., 1., 2., 6.])

    """
    dim = len(dist)
    basis = numpoly.monomial(
        start=1,
        stop=order + 1,
        names=numpoly.variable(dim).names,
        graded=graded,
        reverse=reverse,
        cross_truncation=cross_truncation,
    )
    length = len(basis)

    covariance = chaospy.descriptives.Cov(basis, dist)
    cholmat = chaospy.chol.gill_king(covariance)
    cholmat_inv = numpy.linalg.inv(cholmat.T).T
    if not normed:
        diag_mesh = numpy.repeat(numpy.diag(cholmat_inv), len(cholmat_inv))
        cholmat_inv /= diag_mesh.reshape(cholmat_inv.shape)
        norms = numpy.hstack([1, numpy.diag(cholmat)**2])
    else:
        norms = numpy.ones(length + 1, dtype=float)

    coefs = numpy.empty((length + 1, length + 1))

    coefs[1:, 1:] = cholmat_inv
    coefs[0, 0] = 1
    coefs[0, 1:] = 0

    expected = -numpy.sum(
        cholmat_inv * chaospy.descriptives.E(basis, dist, **kws), -1)
    coefs[1:, 0] = expected

    coefs = coefs.T

    out = {}
    out[(0, ) * dim] = coefs[0]
    for idx, key in enumerate(basis.exponents):
        out[tuple(key)] = coefs[idx + 1]

    names = numpoly.symbols("q:%d" % dim)
    polynomials = numpoly.polynomial(out, names=names)

    if retall:
        return polynomials, norms
    return polynomials
Ejemplo n.º 15
0
"""Test ndpoly baseclass functionality."""
import numpy
from pytest import raises
import numpoly

XY = numpoly.variable(2)
X, Y = numpoly.symbols("q0"), numpoly.symbols("q1")
EMPTY = numpoly.polynomial([])


def test_scalars():
    """Test scalar objects to catch edgecases."""
    assert XY.shape == (2, )
    assert XY.size == 2
    assert X.shape == ()
    assert X.size == 1
    assert EMPTY.shape in [(), (0, )]  # different behavior in py2/3
    assert EMPTY.size == 0

    assert numpy.all(numpy.array(XY.coefficients) == [[1, 0], [0, 1]])
    assert X.coefficients == [1]
    assert EMPTY.coefficients == []

    assert numpy.all(XY.exponents == [[1, 0], [0, 1]])
    assert XY.exponents.shape == (2, 2)
    assert X.exponents == 1
    assert X.exponents.shape == (1, 1)
    assert numpy.all(EMPTY.exponents == 0)
    assert EMPTY.exponents.shape == (1, 1)

    assert numpy.all(XY.indeterminants == XY)
Ejemplo n.º 16
0
    def __new__(
            cls,
            exponents: numpy.typing.ArrayLike = ((0,),),
            shape: Tuple[int, ...] = (),
            names: Union[None, str, Tuple[str, ...], "ndpoly"] = None,
            dtype: Optional[numpy.typing.DTypeLike] = None,
            allocation: Optional[int] = None,
            **kwargs: Any
    ) -> "ndpoly":
        """
        Class constructor.

        Args:
            exponents:
                The exponents in an integer array with shape ``(N, D)``, where
                ``N`` is the number of terms in the polynomial sum and ``D`` is
                the number of dimensions.
            shape:
                Shape of created array.
            names:
                The name of the indeterminant variables in the polynomial. If
                polynomial, inherent from it. Else, pass argument to
                `numpoly.symbols` to create the indeterminants names. If only
                one name is provided, but more than one is required,
                indeterminants will be extended with an integer index. If
                omitted, use ``numpoly.get_options()["default_varname"]``.
            dtype:
                Any object that can be interpreted as a numpy data type.
            allocation:
                The maximum number of polynomial exponents. If omitted, use
                length of exponents for allocation.
            kwargs:
                Extra arguments passed to `numpy.ndarray` constructor.

        """
        exponents = numpy.array(exponents, dtype=numpy.uint32)
        if numpy.prod(exponents.shape):
            keys = (exponents+cls.KEY_OFFSET).flatten()
            keys = keys.view(f"U{exponents.shape[-1]}")
            keys = numpy.array(keys, dtype=f"U{exponents.shape[-1]}")
        else:
            keys = numpy.full((1,), cls.KEY_OFFSET, dtype="uint32").view("U1")
        assert len(keys.shape) == 1

        dtype = int if dtype is None else dtype
        dtype_ = numpy.dtype([(key, dtype) for key in keys])

        obj = super(ndpoly, cls).__new__(
            cls, shape=shape, dtype=dtype_, **kwargs)

        if allocation is None:
            allocation = 2*len(keys)
        assert isinstance(allocation, int) and allocation >= len(keys), (
            "Not enough memory allocated; increase 'allocation'")
        if allocation > len(keys):
            allocation_ = numpy.arange(allocation-len(keys), len(keys))
            allocation_ = [str(s) for s in allocation_]
            keys = numpy.concatenate([keys, allocation_])
        obj.allocation = allocation

        if names is None:
            names = numpoly.get_options()["default_varname"]
            obj.names = numpoly.symbols(
                f"{names}:{exponents.shape[-1]}").names
        elif isinstance(names, str):
            obj.names = numpoly.symbols(names).names
        elif isinstance(names, ndpoly):
            obj.names = names.names
        else:
            obj.names = tuple(str(name) for name in names)
        for name in obj.names:
            assert re.search(numpoly.get_options()["varname_filter"], name), (
                "invalid polynomial name; "
                f"expected format: {numpoly.get_options()['varname_filter']}")

        obj._dtype = numpy.dtype(dtype)  # pylint: disable=protected-access
        obj.keys = keys
        return obj
Ejemplo n.º 17
0
"""Testing functions used for numpy compatible."""
from pytest import raises
import numpy
from numpoly import polynomial
import numpoly

X, Y = numpoly.symbols("X Y")


def test_numpy_absolute(interface):
    assert abs(-X) == abs(X) == X
    assert numpy.all(
        interface.abs(polynomial([X - Y, Y - 4])) == [X + Y, Y + 4])


def test_numpy_add(interface):
    assert interface.add(X, 3) == 3 + X
    assert numpy.all(
        interface.add(polynomial([1, X, Y]), 4) == [5, 4 + X, 4 + Y])
    assert numpy.all(
        interface.add(polynomial([0, X]), polynomial([Y, 0])) == [Y, X])
    assert numpy.all(
        interface.add(polynomial([[1, X], [Y, X * Y]]), [2, X]) ==
        [[3, 2 * X], [2 + Y, X + X * Y]])


def test_numpy_any(interface):
    poly = polynomial([[0, Y], [0, 0]])
    assert interface.any(poly)
    assert numpy.all(interface.any(poly, axis=0) == [False, True])
    assert numpy.all(
Ejemplo n.º 18
0
def basis(start,
          stop=None,
          dim=1,
          graded=True,
          reverse=True,
          cross_truncation=1.,
          sort=None):
    """
    Create an N-dimensional unit polynomial basis.

    Args:
        start (int, numpy.ndarray):
            the minimum polynomial to include. If int is provided, set as
            lowest total order.  If array of int, set as lower order along each
            axis.
        stop (int, numpy.ndarray):
            the maximum shape included. If omitted:
            ``stop <- start; start <- 0`` If int is provided, set as largest
            total order. If array of int, set as largest order along each axis.
        dim (int):
            dim of the basis. Ignored if array is provided in either start or
            stop.
        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.
        cross_truncation (float):
            Use hyperbolic cross truncation scheme to reduce the number of
            terms in expansion.

    Returns:
        (chaospy.poly.ndpoly) : Polynomial array.

    Examples:
        >>> chaospy.basis(2, dim=2)
        polynomial([1, q1, q0, q1**2, q0*q1, q0**2])
        >>> chaospy.basis(2, dim=4, cross_truncation=0)
        polynomial([1, q3, q2, q1, q0, q3**2, q2**2, q1**2, q0**2])
        >>> chaospy.basis(2, 2, dim=2, cross_truncation=numpy.inf)
        polynomial([q1**2, q0**2, q0*q1**2, q0**2*q1, q0**2*q1**2])

    """
    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()
        inverse = "I" in sort.upper()
        out = basis(start, stop, dim, graded, reverse, cross_truncation)
        if inverse:
            out = out[::-1]
        return out

    if stop is None:
        start, stop = 0, start
    dim = max(numpy.asarray(start).size, numpy.asarray(stop).size, dim)
    return numpoly.monomial(
        start=start,
        stop=numpy.array(stop) + 1,
        reverse=reverse,
        graded=graded,
        cross_truncation=cross_truncation,
        names=numpoly.symbols("q:%d" % dim, asarray=True),
    )
def test_numpoly():
    import numpoly
    x = numpoly.symbols("x")
    p = x**2 + 3 * x + 1

    assert numpoly.diff(p, x) == 2 * x + 3
Ejemplo n.º 20
0
def orth_chol(order, dist, normed=False, sort="G", cross_truncation=1., retall=False, **kws):
    """
    Create orthogonal polynomial expansion from Cholesky decomposition.

    Args:
        order (int):
            Order of polynomial expansion
        dist (Dist):
            Distribution space where polynomials are orthogonal
        normed (bool):
            If True orthonormal polynomials will be used instead of monic.
        sort (str):
            Ordering argument passed to poly.basis.  If custom basis is used,
            argument is ignored.
        cross_truncation (float):
            Use hyperbolic cross truncation scheme to reduce the number of
            terms in expansion.
        retall (bool):
            If true return numerical stabilized norms as well. Roughly the same
            as ``cp.E(orth**2, dist)``.

    Examples:
        >>> distribution = chaospy.Normal()
        >>> expansion, norms = chaospy.orth_chol(3, distribution, retall=True)
        >>> expansion.round(4)
        polynomial([1.0, q0, -1.0+q0**2, -3.0*q0+q0**3])
        >>> norms
        array([1., 1., 2., 6.])
    """
    dim = len(dist)
    basis = chaospy.poly.basis(
        start=1, stop=order, dim=dim, sort=sort,
        cross_truncation=cross_truncation,
    )
    length = len(basis)

    covariance = chaospy.descriptives.Cov(basis, dist)
    cholmat = chaospy.chol.gill_king(covariance)
    cholmat_inv = numpy.linalg.inv(cholmat.T).T
    if not normed:
        diag_mesh = numpy.repeat(numpy.diag(cholmat_inv), len(cholmat_inv))
        cholmat_inv /= diag_mesh.reshape(cholmat_inv.shape)
        norms = numpy.hstack([1, numpy.diag(cholmat)**2])
    else:
        norms = numpy.ones(length+1, dtype=float)

    coefs = numpy.empty((length+1, length+1))

    coefs[1:, 1:] = cholmat_inv
    coefs[0, 0] = 1
    coefs[0, 1:] = 0

    expected = -numpy.sum(
        cholmat_inv*chaospy.descriptives.E(basis, dist, **kws), -1)
    coefs[1:, 0] = expected

    coefs = coefs.T

    out = {}
    out[(0,)*dim] = coefs[0]
    for idx, key in enumerate(basis.exponents):
        out[tuple(key)] = coefs[idx+1]

    names = numpoly.symbols("q:%d" % dim)
    polynomials = chaospy.poly.polynomial(out, names=names)

    if retall:
        return polynomials, norms
    return polynomials