### Navigation

- index
- modules |
- next |
- previous |
- Functions »

# Hypergeometric Functions

This module implements manipulation of infinite hypergeometric series represented in standard parametric form (as \(\,_pF_q\) functions).

AUTHORS:

- Fredrik Johansson (2010): initial version
- Eviatar Bach (2013): major changes

EXAMPLES:

Examples from trac ticket #9908:

    sage: maxima('integrate(bessel_j(2, x), x)').sage()
    1/24*x^3*hypergeometric((3/2,), (5/2, 3), -1/4*x^2)
    sage: sum(((2*I)^x/(x^3 + 1)*(1/4)^x), x, 0, oo)
    hypergeometric((1, 1, -1/2*I*sqrt(3) - 1/2, 1/2*I*sqrt(3) - 1/2),...
    (2, -1/2*I*sqrt(3) + 1/2, 1/2*I*sqrt(3) + 1/2), 1/2*I)
    sage: sum((-1)^x/((2*x + 1)*factorial(2*x + 1)), x, 0, oo)
    hypergeometric((1/2,), (3/2, 3/2), -1/4)

Simplification (note that `simplify_full` does not yet call `simplify_hypergeometric`):

    sage: hypergeometric([-2], [], x).simplify_hypergeometric()
    x^2 - 2*x + 1
    sage: hypergeometric([], [], x).simplify_hypergeometric()
    e^x
    sage: a = hypergeometric((hypergeometric((), (), x),), (),
    ....:                    hypergeometric((), (), x))
    sage: a.simplify_hypergeometric()
    1/((-e^x + 1)^e^x)
    sage: a.simplify_hypergeometric(algorithm='sage')
    (-e^x + 1)^(-e^x)

Equality testing:

    sage: bool(hypergeometric([], [], x).derivative(x) ==
    ....:      hypergeometric([], [], x))  # diff(e^x, x) == e^x
    True
    sage: bool(hypergeometric([], [], x) == hypergeometric([], [1], x))
    False

Computing terms and series:

    sage: z = var('z')
    sage: hypergeometric([], [], z).series(z, 0)
    Order(1)
    sage: hypergeometric([], [], z).series(z, 1)
    1 + Order(z)
    sage: hypergeometric([], [], z).series(z, 2)
    1 + 1*z + Order(z^2)
    sage: hypergeometric([], [], z).series(z, 3)
    1 + 1*z + 1/2*z^2 + Order(z^3)

    sage: hypergeometric([-2], [], z).series(z, 3)
    1 + (-2)*z + 1*z^2
    sage: hypergeometric([-2], [], z).series(z, 6)
    1 + (-2)*z + 1*z^2
    sage: hypergeometric([-2], [], z).series(z, 6).is_terminating_series()
    True
    sage: hypergeometric([-2], [], z).series(z, 2)
    1 + (-2)*z + Order(z^2)
    sage: hypergeometric([-2], [], z).series(z, 2).is_terminating_series()
    False

    sage: hypergeometric([1], [], z).series(z, 6)
    1 + 1*z + 1*z^2 + 1*z^3 + 1*z^4 + 1*z^5 + Order(z^6)
    sage: hypergeometric([], [1/2], -z^2/4).series(z, 11)
    1 + (-1/2)*z^2 + 1/24*z^4 + (-1/720)*z^6 + 1/40320*z^8 +...
    (-1/3628800)*z^10 + Order(z^11)

    sage: hypergeometric([1], [5], x).series(x, 5)
    1 + 1/5*x + 1/30*x^2 + 1/210*x^3 + 1/1680*x^4 + Order(x^5)

    sage: sum(hypergeometric([1, 2], [3], 1/3).terms(6)).n()
    1.29788359788360
    sage: hypergeometric([1, 2], [3], 1/3).n()
    1.29837194594696
    sage: hypergeometric([], [], x).series(x, 20)(x=1).n() == e.n()
    True

Plotting:

    sage: plot(hypergeometric([1, 1], [3, 3, 3], x), x, -30, 30)
    Graphics object consisting of 1 graphics primitive
    sage: complex_plot(hypergeometric([x], [], 2), (-1, 1), (-1, 1))
    Graphics object consisting of 1 graphics primitive

Numeric evaluation:

    sage: hypergeometric([1], [], 1/10).n()  # geometric series
    1.11111111111111
    sage: hypergeometric([], [], 1).n()  # e
    2.71828182845905
    sage: hypergeometric([], [], 3., hold=True)
    hypergeometric((), (), 3.00000000000000)
    sage: hypergeometric([1, 2, 3], [4, 5, 6], 1/2).n()
    1.02573619590134
    sage: hypergeometric([1, 2, 3], [4, 5, 6], 1/2).n(digits=30)
    1.02573619590133865036584139535
    sage: hypergeometric([5 - 3*I], [3/2, 2 + I, sqrt(2)], 4 + I).n()
    5.52605111678805 - 7.86331357527544*I
    sage: hypergeometric((10, 10), (50,), 2.)
    -1705.75733163554 - 356.749986056024*I

Conversions:

    sage: maxima(hypergeometric([1, 1, 1], [3, 3, 3], x))
    hypergeometric([1,1,1],[3,3,3],_SAGE_VAR_x)
    sage: hypergeometric((5, 4), (4, 4), 3)._sympy_()
    hyper((5, 4), (4, 4), 3)
    sage: hypergeometric((5, 4), (4, 4), 3)._mathematica_init_()
    'HypergeometricPFQ[{5,4},{4,4},3]'

Arbitrary level of nesting for conversions:

    sage: maxima(nest(lambda y: hypergeometric([y], [], x), 3, 1))
    1/(1-_SAGE_VAR_x)^(1/(1-_SAGE_VAR_x)^(1/(1-_SAGE_VAR_x)))
    sage: maxima(nest(lambda y: hypergeometric([y], [3], x), 3, 1))._sage_()
    hypergeometric((hypergeometric((hypergeometric((1,), (3,), x),), (3,),...
    x),), (3,), x)
    sage: nest(lambda y: hypergeometric([y], [], x), 3, 1)._mathematica_init_()
    'HypergeometricPFQ[{HypergeometricPFQ[{HypergeometricPFQ[{1},{},x]},...

class `sage.functions.hypergeometric.``Hypergeometric`

  Bases: `sage.symbolic.function.BuiltinFunction`

  Represents a (formal) generalized infinite hypergeometric series. It is defined as

  \[\,_pF_q(a_1, \ldots, a_p; b_1, \ldots, b_q; z) = \sum_{n=0}^{\infty} \frac{(a_1)_n \cdots (a_p)_n}{(b_1)_n \cdots(b_q)_n} \, \frac{z^n}{n!},\]

  where \((x)_n\) is the rising factorial.

  class `EvaluationMethods`
    `deflated`(self, a, b, z)

      Rewrite as a linear combination of functions of strictly lower degree by eliminating all parameters `a[i]` and `b[j]` such that `a[i]` = `b[i]` + `m` for nonnegative integer `m`.

      EXAMPLES:

          sage: x = hypergeometric([6, 1], [3, 4, 5], 10)
          sage: y = x.deflated()
          sage: y
          1/252*hypergeometric((4,), (7, 8), 10)
           + 1/12*hypergeometric((3,), (6, 7), 10)
           + 1/2*hypergeometric((2,), (5, 6), 10)
           + hypergeometric((1,), (4, 5), 10)
          sage: x.n(); y.n()
          2.87893612686782
          2.87893612686782

          sage: x = hypergeometric([6, 7], [3, 4, 5], 10)
          sage: y = x.deflated()
          sage: y
          25/27216*hypergeometric((), (11,), 10)
           + 25/648*hypergeometric((), (10,), 10)
           + 265/504*hypergeometric((), (9,), 10)
           + 181/63*hypergeometric((), (8,), 10)
           + 19/3*hypergeometric((), (7,), 10)
           + 5*hypergeometric((), (6,), 10)
           + hypergeometric((), (5,), 10)
          sage: x.n(); y.n()
          63.0734110716969
          63.0734110716969

    `eliminate_parameters`(self, a, b, z)

      Eliminate repeated parameters by pairwise cancellation of identical terms in `a` and `b`.

      EXAMPLES:

          sage: hypergeometric([1, 1, 2, 5], [5, 1, 4],
          ....:                1/2).eliminate_parameters()
          hypergeometric((1, 2), (4,), 1/2)
          sage: hypergeometric([x], [x], x).eliminate_parameters()
          hypergeometric((), (), x)
          sage: hypergeometric((5, 4), (4, 4), 3).eliminate_parameters()
          hypergeometric((5,), (4,), 3)

    `is_absolutely_convergent`(self, a, b, z)

      Determine whether `self` converges absolutely as an infinite series. `False` is returned if not all terms are finite.

      EXAMPLES:

      Degree giving infinite radius of convergence:

          sage: hypergeometric([2, 3], [4, 5],
          ....:                6).is_absolutely_convergent()
          True
          sage: hypergeometric([2, 3], [-4, 5],
          ....:                6).is_absolutely_convergent()  # undefined
          False
          sage: (hypergeometric([2, 3], [-4, 5], Infinity)
          ....:  .is_absolutely_convergent())  # undefined
          False

      Ordinary geometric series (unit radius of convergence):

          sage: hypergeometric([1], [], 1/2).is_absolutely_convergent()
          True
          sage: hypergeometric([1], [], 2).is_absolutely_convergent()
          False
          sage: hypergeometric([1], [], 1).is_absolutely_convergent()
          False
          sage: hypergeometric([1], [], -1).is_absolutely_convergent()
          False
          sage: hypergeometric([1], [], -1).n()  # Sum still exists
          0.500000000000000

      Degree \(p = q+1\) (unit radius of convergence):

          sage: hypergeometric([2, 3], [4], 6).is_absolutely_convergent()
          False
          sage: hypergeometric([2, 3], [4], 1).is_absolutely_convergent()
          False
          sage: hypergeometric([2, 3], [5], 1).is_absolutely_convergent()
          False
          sage: hypergeometric([2, 3], [6], 1).is_absolutely_convergent()
          True
          sage: hypergeometric([-2, 3], [4],
          ....:                5).is_absolutely_convergent()
          True
          sage: hypergeometric([2, -3], [4],
          ....:                5).is_absolutely_convergent()
          True
          sage: hypergeometric([2, -3], [-4],
          ....:                5).is_absolutely_convergent()
          True
          sage: hypergeometric([2, -3], [-1],
          ....:                5).is_absolutely_convergent()
          False

      Degree giving zero radius of convergence:

          sage: hypergeometric([1, 2, 3], [4],
          ....:                2).is_absolutely_convergent()
          False
          sage: hypergeometric([1, 2, 3], [4],
          ....:                1/2).is_absolutely_convergent()
          False
          sage: (hypergeometric([1, 2, -3], [4], 1/2)
          ....:  .is_absolutely_convergent())  # polynomial
          True

    `is_terminating`(self, a, b, z)

      Determine whether the series represented by self terminates after a finite number of terms, i.e. whether any of the numerator parameters are nonnegative integers (with no preceding nonnegative denominator parameters), or \(z = 0\).

      If terminating, the series represents a polynomial of \(z\).

      EXAMPLES:

          sage: hypergeometric([1, 2], [3, 4], x).is_terminating()
          False
          sage: hypergeometric([1, -2], [3, 4], x).is_terminating()
          True
          sage: hypergeometric([1, -2], [], x).is_terminating()
          True

    `is_termwise_finite`(self, a, b, z)

      Determine whether all terms of `self` are finite. Any infinite terms or ambiguous terms beyond the first zero, if one exists, are ignored.

      Ambiguous cases (where a term is the product of both zero and an infinity) are not considered finite.

      EXAMPLES:

          sage: hypergeometric([2], [3, 4], 5).is_termwise_finite()
          True
          sage: hypergeometric([2], [-3, 4], 5).is_termwise_finite()
          False
          sage: hypergeometric([-2], [-3, 4], 5).is_termwise_finite()
          True
          sage: hypergeometric([-3], [-3, 4],
          ....:                5).is_termwise_finite()  # ambiguous
          False

          sage: hypergeometric([0], [-1], 5).is_termwise_finite()
          True
          sage: hypergeometric([0], [0],
          ....:                5).is_termwise_finite()  # ambiguous
          False
          sage: hypergeometric([1], [2], Infinity).is_termwise_finite()
          False
          sage: (hypergeometric([0], [0], Infinity)
          ....:  .is_termwise_finite())  # ambiguous
          False
          sage: (hypergeometric([0], [], Infinity)
          ....:  .is_termwise_finite())  # ambiguous
          False

    `sorted_parameters`(self, a, b, z)

      Return with parameters sorted in a canonical order.

      EXAMPLES:

          sage: hypergeometric([2, 1, 3], [5, 4],
          ....:                1/2).sorted_parameters()
          hypergeometric((1, 2, 3), (4, 5), 1/2)

    `terms`(self, a, b, z, n=None)

      Generate the terms of `self` (optionally only `n` terms).

      EXAMPLES:

          sage: list(hypergeometric([-2, 1], [3, 4], x).terms())
          [1, -1/6*x, 1/120*x^2]
          sage: list(hypergeometric([-2, 1], [3, 4], x).terms(2))
          [1, -1/6*x]
          sage: list(hypergeometric([-2, 1], [3, 4], x).terms(0))
          []

`sage.functions.hypergeometric.``closed_form`(hyp)

  Try to evaluate `hyp` in closed form using elementary (and other simple) functions.

  It may be necessary to call `Hypergeometric.deflated()` first to find some closed forms.

  EXAMPLES:

      sage: from sage.functions.hypergeometric import closed_form
      sage: var('a b c z')
      (a, b, c, z)
      sage: closed_form(hypergeometric([1], [], 1 + z))
      -1/z
      sage: closed_form(hypergeometric([], [], 1 + z))
      e^(z + 1)
      sage: closed_form(hypergeometric([], [1/2], 4))
      cosh(4)
      sage: closed_form(hypergeometric([], [3/2], 4))
      1/4*sinh(4)
      sage: closed_form(hypergeometric([], [5/2], 4))
      3/16*cosh(4) - 3/64*sinh(4)
      sage: closed_form(hypergeometric([], [-3/2], 4))
      19/3*cosh(4) - 4*sinh(4)
      sage: closed_form(hypergeometric([-3, 1], [var('a')], z))
      -3*z/a + 6*z^2/((a + 1)*a) - 6*z^3/((a + 2)*(a + 1)*a) + 1
      sage: closed_form(hypergeometric([-3, 1/3], [-4], z))
      7/162*z^3 + 1/9*z^2 + 1/4*z + 1
      sage: closed_form(hypergeometric([], [], z))
      e^z
      sage: closed_form(hypergeometric([a], [], z))
      (-z + 1)^(-a)
      sage: closed_form(hypergeometric([1, 1, 2], [1, 1], z))
      (z - 1)^(-2)
      sage: closed_form(hypergeometric([2, 3], [1], x))
      -1/(x - 1)^3 + 3*x/(x - 1)^4
      sage: closed_form(hypergeometric([1/2], [3/2], -5))
      1/10*sqrt(5)*sqrt(pi)*erf(sqrt(5))
      sage: closed_form(hypergeometric([2], [5], 3))
      4
      sage: closed_form(hypergeometric([2], [5], 5))
      48/625*e^5 + 612/625
      sage: closed_form(hypergeometric([1/2, 7/2], [3/2], z))
      1/5*z^2/(-z + 1)^(5/2) + 2/3*z/(-z + 1)^(3/2) + 1/sqrt(-z + 1)
      sage: closed_form(hypergeometric([1/2, 1], [2], z))
      -2*(sqrt(-z + 1) - 1)/z
      sage: closed_form(hypergeometric([1, 1], [2], z))
      -log(-z + 1)/z
      sage: closed_form(hypergeometric([1, 1], [3], z))
      -2*((z - 1)*log(-z + 1)/z - 1)/z
      sage: closed_form(hypergeometric([1, 1, 1], [2, 2], x))
      hypergeometric((1, 1, 1), (2, 2), x)

`sage.functions.hypergeometric.``rational_param_as_tuple`(x)

  Utility function for converting rational \(\,_pF_q\) parameters to tuples (which mpmath handles more efficiently).

  EXAMPLES:

      sage: from sage.functions.hypergeometric import rational_param_as_tuple
      sage: rational_param_as_tuple(1/2)
      (1, 2)
      sage: rational_param_as_tuple(3)
      3
      sage: rational_param_as_tuple(pi)
      pi

### Navigation

- index
- modules |
- next |
- previous |
- Functions »