Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" 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:`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: var('z') 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: f(x) = hypergeometric([1, 1], [3, 3, 3], x) sage: plot(f, x, -30, 30) Graphics object consisting of 1 graphics primitive sage: g(x) = hypergeometric([x], [], 2) sage: complex_plot(g, (-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.52605111678803 - 7.86331357527540*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]},...
The confluent hypergeometric functions can arise as solutions to second-order differential equations (example from `here <http://ask.sagemath.org/question/ 1168/how-can-one-use-maxima-kummer-confluent-functions>`_)::
sage: var('m') m sage: y = function('y')(x) sage: desolve(diff(y, x, 2) + 2*x*diff(y, x) - 4*m*y, y, ....: contrib_ode=true, ivar=x) [y(x) == _K1*hypergeometric_M(-m, 1/2, -x^2) +... _K2*hypergeometric_U(-m, 1/2, -x^2)]
Series expansions of confluent hypergeometric functions::
sage: hypergeometric_M(2, 2, x).series(x, 3) 1 + 1*x + 1/2*x^2 + Order(x^3) sage: hypergeometric_U(2, 2, x).series(x == 3, 100).subs(x=1).n() 0.403652637676806 sage: hypergeometric_U(2, 2, 1).n() 0.403652637676806 """
#***************************************************************************** # Copyright (C) 2010 Fredrik Johansson <fredrik.johansson@gmail.com> # Copyright (C) 2013 Eviatar Bach <eviatarbach@gmail.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** from six.moves import range
from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.infinity import Infinity from sage.arith.all import binomial, rising_factorial, factorial from sage.symbolic.constants import pi from sage.symbolic.all import I from sage.symbolic.function import BuiltinFunction from sage.symbolic.ring import SR from sage.structure.element import get_coercion_model from sage.misc.latex import latex from sage.misc.misc_c import prod from sage.libs.mpmath import utils as mpmath_utils from sage.symbolic.expression import Expression from sage.calculus.functional import derivative from functools import reduce
from .gamma import gamma from .other import sqrt, real_part from .log import exp, log from .trig import sin from .hyperbolic import cosh, sinh from .error import erf
def rational_param_as_tuple(x): r""" 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 """
class Hypergeometric(BuiltinFunction): r""" Represents a (formal) generalized infinite hypergeometric series. It is defined as
.. MATH::
\,_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. """ def __init__(self): """ Initialize class.
EXAMPLES::
sage: maxima(hypergeometric) hypergeometric """ BuiltinFunction.__init__(self, 'hypergeometric', nargs=3, conversions={'mathematica': 'HypergeometricPFQ', 'maxima': 'hypergeometric', 'sympy': 'hyper', 'fricas': 'hypergeometricF'})
def __call__(self, a, b, z, **kwargs): """ Return symbolic hypergeometric function expression.
INPUT:
- ``a`` -- a list or tuple of parameters - ``b`` -- a list or tuple of parameters - ``z`` -- a number or symbolic expression
EXAMPLES::
sage: hypergeometric([], [], 1) hypergeometric((), (), 1) sage: hypergeometric([], [1], 1) hypergeometric((), (1,), 1) sage: hypergeometric([2, 3], [1], 1) hypergeometric((2, 3), (1,), 1) sage: hypergeometric([], [], x) hypergeometric((), (), x) sage: hypergeometric([x], [], x^2) hypergeometric((x,), (), x^2)
The only simplification that is done automatically is returning 1 if ``z`` is 0. For other simplifications use the ``simplify_hypergeometric`` method. """ SR._force_pyobject(a), SR._force_pyobject(b), z, **kwargs)
def _print_latex_(self, a, b, z): r""" TESTS::
sage: latex(hypergeometric([1, 1], [2], -1)) \,_2F_1\left(\begin{matrix} 1,1 \\ 2 \end{matrix} ; -1 \right)
""" r"{} \right)").format(len(a), len(b), aa, bb, z)
def _eval_(self, a, b, z, **kwargs): """ EXAMPLES::
sage: hypergeometric([], [], 0) 1 """ raise TypeError("The first two parameters must be of type list")
def _evalf_try_(self, a, b, z): """ Call :meth:`_evalf_` if one of the arguments is numerical and none of the arguments are symbolic.
OUTPUT:
- ``None`` if we didn't succeed to call :meth:`_evalf_` or if the input wasn't suitable for it.
- otherwise, a numerical value for the function.
EXAMPLES::
sage: hypergeometric._evalf_try_((1.0,), (2.0,), 3.0) 6.36184564106256 sage: hypergeometric._evalf_try_((1.0, 1), (), 3.0) -0.0377593153441588 + 0.750349833788561*I sage: hypergeometric._evalf_try_((1, 1), (), 3) # exact input sage: hypergeometric._evalf_try_((x,), (), 1.0) # symbolic sage: hypergeometric._evalf_try_(1.0, 2.0, 3.0) # not tuples """ # We need to override this for hypergeometric functions since # the first 2 arguments are tuples and the generic _evalf_try_ # cannot handle that.
def _evalf_(self, a, b, z, parent, algorithm=None): """ TESTS::
sage: hypergeometric([1, 1], [2], -1).n() 0.693147180559945 sage: hypergeometric([], [], RealField(100)(1)) 2.7182818284590452353602874714
""" raise TypeError("The first two parameters must be of type list")
def _tderivative_(self, a, b, z, *args, **kwargs): """ EXAMPLES::
sage: hypergeometric([1/3, 2/3], [5], x^2).diff(x) 4/45*x*hypergeometric((4/3, 5/3), (6,), x^2) sage: hypergeometric([1, 2], [x], 2).diff(x) Traceback (most recent call last): ... NotImplementedError: derivative of hypergeometric function with... respect to parameters. Try calling .simplify_hypergeometric()... first. sage: hypergeometric([1/3, 2/3], [5], 2).diff(x) 0 """ "with respect to parameters. Try calling" " .simplify_hypergeometric() first.") reduce(lambda x, y: x / y, b, Integer(1))) hypergeometric([c + 1 for c in a], [c + 1 for c in b], z))
class EvaluationMethods(object): def _fast_float_(self, *args): """ Do not support the old ``fast_float``.
OUTPUT:
This method raises ``NotImplementedError``; use the newer ``fast_callable`` implementation.
EXAMPLES::
sage: f = hypergeometric([], [], x) sage: f._fast_float_() Traceback (most recent call last): ... NotImplementedError """
def _fast_callable_(self, a, b, z, etb): """ Override the ``fast_callable`` method.
OUTPUT:
A :class:`~sage.ext.fast_callable.ExpressionCall` representing the hypergeometric function in the expression tree.
EXAMPLES::
sage: h = hypergeometric([], [], x) sage: from sage.ext.fast_callable import ExpressionTreeBuilder sage: etb = ExpressionTreeBuilder(vars=['x']) sage: h._fast_callable_(etb) {hypergeometric((), (), x)}(v_0)
sage: var('x, y') (x, y) sage: f = fast_callable(hypergeometric([y], [], x), vars=[x, y]) sage: f(3, 4) doctest:...: DeprecationWarning: Substitution using function-call syntax and unnamed arguments is deprecated and will be removed from a future release of Sage; you can use named arguments instead, like EXPR(x=..., y=...) See http://trac.sagemath.org/5930 for details. hypergeometric((4,), (), 3) """
def 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) """
def 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) """ else:
def 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 """ return 0 not in b return False
def is_terminating(self, a, b, z): r""" 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 """ return True
def is_absolutely_convergent(self, a, b, z): r""" 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 """
def 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)) [] """
def deflated(self, a, b, z): r""" 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 """
def _deflated(self, a, b, z): """ Private helper to return list of deflated terms.
EXAMPLES::
sage: x = hypergeometric([5], [4], 3) sage: y = x.deflated() sage: y 7/4*hypergeometric((), (), 3) sage: x.n(); y.n() 35.1496896155784 35.1496896155784 """ # TODO: could rewrite prefactors as recurrence [c + k for c in bbbb], z) counts[unique.index(f)] += c else: Fterms]
hypergeometric = Hypergeometric()
def closed_form(hyp): """ Try to evaluate ``hyp`` in closed form using elementary (and other simple) functions.
It may be necessary to call :meth:`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) """
return Integer(1)
# TODO: make this require only linear time _0f1(b - 1, z))) _0f1(b + 2, z)) raise ValueError # Can evaluate 0F1 in terms of elementary functions when # the parameter is a half-integer
# Confluent hypergeometric function return (exp(z) - 1) / z return (exp(z) * sum(rf(m - n, k) * (-z) ** k / factorial(k) / rf(m, k) for k in range(n - m + 1))) else: (factorial(k) * rf(2 - m, k)) for k in range(m - n)) (factorial(k) * rf(2 - m, k)) for k in range(n)) z ** (1 - m) / factorial(n - 1) * (T - exp(z) * U))
""" Evaluation of 2F1(a, b; c; z), assuming a, b, c positive integers or half-integers """ return (1 - z) ** (-b) return Integer(1) a, b = b, a F1 = _2f1(a, b - 1, c, z) F2 = _2f1(a, b - 2, c, z) q = (b - 1) * (z - 1) return (((c - 2 * b + 2 + (b - a - 1) * z) * F1 + (b - c - 1) * F2) / q) # how to handle this case? raise NotImplementedError
if (a, b, c) == (1, R32, R12): return (1 + z) / (1 - z) ** 2 if (a, b, c) == (1, R32, 2): return 2 * (1 / sqrt(1 - z) - 1) / z if (a, b, c) == (R32, 2, R12): return (1 + 3 * z) / (1 - z) ** 3 if (a, b, c) == (R32, 2, 1): return (2 + z) / (2 * (sqrt(1 - z) * (1 - z) ** 2)) if (a, b, c) == (2, 2, 1): return (1 + z) / (1 - z) ** 3 raise NotImplementedError return (gamma(cc) * gamma(cc - aa - bb) / gamma(cc - aa) / gamma(cc - bb)) aa > 0 and bb > 0 and cc > 0): except NotImplementedError: pass
class Hypergeometric_M(BuiltinFunction): r""" The confluent hypergeometric function of the first kind, `y = M(a,b,z)`, is defined to be the solution to Kummer's differential equation
.. MATH::
zy'' + (b-z)y' - ay = 0.
This is not the same as Kummer's `U`-hypergeometric function, though it satisfies the same DE that `M` does.
.. warning::
In the literature, both are called "Kummer confluent hypergeometric" functions.
EXAMPLES::
sage: hypergeometric_M(1, 1, 1) hypergeometric_M(1, 1, 1) sage: hypergeometric_M(1, 1, 1.) 2.71828182845905 sage: hypergeometric_M(1, 1, 1).n(70) 2.7182818284590452354 sage: hypergeometric_M(1, 1, 1).simplify_hypergeometric() e sage: hypergeometric_M(1, 1/2, x).simplify_hypergeometric() (-I*sqrt(pi)*x*erf(I*sqrt(-x))*e^x + sqrt(-x))/sqrt(-x) sage: hypergeometric_M(1, 3/2, 1).simplify_hypergeometric() 1/2*sqrt(pi)*erf(1)*e """ def __init__(self): """ TESTS::
sage: maxima(hypergeometric_M(1,1,x)) kummer_m(1,1,_SAGE_VAR_x) sage: latex(hypergeometric_M(1,1,x)) M\left(1, 1, x\right) """ BuiltinFunction.__init__(self, 'hypergeometric_M', nargs=3, conversions={'mathematica': 'Hypergeometric1F1', 'maxima': 'kummer_m', 'fricas': 'kummerM'}, latex_name='M')
def _eval_(self, a, b, z, **kwargs): """ TESTS::
sage: (a,b)=var('a,b') sage: hypergeometric_M(a,b,0) 1 """
def _evalf_(self, a, b, z, parent, algorithm=None): """ TESTS::
sage: hypergeometric_M(1,1,1).n() 2.71828182845905 """
def _derivative_(self, a, b, z, diff_param): """ TESTS::
sage: diff(hypergeometric_M(1,1,x),x,3) hypergeometric_M(4, 4, x) sage: diff(hypergeometric_M(x,1,1),x,3) Traceback (most recent call last): ... NotImplementedError: derivative of hypergeometric function with respect to parameters """ 'with respect to parameters')
class EvaluationMethods(object): def generalized(self, a, b, z): """ Return as a generalized hypergeometric function
EXAMPLES::
sage: var('a b z') (a, b, z) sage: hypergeometric_M(a, b, z).generalized() hypergeometric((a,), (b,), z)
"""
hypergeometric_M = Hypergeometric_M()
class Hypergeometric_U(BuiltinFunction): r""" The confluent hypergeometric function of the second kind, `y = U(a,b,z)`, is defined to be the solution to Kummer's differential equation
.. MATH::
zy'' + (b-z)y' - ay = 0.
This satisfies `U(a,b,z) \sim z^{-a}`, as `z\rightarrow \infty`, and is sometimes denoted `z^{-a}{}_2F_0(a,1+a-b;;-1/z)`. This is not the same as Kummer's `M`-hypergeometric function, denoted sometimes as `_1F_1(\alpha,\beta,z)`, though it satisfies the same DE that `U` does.
.. warning::
In the literature, both are called "Kummer confluent hypergeometric" functions.
EXAMPLES::
sage: hypergeometric_U(1, 1, 1) hypergeometric_U(1, 1, 1) sage: hypergeometric_U(1, 1, 1.) 0.596347362323194 sage: hypergeometric_U(1, 1, 1).n(70) 0.59634736232319407434 sage: hypergeometric_U(10^4, 1/3, 1).n() 6.60377008885811e-35745 sage: hypergeometric_U(2 + I, 2, 1).n() 0.183481989942099 - 0.458685959185190*I sage: hypergeometric_U(1, 3, x).simplify_hypergeometric() (x + 1)/x^2 sage: hypergeometric_U(1, 2, 2).simplify_hypergeometric() 1/2
""" def __init__(self): """ TESTS::
sage: maxima(hypergeometric_U(1,1,x)) kummer_u(1,1,_SAGE_VAR_x) sage: latex(hypergeometric_U(1,1,x)) U\left(1, 1, x\right) """ BuiltinFunction.__init__(self, 'hypergeometric_U', nargs=3, conversions={'mathematica': 'HypergeometricU', 'maxima': 'kummer_u', 'fricas': 'kummerU'}, latex_name='U')
def _eval_(self, a, b, z, **kwargs):
def _evalf_(self, a, b, z, parent, algorithm=None): """ TESTS::
sage: hypergeometric_U(1,1,1).n() 0.596347362323194 """
def _derivative_(self, a, b, z, diff_param): """ TESTS::
sage: diff(hypergeometric_U(1,1,x),x,3) -6*hypergeometric_U(4, 4, x) sage: diff(hypergeometric_U(x,1,1),x,3) Traceback (most recent call last): ... NotImplementedError: derivative of hypergeometric function with respect to parameters """ 'with respect to parameters')
class EvaluationMethods(object): def generalized(self, a, b, z): """ Return in terms of the generalized hypergeometric function
EXAMPLES::
sage: var('a b z') (a, b, z) sage: hypergeometric_U(a, b, z).generalized() z^(-a)*hypergeometric((a, a - b + 1), (), -1/z) sage: hypergeometric_U(1, 3, 1/2).generalized() 2*hypergeometric((1, -1), (), -2) sage: hypergeometric_U(3, I, 2).generalized() 1/8*hypergeometric((3, -I + 4), (), -1/2)
"""
hypergeometric_U = Hypergeometric_U() |