def analytical_stieljes(order, dist, normed=False): """ Examples: >>> dist = chaospy.J(chaospy.Uniform(0, 1), chaospy.Beta(3, 4)) >>> coeffs, orth, norms = analytical_stieljes(2, dist) >>> coeffs.round(5) array([[[0.5 , 0.5 , 0.5 ], [0.42857, 0.46032, 0.47475]], <BLANKLINE> [[1. , 0.08333, 0.06667], [1. , 0.03061, 0.04321]]]) >>> orth[:, 2].round(5) polynomial([q0**2-q0+0.16667, q1**2-0.88889*q1+0.16667]) >>> norms.round(5) array([[1. , 0.08333, 0.00556], [1. , 0.03061, 0.00132]]) >>> coeffs, orth, norms = analytical_stieljes(2, dist, normed=True) >>> coeffs.round(5) array([[[0.5 , 0.5 , 0.5 ], [0.42857, 0.46032, 0.47475]], <BLANKLINE> [[1. , 0.08333, 0.06667], [1. , 0.03061, 0.04321]]]) >>> orth[:, 2].round(5) polynomial([13.41641*q0**2-13.41641*q0+2.23607, 27.49545*q1**2-24.4404*q1+4.58258]) >>> norms.round(5) array([[1., 1., 1.], [1., 1., 1.]]) """ dimensions = len(dist) mom_order = numpy.arange(order + 1).repeat(dimensions) mom_order = mom_order.reshape(order + 1, dimensions).T coeffs = dist.ttr(mom_order) coeffs[1, :, 0] = 1. var = numpoly.variable(dimensions) orth = [numpy.zeros(dimensions), numpy.ones(dimensions)] for order_ in range(order): orth.append((var - coeffs[0, :, order_]) * orth[-1] - coeffs[1, :, order_] * orth[-2]) orth = numpoly.polynomial(orth[1:]).T norms = numpy.cumprod(coeffs[1], 1) if normed: orth = numpoly.true_divide(orth, numpy.sqrt(norms)) norms **= 0 return coeffs, orth, norms
def Kurt(poly, dist=None, fisher=True, **kws): """ The forth order statistical moment Kurtosis. Element by element 4rd order statistics of a distribution or polynomial. Args: poly (numpoly.ndpoly, Distribution): Input to take kurtosis on. dist (Distribution): Defines the space the skewness is taken on. It is ignored if ``poly`` is a distribution. fisher (bool): If True, Fisher's definition is used (Normal -> 0.0). If False, Pearson's definition is used (normal -> 3.0) Returns: (numpy.ndarray): Element for element variance along ``poly``, where ``skewness.shape==poly.shape``. Examples: >>> dist = chaospy.J(chaospy.Gamma(1, 1), chaospy.Normal(0, 2)) >>> chaospy.Kurt(dist).round(4) array([6., 0.]) >>> chaospy.Kurt(dist, fisher=False).round(4) array([9., 3.]) >>> q0, q1 = chaospy.variable(2) >>> poly = chaospy.polynomial([1, q0, q1, 10*q0*q1-1]) >>> chaospy.Kurt(poly, dist).round(4) array([nan, 6., 0., 15.]) >>> chaospy.Kurt(4., dist) array(nan) """ adjust = 3 if fisher else 0 if dist is None: dist, poly = poly, numpoly.variable(len(poly)) poly = numpoly.set_dimensions(poly, len(dist)) if poly.isconstant(): return numpy.full(poly.shape, numpy.nan) poly = poly - E(poly, dist, **kws) poly = numpoly.true_divide(poly, Std(poly, dist, **kws)) return E(poly**4, dist, **kws) - adjust
def Skew(poly, dist=None, **kws): """ The third order statistical moment Kurtosis. Element by element 3rd order statistics of a distribution or polynomial. Args: poly (numpoly.ndpoly, Distribution): Input to take skewness on. dist (Distribution): Defines the space the skewness is taken on. It is ignored if ``poly`` is a distribution. Returns: (numpy.ndarray): Element for element variance along ``poly``, where ``skewness.shape == poly.shape``. Examples: >>> dist = chaospy.J(chaospy.Gamma(1, 1), chaospy.Normal(0, 2)) >>> chaospy.Skew(dist) array([2., 0.]) >>> q0, q1 = chaospy.variable(2) >>> poly = chaospy.polynomial([1, q0, q1, 10*q0*q1-1]) >>> chaospy.Skew(poly, dist) array([nan, 2., 0., 0.]) >>> chaospy.Skew(2., dist) array(nan) """ if dist is None: dist, poly = poly, numpoly.variable(len(poly)) poly = numpoly.set_dimensions(poly, len(dist)) if poly.isconstant(): return numpy.full(poly.shape, numpy.nan) poly = poly - E(poly, dist, **kws) poly = numpoly.true_divide(poly, Std(poly, dist, **kws)) return E(poly**3, dist, **kws)
def Skew(poly, dist=None, **kws): """ Skewness operator. Element by element 3rd order statistics of a distribution or polynomial. Args: poly (chaospy.poly.ndpoly, Dist): Input to take skewness on. dist (Dist): Defines the space the skewness is taken on. It is ignored if ``poly`` is a distribution. Returns: (numpy.ndarray): Element for element variance along ``poly``, where ``skewness.shape == poly.shape``. Examples: >>> dist = chaospy.J(chaospy.Gamma(1, 1), chaospy.Normal(0, 2)) >>> chaospy.Skew(dist) array([2., 0.]) >>> x, y = chaospy.variable(2) >>> poly = chaospy.polynomial([1, x, y, 10*x*y]) >>> chaospy.Skew(poly, dist) array([nan, 2., 0., 0.]) """ if dist is None: dist, poly = poly, polynomials.variable(len(poly)) poly = polynomials.setdim(poly, len(dist)) if not poly.isconstant: return poly.tonumpy()**3 poly = poly - E(poly, dist, **kws) poly = numpoly.true_divide(poly, Std(poly, dist, **kws)) return E(poly**3, dist, **kws)
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