Ticket #14896: trac_14896_2.patch
File trac_14896_2.patch, 13.9 KB (added by , 9 years ago) |
---|
-
sage/functions/all.py
# HG changeset patch # User Eviatar Bach <eviatarbach@gmail.com> # Date 1374019480 25200 # Branch hyper # Node ID 93aa2f7392e1909a85a3571f3d93dc54f0996083 # Parent 2c773352ebc9bc079a27fa06e03ca858bf60e39a Implementing confluent hypergeometric functions diff --git a/sage/functions/all.py b/sage/functions/all.py
a b 27 27 from transcendental import (zeta, zetaderiv, zeta_symmetric, dickman_rho) 28 28 29 29 from special import (bessel_I, bessel_J, bessel_K, bessel_Y, 30 hypergeometric_U,Bessel,30 Bessel, 31 31 spherical_bessel_J, spherical_bessel_Y, 32 32 spherical_hankel1, spherical_hankel2, 33 33 spherical_harmonic, jacobi, … … 68 68 sinh_integral, cosh_integral, Shi, Chi, 69 69 exponential_integral_1, Ei) 70 70 71 from hypergeometric import hypergeometric 71 from hypergeometric import hypergeometric, hypergeometric_M, hypergeometric_U -
sage/functions/hypergeometric.py
diff --git a/sage/functions/hypergeometric.py b/sage/functions/hypergeometric.py
a b 1 1 r""" 2 2 Hypergeometric Functions 3 3 4 This module implements manipulation of infinite hypergeometric series 5 represented in standard parametric form (as $\,_pF_q$ functions). 4 This module implements manipulation of generalized hypergeometric series 5 represented in standard parametric form (as $\,_pF_q$ functions), as well as 6 the confluent hypergeometric functions of the first and second kind. 6 7 7 8 AUTHORS: 8 9 … … 123 124 x),), (3,), x) 124 125 sage: nest(lambda y: hypergeometric([y], [], x), 3, 1)._mathematica_init_() 125 126 'HypergeometricPFQ[{HypergeometricPFQ[{HypergeometricPFQ[{1},{},x]},... 127 128 The confluent hypergeometric functions can arise as solutions to second-order 129 differential equations (example from `here <http://ask.sagemath.org/question/ 130 1168/how-can-one-use-maxima-kummer-confluent-functions>`_):: 131 132 sage: m = var('m') 133 sage: y = function('y', x) 134 sage: desolve(diff(y, x, 2) + 2*x*diff(y, x) - 4*m*y, y, 135 ....: contrib_ode=true, ivar=x) 136 [y(x) == k1*hypergeometric_M(-m, 1/2, -x^2) +... 137 k2*hypergeometric_U(-m, 1/2, -x^2)] 138 139 Series expansions of confluent hypergeometric functions:: 140 141 sage: hypergeometric_M(2, 2, x).series(x, 3) 142 1 + 1*x + 1/2*x^2 + Order(x^3) 143 sage: hypergeometric_U(2, 2, x).series(x == 3, 100).subs(x=1).n() 144 0.403652637676806 145 sage: hypergeometric_U(2, 2, 1).n() 146 0.403652637676806 126 147 """ 127 148 #***************************************************************************** 128 149 # Copyright (C) 2010 Fredrik Johansson <fredrik.johansson@gmail.com> … … 138 159 rising_factorial, factorial) 139 160 from sage.functions.other import sqrt, gamma, real_part 140 161 from sage.functions.log import exp, log 141 from sage.functions.trig import cos,sin162 from sage.functions.trig import sin 142 163 from sage.functions.hyperbolic import cosh, sinh 143 164 from sage.functions.other import erf 144 165 from sage.symbolic.constants import pi … … 782 803 783 804 def _2f1(a, b, c, z): 784 805 """ 785 Evaluation of 2F1(a, b , c,z), assuming a, b, c positive806 Evaluation of 2F1(a, b; c; z), assuming a, b, c positive 786 807 integers or half-integers 787 808 """ 788 809 if b == c: … … 838 859 pass 839 860 return hyp 840 861 return sum([coeff * _closed_form(pfq) for coeff, pfq in new._deflated()]) 862 863 class Hypergeometric_M(BuiltinFunction): 864 r""" 865 The confluent hypergeometric function of the first kind, 866 `y = M(a,b,z)`, is defined to be the solution to Kummer's differential 867 equation 868 869 .. math:: 870 871 zy'' + (b-z)y' - ay = 0. 872 873 This is not the same as Kummer's `U`-hypergeometric function, though it 874 satisfies the same DE that `M` does. 875 876 .. warning:: 877 878 In the literature, both are called "Kummer confluent 879 hypergeometric" functions. 880 881 EXAMPLES:: 882 883 sage: hypergeometric_M(1, 1, 1) 884 hypergeometric_M(1, 1, 1) 885 sage: hypergeometric_M(1, 1, 1.) 886 2.71828182845905 887 sage: hypergeometric_M(1, 1, 1).n(70) 888 2.7182818284590452354 889 sage: hypergeometric_M(1, 1, 1).simplify_hypergeometric() 890 e 891 sage: hypergeometric_M(1, 1/2, x).simplify_hypergeometric() 892 (-I*sqrt(pi)*x*e^x*erf(I*sqrt(-x)) + sqrt(-x))/sqrt(-x) 893 sage: hypergeometric_M(1, 3/2, 1).simplify_hypergeometric() 894 1/2*sqrt(pi)*e*erf(1) 895 """ 896 def __init__(self): 897 BuiltinFunction.__init__(self, 'hypergeometric_M', nargs=3, 898 conversions={'mathematica': 899 'Hypergeometric1F1', 900 'maxima': 'kummer_m'}, 901 latex_name='M') 902 903 def _eval_(self, a, b, z, **kwargs): 904 cm = get_coercion_model() 905 co = cm.canonical_coercion(cm.canonical_coercion(a, b)[0], z)[0] 906 if is_inexact(co) and not isinstance(co, Expression): 907 from sage.structure.coerce import parent 908 return self._evalf_(a, b, z, parent=parent(co)) 909 if not isinstance(z, Expression) and z == 0: 910 return Integer(1) 911 return 912 913 def _evalf_(self, a, b, z, parent): 914 from mpmath import hyp1f1 915 return mpmath_utils.call(hyp1f1, a, b, z, parent=parent) 916 917 def _derivative_(self, a, b, z, diff_param): 918 if diff_param == 2: 919 return (a / b) * hypergeometric_M(a + 1, b + 1, z) 920 raise NotImplementedError('derivative of hypergeometric function ' 921 'with respect to parameters') 922 923 class EvaluationMethods: 924 def generalized(cls, self, a, b, z): 925 """ 926 Return as a generalized hypergeometric function 927 928 EXAMPLES:: 929 930 sage: a, b, z = var('a b z') 931 sage: hypergeometric_M(a, b, z).generalized() 932 hypergeometric((a,), (b,), z) 933 934 """ 935 return hypergeometric([a], [b], z) 936 937 hypergeometric_M = Hypergeometric_M() 938 939 class Hypergeometric_U(BuiltinFunction): 940 r""" 941 The confluent hypergeometric function of the second kind, 942 `y = U(a,b,z)`, is defined to be the solution to Kummer's differential 943 equation 944 945 .. math:: 946 947 zy'' + (b-z)y' - ay = 0. 948 949 This satisfies `U(a,b,z) \sim z^{-a}`, as 950 `z\rightarrow \infty`, and is sometimes denoted 951 `z^{-a}{}_2F_0(a,1+a-b;;-1/z)`. This is not the same as Kummer's 952 `M`-hypergeometric function, denoted sometimes as 953 `_1F_1(\alpha,\beta,z)`, though it satisfies the same DE that 954 `U` does. 955 956 .. warning:: 957 958 In the literature, both are called "Kummer confluent 959 hypergeometric" functions. 960 961 EXAMPLES:: 962 963 sage: hypergeometric_U(1, 1, 1) 964 hypergeometric_U(1, 1, 1) 965 sage: hypergeometric_U(1, 1, 1.) 966 0.596347362323194 967 sage: hypergeometric_U(1, 1, 1).n(70) 968 0.59634736232319407434 969 sage: hypergeometric_U(10^4, 1/3, 1).n() 970 6.60377008885811e-35745 971 sage: hypergeometric_U(2 + I, 2, 1).n() 972 0.183481989942099 - 0.458685959185190*I 973 sage: hypergeometric_U(1, 3, x).simplify_hypergeometric() 974 (x + 1)/x^2 975 sage: hypergeometric_U(1, 2, 2).simplify_hypergeometric() 976 1/2 977 978 """ 979 def __init__(self): 980 BuiltinFunction.__init__(self, 'hypergeometric_U', nargs=3, 981 conversions={'mathematica': 982 'HypergeometricU', 983 'maxima': 'kummer_u'}, 984 latex_name='U') 985 986 def _eval_(self, a, b, z, **kwargs): 987 cm = get_coercion_model() 988 co = cm.canonical_coercion(cm.canonical_coercion(a, b)[0], z)[0] 989 if is_inexact(co) and not isinstance(co, Expression): 990 from sage.structure.coerce import parent 991 return self._evalf_(a, b, z, parent=parent(co)) 992 return 993 994 def _evalf_(self, a, b, z, parent): 995 from mpmath import hyperu 996 return mpmath_utils.call(hyperu, a, b, z, parent=parent) 997 998 def _derivative_(self, a, b, z, diff_param): 999 if diff_param == 2: 1000 return -a * hypergeometric_U(a + 1, b + 1, z) 1001 raise NotImplementedError('derivative of hypergeometric function ' 1002 'with respect to parameters') 1003 1004 class EvaluationMethods: 1005 def generalized(cls, self, a, b, z): 1006 """ 1007 Return in terms of the generalized hypergeometric function 1008 1009 EXAMPLES:: 1010 1011 sage: a, b, z = var('a b z') 1012 sage: hypergeometric_U(a, b, z).generalized() 1013 z^(-a)*hypergeometric((a, a - b + 1), (), -1/z) 1014 sage: hypergeometric_U(1, 3, 1/2).generalized() 1015 2*hypergeometric((1, -1), (), -2) 1016 sage: hypergeometric_U(3, I, 2).generalized() 1017 1/8*hypergeometric((3, -I + 4), (), -1/2) 1018 1019 """ 1020 return z ** (-a) * hypergeometric([a, a - b + 1], [], -z ** (-1)) 1021 1022 hypergeometric_U = Hypergeometric_U() -
sage/functions/special.py
diff --git a/sage/functions/special.py b/sage/functions/special.py
a b 175 175 y_n(x) = \sqrt{\frac{\pi}{2x}} Y_{n+1/2}(x) = (-1)^{n+1} \sqrt{\frac{\pi}{2x}} J_{-n-1/2}(x). 176 176 177 177 178 179 - For `x>0`, the confluent hypergeometric function180 `y = U(a,b,x)` is defined to be the solution to Kummer's181 differential equation182 183 184 .. math::185 186 xy'' + (b-x)y' - ay = 0,187 188 which satisfies `U(a,b,x) \sim x^{-a}`, as189 `x\rightarrow \infty`. (There is a linearly independent190 solution, called Kummer's function `M(a,b,x)`, which is not191 implemented.)192 193 178 - Jacobi elliptic functions can be thought of as generalizations 194 179 of both ordinary and hyperbolic trig functions. There are twelve 195 180 Jacobian elliptic functions. Each of the twelve corresponds to an … … 349 334 - Online Encyclopedia of Special Function 350 335 http://algo.inria.fr/esf/index.html 351 336 352 TODO: Resolve weird bug in commented out code in hypergeometric_U353 below.354 355 337 AUTHORS: 356 338 357 339 - David Joyner and William Stein … … 1216 1198 f = lambda z: bessel_Y(nu,z,s) 1217 1199 P = plot(f,a,b) 1218 1200 return P 1219 1220 def hypergeometric_U(alpha,beta,x,algorithm="pari",prec=53):1221 r"""1222 Default is a wrap of PARI's hyperu(alpha,beta,x) function.1223 Optionally, algorithm = "scipy" can be used.1224 1225 The confluent hypergeometric function `y = U(a,b,x)` is1226 defined to be the solution to Kummer's differential equation1227 1228 .. math::1229 1230 xy'' + (b-x)y' - ay = 0.1231 1232 This satisfies `U(a,b,x) \sim x^{-a}`, as1233 `x\rightarrow \infty`, and is sometimes denoted1234 ``x^{-a}2_F_0(a,1+a-b,-1/x)``. This is not the same as Kummer's1235 `M`-hypergeometric function, denoted sometimes as1236 ``_1F_1(alpha,beta,x)``, though it satisfies the same DE that1237 `U` does.1238 1239 .. warning::1240 1241 In the literature, both are called "Kummer confluent1242 hypergeometric" functions.1243 1244 EXAMPLES::1245 1246 sage: hypergeometric_U(1,1,1,"scipy")1247 0.596347362323...1248 sage: hypergeometric_U(1,1,1)1249 0.59634736232319...1250 sage: hypergeometric_U(1,1,1,"pari",70)1251 0.59634736232319407434...1252 """1253 if algorithm=="scipy":1254 if prec != 53:1255 raise ValueError, "for the scipy algorithm the precision must be 53"1256 import scipy.special1257 ans = str(scipy.special.hyperu(float(alpha),float(beta),float(x)))1258 ans = ans.replace("(","")1259 ans = ans.replace(")","")1260 ans = ans.replace("j","*I")1261 return sage_eval(ans)1262 elif algorithm=='pari':1263 from sage.libs.pari.all import pari1264 R = RealField(prec)1265 return R(pari(R(alpha)).hyperu(R(beta), R(x), precision=prec))1266 else:1267 raise ValueError, "unknown algorithm '%s'"%algorithm1268 1201 1269 1202 def spherical_bessel_J(n, var, algorithm="maxima"): 1270 1203 r""" -
sage/symbolic/expression.pyx
diff --git a/sage/symbolic/expression.pyx b/sage/symbolic/expression.pyx
a b 7481 7481 7482 7482 def simplify_hypergeometric(self, algorithm='maxima'): 7483 7483 """ 7484 Simplify an expression containing hypergeometric functions 7484 Simplify an expression containing hypergeometric or confluent 7485 hypergeometric functions 7485 7486 7486 7487 INPUT: 7487 7488 … … 7509 7510 sage: (nest(lambda y: hypergeometric([y], [1], x), 3, 1) 7510 7511 ....: .simplify_hypergeometric(algorithm='sage')) 7511 7512 hypergeometric((hypergeometric((e^x,), (1,), x),), (1,), x) 7512 7513 """ 7514 from sage.functions.hypergeometric import hypergeometric, closed_form 7513 sage: hypergeometric_M(1, 3, x).simplify_hypergeometric() 7514 -2*(x - e^x + 1)/x^2 7515 sage: (2 * hypergeometric_U(1, 3, x)).simplify_hypergeometric() 7516 2*(x + 1)/x^2 7517 7518 """ 7519 from sage.functions.hypergeometric import (hypergeometric, 7520 hypergeometric_M, 7521 hypergeometric_U, 7522 closed_form) 7515 7523 from sage.calculus.calculus import maxima 7516 7524 try: 7517 7525 op = self.operator() 7518 7526 except RuntimeError: 7519 7527 return self 7520 7528 ops = self.operands() 7529 if op == hypergeometric_M or op == hypergeometric_U: 7530 return self.generalized().simplify_hypergeometric(algorithm) 7521 7531 if op == hypergeometric: 7522 7532 if algorithm == 'maxima': 7523 7533 return (self.parent()