Example #1
0
def test_jacobi_poly():
    raises(ValueError, lambda: jacobi_poly(-1, a, b, x))

    assert jacobi_poly(1, a, b, x, polys=True) == Poly((a/2 + b/2 + 1)*x + a/2 - b/2, x, domain='ZZ(a,b)')

    assert jacobi_poly(0, a, b, x) == 1
    assert jacobi_poly(1, a, b, x) == a/2 - b/2 + x*(a/2 + b/2 + 1)
    assert jacobi_poly(2, a, b, x) == (a**2/8 - a*b/4 - a/8 + b**2/8 - b/8 + x**2*(a**2/8 + a*b/4 + 7*a/8 +
                                       b**2/8 + 7*b/8 + S(3)/2) + x*(a**2/4 + 3*a/4 - b**2/4 - 3*b/4) - S(1)/2)

    assert jacobi_poly(1, a, b, polys=True) == Poly((a/2 + b/2 + 1)*x + a/2 - b/2, x, domain='ZZ(a,b)')
Example #2
0
    def eval(cls, n, a, b, x):
        # Simplify to other polynomials
        # P^{a, a}_n(x)
        if a == b:
            if a == -S.Half:
                return C.RisingFactorial(S.Half, n) / C.factorial(n) * chebyshevt(n, x)
            elif a == S.Zero:
                return legendre(n, x)
            elif a == S.Half:
                return C.RisingFactorial(3 * S.Half, n) / C.factorial(n + 1) * chebyshevu(n, x)
            else:
                return C.RisingFactorial(a + 1, n) / C.RisingFactorial(2 * a + 1, n) * gegenbauer(n, a + S.Half, x)
        elif b == -a:
            # P^{a, -a}_n(x)
            return (
                C.gamma(n + a + 1) / C.gamma(n + 1) * (1 + x) ** (a / 2) / (1 - x) ** (a / 2) * assoc_legendre(n, -a, x)
            )
        elif a == -b:
            # P^{-b, b}_n(x)
            return (
                C.gamma(n - b + 1) / C.gamma(n + 1) * (1 - x) ** (b / 2) / (1 + x) ** (b / 2) * assoc_legendre(n, b, x)
            )

        if not n.is_Number:
            # Symbolic result P^{a,b}_n(x)
            # P^{a,b}_n(-x)  --->  (-1)**n * P^{b,a}_n(-x)
            if x.could_extract_minus_sign():
                return S.NegativeOne ** n * jacobi(n, b, a, -x)
            # We can evaluate for some special values of x
            if x == S.Zero:
                return (
                    2 ** (-n)
                    * C.gamma(a + n + 1)
                    / (C.gamma(a + 1) * C.factorial(n))
                    * C.hyper([-b - n, -n], [a + 1], -1)
                )
            if x == S.One:
                return C.RisingFactorial(a + 1, n) / C.factorial(n)
            elif x == S.Infinity:
                if n.is_positive:
                    # TODO: Make sure a+b+2*n \notin Z
                    return C.RisingFactorial(a + b + n + 1, n) * S.Infinity
        else:
            # n is a given fixed integer, evaluate into polynomial
            return jacobi_poly(n, a, b, x)
Example #3
0
    def eval(cls, n, a, b, x):
        # Simplify to other polynomials
        # P^{a, a}_n(x)
        if a == b:
            if a == Rational(-1, 2):
                return RisingFactorial(S.Half, n) / factorial(n) * chebyshevt(
                    n, x)
            elif a.is_zero:
                return legendre(n, x)
            elif a == S.Half:
                return RisingFactorial(
                    3 * S.Half, n) / factorial(n + 1) * chebyshevu(n, x)
            else:
                return RisingFactorial(a + 1, n) / RisingFactorial(
                    2 * a + 1, n) * gegenbauer(n, a + S.Half, x)
        elif b == -a:
            # P^{a, -a}_n(x)
            return gamma(n + a + 1) / gamma(n + 1) * (1 + x)**(a / 2) / (
                1 - x)**(a / 2) * assoc_legendre(n, -a, x)

        if not n.is_Number:
            # Symbolic result P^{a,b}_n(x)
            # P^{a,b}_n(-x)  --->  (-1)**n * P^{b,a}_n(-x)
            if x.could_extract_minus_sign():
                return S.NegativeOne**n * jacobi(n, b, a, -x)
            # We can evaluate for some special values of x
            if x.is_zero:
                return (2**(-n) * gamma(a + n + 1) /
                        (gamma(a + 1) * factorial(n)) *
                        hyper([-b - n, -n], [a + 1], -1))
            if x == S.One:
                return RisingFactorial(a + 1, n) / factorial(n)
            elif x is S.Infinity:
                if n.is_positive:
                    # Make sure a+b+2*n \notin Z
                    if (a + b + 2 * n).is_integer:
                        raise ValueError(
                            "Error. a + b + 2*n should not be an integer.")
                    return RisingFactorial(a + b + n + 1, n) * S.Infinity
        else:
            # n is a given fixed integer, evaluate into polynomial
            return jacobi_poly(n, a, b, x)
Example #4
0
def test_jacobi_poly():
    raises(ValueError, lambda: jacobi_poly(-1, a, b, x))

    assert jacobi_poly(1, a, b, x, polys=True) == Poly(
        (a / 2 + b / 2 + 1) * x + a / 2 - b / 2, x, domain='ZZ(a,b)')

    assert jacobi_poly(0, a, b, x) == 1
    assert jacobi_poly(1, a, b, x) == a / 2 - b / 2 + x * (a / 2 + b / 2 + 1)
    assert jacobi_poly(2, a, b, x) == (
        a**2 / 8 - a * b / 4 - a / 8 + b**2 / 8 - b / 8 + x**2 *
        (a**2 / 8 + a * b / 4 + a * Q(7, 8) + b**2 / 8 + b * Q(7, 8) + Q(3, 2))
        + x * (a**2 / 4 + a * Q(3, 4) - b**2 / 4 - b * Q(3, 4)) - S.Half)

    assert jacobi_poly(1, a, b, polys=True) == Poly(
        (a / 2 + b / 2 + 1) * x + a / 2 - b / 2, x, domain='ZZ(a,b)')
def test_jacobi_poly():
    raises(ValueError, lambda: jacobi_poly(-1, a, b, x))

    assert jacobi_poly(1, a, b, x, polys=True) == Poly(
        (a / 2 + b / 2 + 1) * x + a / 2 - b / 2, x, domain='ZZ(a,b)')

    assert jacobi_poly(0, a, b, x) == 1
    assert jacobi_poly(1, a, b, x) == a / 2 - b / 2 + x * (a / 2 + b / 2 + 1)
    assert jacobi_poly(2, a, b, x) == (
        a**2 / 8 - a * b / 4 - a / 8 + b**2 / 8 - b / 8 + x**2 *
        (a**2 / 8 + a * b / 4 + 7 * a / 8 + b**2 / 8 + 7 * b / 8 + S(3) / 2) +
        x * (a**2 / 4 + 3 * a / 4 - b**2 / 4 - 3 * b / 4) - S(1) / 2)

    assert jacobi_poly(1, a, b, polys=True) == Poly(
        (a / 2 + b / 2 + 1) * x + a / 2 - b / 2, x, domain='ZZ(a,b)')
Example #6
0
    def eval(cls, n, a, b, x):
        # Simplify to other polynomials
        # P^{a, a}_n(x)
        if a == b:
            if a == -S.Half:
                return C.RisingFactorial(S.Half, n) / C.factorial(n) * chebyshevt(n, x)
            elif a == S.Zero:
                return legendre(n, x)
            elif a == S.Half:
                return C.RisingFactorial(3*S.Half, n) / C.factorial(n + 1) * chebyshevu(n, x)
            else:
                return C.RisingFactorial(a + 1, n) / C.RisingFactorial(2*a + 1, n) * gegenbauer(n, a + S.Half, x)
        elif b == -a:
            # P^{a, -a}_n(x)
            return C.gamma(n + a + 1) / C.gamma(n + 1) * (1 + x)**(a/2) / (1 - x)**(a/2) * assoc_legendre(n, -a, x)
        elif a == -b:
            # P^{-b, b}_n(x)
            return C.gamma(n - b + 1) / C.gamma(n + 1) * (1 - x)**(b/2) / (1 + x)**(b/2) * assoc_legendre(n, b, x)

        if not n.is_Number:
            # Symbolic result P^{a,b}_n(x)
            # P^{a,b}_n(-x)  --->  (-1)**n * P^{b,a}_n(-x)
            if x.could_extract_minus_sign():
                return S.NegativeOne**n * jacobi(n, b, a, -x)
            # We can evaluate for some special values of x
            if x == S.Zero:
                return (2**(-n) * C.gamma(a + n + 1) / (C.gamma(a + 1) * C.factorial(n)) *
                        C.hyper([-b - n, -n], [a + 1], -1))
            if x == S.One:
                return C.RisingFactorial(a + 1, n) / C.factorial(n)
            elif x == S.Infinity:
                if n.is_positive:
                    # TODO: Make sure a+b+2*n \notin Z
                    return C.RisingFactorial(a + b + n + 1, n) * S.Infinity
        else:
            # n is a given fixed integer, evaluate into polynomial
            return jacobi_poly(n, a, b, x)
def gauss_jacobi(n, alpha, beta, n_digits):
    r"""
    Computes the Gauss-Jacobi quadrature [1]_ points and weights.

    The Gauss-Jacobi quadrature of the first kind approximates the integral:

    .. math::
        \int_{-1}^1 (1-x)^\alpha (1+x)^\beta f(x)\,dx \approx
            \sum_{i=1}^n w_i f(x_i)

    The nodes `x_i` of an order `n` quadrature rule are the roots of
    `P^{(\alpha,\beta)}_n` and the weights `w_i` are given by:

    .. math::
        w_i = -\frac{2n+\alpha+\beta+2}{n+\alpha+\beta+1}
              \frac{\Gamma(n+\alpha+1)\Gamma(n+\beta+1)}
              {\Gamma(n+\alpha+\beta+1)(n+1)!}
              \frac{2^{\alpha+\beta}}{P'_n(x_i)
              P^{(\alpha,\beta)}_{n+1}(x_i)}

    Parameters
    ==========

    n : the order of quadrature

    alpha : the first parameter of the Jacobi Polynomial, `\alpha > -1`

    beta : the second parameter of the Jacobi Polynomial, `\beta > -1`

    n_digits : number of significant digits of the points and weights to return

    Returns
    =======

    (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats.
             The points `x_i` and weights `w_i` are returned as ``(x, w)``
             tuple of lists.

    Examples
    ========

    >>> from sympy import S
    >>> from sympy.integrals.quadrature import gauss_jacobi
    >>> x, w = gauss_jacobi(3, S.Half, -S.Half, 5)
    >>> x
    [-0.90097, -0.22252, 0.62349]
    >>> w
    [1.7063, 1.0973, 0.33795]

    >>> x, w = gauss_jacobi(6, 1, 1, 5)
    >>> x
    [-0.87174, -0.5917, -0.2093, 0.2093, 0.5917, 0.87174]
    >>> w
    [0.050584, 0.22169, 0.39439, 0.39439, 0.22169, 0.050584]

    See Also
    ========

    gauss_legendre, gauss_laguerre, gauss_hermite, gauss_gen_laguerre, gauss_chebyshev_t, gauss_chebyshev_u, gauss_lobatto

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Gauss%E2%80%93Jacobi_quadrature
    .. [2] http://people.sc.fsu.edu/~jburkardt/cpp_src/jacobi_rule/jacobi_rule.html
    .. [3] http://people.sc.fsu.edu/~jburkardt/cpp_src/gegenbauer_rule/gegenbauer_rule.html
    """
    x = Dummy("x")
    p = jacobi_poly(n, alpha, beta, x, polys=True)
    pd = p.diff(x)
    pn = jacobi_poly(n + 1, alpha, beta, x, polys=True)
    xi = []
    w = []
    for r in p.real_roots():
        if isinstance(r, RootOf):
            r = r.eval_rational(S(1) / 10**(n_digits + 2))
        xi.append(r.n(n_digits))
        w.append(
            (-(2 * n + alpha + beta + 2) / (n + alpha + beta + S.One) *
             (gamma(n + alpha + 1) * gamma(n + beta + 1)) /
             (gamma(n + alpha + beta + S.One) * gamma(n + 2)) *
             2**(alpha + beta) / (pd.subs(x, r) * pn.subs(x, r))).n(n_digits))
    return xi, w
Example #8
0
def gauss_jacobi(n, alpha, beta, n_digits):
    r"""
    Computes the Gauss-Jacobi quadrature [1]_ points and weights.

    The Gauss-Jacobi quadrature of the first kind approximates the integral:

    .. math::
        \int_{-1}^1 (1-x)^\alpha (1+x)^\beta f(x)\,dx \approx \sum_{i=1}^n w_i f(x_i)

    The nodes `x_i` of an order `n` quadrature rule are the roots of `P^{(\alpha,\beta)}_n`
    and the weights `w_i` are given by:

    .. math::
        w_i = -\frac{2n+\alpha+\beta+2}{n+\alpha+\beta+1}\frac{\Gamma(n+\alpha+1)\Gamma(n+\beta+1)}
              {\Gamma(n+\alpha+\beta+1)(n+1)!} \frac{2^{\alpha+\beta}}{P'_n(x_i)
              P^{(\alpha,\beta)}_{n+1}(x_i)}

    Parameters
    ==========

    n : the order of quadrature

    alpha : the first parameter of the Jacobi Polynomial, `\alpha > -1`

    beta : the second parameter of the Jacobi Polynomial, `\beta > -1`

    n_digits : number of significant digits of the points and weights to return

    Returns
    =======

    (x, w) : the ``x`` and ``w`` are lists of points and weights as Floats.
             The points `x_i` and weights `w_i` are returned as ``(x, w)``
             tuple of lists.

    Examples
    ========

    >>> from sympy import S
    >>> from sympy.integrals.quadrature import gauss_jacobi
    >>> x, w = gauss_jacobi(3, S.Half, -S.Half, 5)
    >>> x
    [-0.90097, -0.22252, 0.62349]
    >>> w
    [1.7063, 1.0973, 0.33795]

    >>> x, w = gauss_jacobi(6, 1, 1, 5)
    >>> x
    [-0.87174, -0.5917, -0.2093, 0.2093, 0.5917, 0.87174]
    >>> w
    [0.050584, 0.22169, 0.39439, 0.39439, 0.22169, 0.050584]

    See Also
    ========

    gauss_legendre, gauss_laguerre, gauss_hermite, gauss_gen_laguerre, gauss_chebyshev_t, gauss_chebyshev_u

    References
    ==========

    .. [1] http://en.wikipedia.org/wiki/Gauss%E2%80%93Jacobi_quadrature
    .. [2] http://people.sc.fsu.edu/~jburkardt/cpp_src/jacobi_rule/jacobi_rule.html
    .. [3] http://people.sc.fsu.edu/~jburkardt/cpp_src/gegenbauer_rule/gegenbauer_rule.html
    """
    x = Dummy("x")
    p = jacobi_poly(n, alpha, beta, x, polys=True)
    pd = p.diff(x)
    pn = jacobi_poly(n+1, alpha, beta, x, polys=True)
    xi = []
    w  = []
    for r in p.real_roots():
        if isinstance(r, RootOf):
            r = r.eval_rational(S(1)/10**(n_digits+2))
        xi.append(r.n(n_digits))
        w.append((
            - (2*n+alpha+beta+2) / (n+alpha+beta+S.One)
            * (gamma(n+alpha+1)*gamma(n+beta+1)) / (gamma(n+alpha+beta+S.One)*gamma(n+2))
            * 2**(alpha+beta) / (pd.subs(x, r) * pn.subs(x, r))
        ).n(n_digits))
    return xi, w
Example #9
0
LegendreF = Rat(1) / (Rat(2) ** n) * (binomial(n, k)) ** 2 * (x - Rat(1)) ** k * (x + Rat(1)) ** (n - k)
LegendreP = Sum(LegendreF, (k, 0, n))

for nvar in range(4):
    legendre_poly(nvar, x) == LegendreP.subs(n, nvar).doit().expand()  # True

(LegendreF.subs(n, n + 1) / LegendreF).simplify()  # (n + 1)**2*(x + 1)/(2*(k - n - 1)**2)
(LegendreF.subs(k, k + 1) / LegendreF).simplify()  # (k - n)**2*(x - 1)/((k + 1)**2*(x + 1))

JacobiF = (
    Rat(1)
    / (Rat(2) ** n)
    * binomial(n + alpha, n - k)
    * binomial(n + beta, k)
    * (x - Rat(1)) ** k
    * (x + Rat(1)) ** (n - k)
)
JacobiP = Sum(JacobiF, (k, 0, n))
for alphvar in range(5):
    for betvar in range(5):
        for nvar in range(5):
            jacobi_poly(nvar, alphvar, betvar, x) == JacobiP.subs(n, nvar).subs(alpha, alphvar).subs(
                beta, betvar
            ).doit().expand()  # True

(
    JacobiF.subs(n, n + 1) / JacobiF
).simplify()  # (x + 1)*(alpha + n + 1)*(beta + n + 1)/(2*(k - n - 1)*(-beta + k - n - 1))
(JacobiF.subs(k, k + 1) / JacobiF).simplify()  # (k - n)*(x - 1)*(-beta + k - n)/((k + 1)*(x + 1)*(alpha + k + 1))