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.
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
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
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
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)
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)
def test_poly_composit(): X, Y, Z = cp.variable(3) ZYX = cp.polynomial([Z, Y, X]) assert str(ZYX) == "[q2 q1 q0]"
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