polynomials.py 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447
  1. """
  2. This module mainly implements special orthogonal polynomials.
  3. See also functions.combinatorial.numbers which contains some
  4. combinatorial polynomials.
  5. """
  6. from sympy.core import Rational
  7. from sympy.core.function import Function, ArgumentIndexError
  8. from sympy.core.singleton import S
  9. from sympy.core.symbol import Dummy
  10. from sympy.functions.combinatorial.factorials import binomial, factorial, RisingFactorial
  11. from sympy.functions.elementary.complexes import re
  12. from sympy.functions.elementary.exponential import exp
  13. from sympy.functions.elementary.integers import floor
  14. from sympy.functions.elementary.miscellaneous import sqrt
  15. from sympy.functions.elementary.trigonometric import cos, sec
  16. from sympy.functions.special.gamma_functions import gamma
  17. from sympy.functions.special.hyper import hyper
  18. from sympy.polys.orthopolys import (chebyshevt_poly, chebyshevu_poly,
  19. gegenbauer_poly, hermite_poly, hermite_prob_poly,
  20. jacobi_poly, laguerre_poly, legendre_poly)
  21. _x = Dummy('x')
  22. class OrthogonalPolynomial(Function):
  23. """Base class for orthogonal polynomials.
  24. """
  25. @classmethod
  26. def _eval_at_order(cls, n, x):
  27. if n.is_integer and n >= 0:
  28. return cls._ortho_poly(int(n), _x).subs(_x, x)
  29. def _eval_conjugate(self):
  30. return self.func(self.args[0], self.args[1].conjugate())
  31. #----------------------------------------------------------------------------
  32. # Jacobi polynomials
  33. #
  34. class jacobi(OrthogonalPolynomial):
  35. r"""
  36. Jacobi polynomial $P_n^{\left(\alpha, \beta\right)}(x)$.
  37. Explanation
  38. ===========
  39. ``jacobi(n, alpha, beta, x)`` gives the $n$th Jacobi polynomial
  40. in $x$, $P_n^{\left(\alpha, \beta\right)}(x)$.
  41. The Jacobi polynomials are orthogonal on $[-1, 1]$ with respect
  42. to the weight $\left(1-x\right)^\alpha \left(1+x\right)^\beta$.
  43. Examples
  44. ========
  45. >>> from sympy import jacobi, S, conjugate, diff
  46. >>> from sympy.abc import a, b, n, x
  47. >>> jacobi(0, a, b, x)
  48. 1
  49. >>> jacobi(1, a, b, x)
  50. a/2 - b/2 + x*(a/2 + b/2 + 1)
  51. >>> jacobi(2, a, b, x)
  52. 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 + 3/2) + x*(a**2/4 + 3*a/4 - b**2/4 - 3*b/4) - 1/2
  53. >>> jacobi(n, a, b, x)
  54. jacobi(n, a, b, x)
  55. >>> jacobi(n, a, a, x)
  56. RisingFactorial(a + 1, n)*gegenbauer(n,
  57. a + 1/2, x)/RisingFactorial(2*a + 1, n)
  58. >>> jacobi(n, 0, 0, x)
  59. legendre(n, x)
  60. >>> jacobi(n, S(1)/2, S(1)/2, x)
  61. RisingFactorial(3/2, n)*chebyshevu(n, x)/factorial(n + 1)
  62. >>> jacobi(n, -S(1)/2, -S(1)/2, x)
  63. RisingFactorial(1/2, n)*chebyshevt(n, x)/factorial(n)
  64. >>> jacobi(n, a, b, -x)
  65. (-1)**n*jacobi(n, b, a, x)
  66. >>> jacobi(n, a, b, 0)
  67. gamma(a + n + 1)*hyper((-b - n, -n), (a + 1,), -1)/(2**n*factorial(n)*gamma(a + 1))
  68. >>> jacobi(n, a, b, 1)
  69. RisingFactorial(a + 1, n)/factorial(n)
  70. >>> conjugate(jacobi(n, a, b, x))
  71. jacobi(n, conjugate(a), conjugate(b), conjugate(x))
  72. >>> diff(jacobi(n,a,b,x), x)
  73. (a/2 + b/2 + n/2 + 1/2)*jacobi(n - 1, a + 1, b + 1, x)
  74. See Also
  75. ========
  76. gegenbauer,
  77. chebyshevt_root, chebyshevu, chebyshevu_root,
  78. legendre, assoc_legendre,
  79. hermite, hermite_prob,
  80. laguerre, assoc_laguerre,
  81. sympy.polys.orthopolys.jacobi_poly,
  82. sympy.polys.orthopolys.gegenbauer_poly
  83. sympy.polys.orthopolys.chebyshevt_poly
  84. sympy.polys.orthopolys.chebyshevu_poly
  85. sympy.polys.orthopolys.hermite_poly
  86. sympy.polys.orthopolys.legendre_poly
  87. sympy.polys.orthopolys.laguerre_poly
  88. References
  89. ==========
  90. .. [1] https://en.wikipedia.org/wiki/Jacobi_polynomials
  91. .. [2] https://mathworld.wolfram.com/JacobiPolynomial.html
  92. .. [3] https://functions.wolfram.com/Polynomials/JacobiP/
  93. """
  94. @classmethod
  95. def eval(cls, n, a, b, x):
  96. # Simplify to other polynomials
  97. # P^{a, a}_n(x)
  98. if a == b:
  99. if a == Rational(-1, 2):
  100. return RisingFactorial(S.Half, n) / factorial(n) * chebyshevt(n, x)
  101. elif a.is_zero:
  102. return legendre(n, x)
  103. elif a == S.Half:
  104. return RisingFactorial(3*S.Half, n) / factorial(n + 1) * chebyshevu(n, x)
  105. else:
  106. return RisingFactorial(a + 1, n) / RisingFactorial(2*a + 1, n) * gegenbauer(n, a + S.Half, x)
  107. elif b == -a:
  108. # P^{a, -a}_n(x)
  109. return gamma(n + a + 1) / gamma(n + 1) * (1 + x)**(a/2) / (1 - x)**(a/2) * assoc_legendre(n, -a, x)
  110. if not n.is_Number:
  111. # Symbolic result P^{a,b}_n(x)
  112. # P^{a,b}_n(-x) ---> (-1)**n * P^{b,a}_n(-x)
  113. if x.could_extract_minus_sign():
  114. return S.NegativeOne**n * jacobi(n, b, a, -x)
  115. # We can evaluate for some special values of x
  116. if x.is_zero:
  117. return (2**(-n) * gamma(a + n + 1) / (gamma(a + 1) * factorial(n)) *
  118. hyper([-b - n, -n], [a + 1], -1))
  119. if x == S.One:
  120. return RisingFactorial(a + 1, n) / factorial(n)
  121. elif x is S.Infinity:
  122. if n.is_positive:
  123. # Make sure a+b+2*n \notin Z
  124. if (a + b + 2*n).is_integer:
  125. raise ValueError("Error. a + b + 2*n should not be an integer.")
  126. return RisingFactorial(a + b + n + 1, n) * S.Infinity
  127. else:
  128. # n is a given fixed integer, evaluate into polynomial
  129. return jacobi_poly(n, a, b, x)
  130. def fdiff(self, argindex=4):
  131. from sympy.concrete.summations import Sum
  132. if argindex == 1:
  133. # Diff wrt n
  134. raise ArgumentIndexError(self, argindex)
  135. elif argindex == 2:
  136. # Diff wrt a
  137. n, a, b, x = self.args
  138. k = Dummy("k")
  139. f1 = 1 / (a + b + n + k + 1)
  140. f2 = ((a + b + 2*k + 1) * RisingFactorial(b + k + 1, n - k) /
  141. ((n - k) * RisingFactorial(a + b + k + 1, n - k)))
  142. return Sum(f1 * (jacobi(n, a, b, x) + f2*jacobi(k, a, b, x)), (k, 0, n - 1))
  143. elif argindex == 3:
  144. # Diff wrt b
  145. n, a, b, x = self.args
  146. k = Dummy("k")
  147. f1 = 1 / (a + b + n + k + 1)
  148. f2 = (-1)**(n - k) * ((a + b + 2*k + 1) * RisingFactorial(a + k + 1, n - k) /
  149. ((n - k) * RisingFactorial(a + b + k + 1, n - k)))
  150. return Sum(f1 * (jacobi(n, a, b, x) + f2*jacobi(k, a, b, x)), (k, 0, n - 1))
  151. elif argindex == 4:
  152. # Diff wrt x
  153. n, a, b, x = self.args
  154. return S.Half * (a + b + n + 1) * jacobi(n - 1, a + 1, b + 1, x)
  155. else:
  156. raise ArgumentIndexError(self, argindex)
  157. def _eval_rewrite_as_Sum(self, n, a, b, x, **kwargs):
  158. from sympy.concrete.summations import Sum
  159. # Make sure n \in N
  160. if n.is_negative or n.is_integer is False:
  161. raise ValueError("Error: n should be a non-negative integer.")
  162. k = Dummy("k")
  163. kern = (RisingFactorial(-n, k) * RisingFactorial(a + b + n + 1, k) * RisingFactorial(a + k + 1, n - k) /
  164. factorial(k) * ((1 - x)/2)**k)
  165. return 1 / factorial(n) * Sum(kern, (k, 0, n))
  166. def _eval_rewrite_as_polynomial(self, n, a, b, x, **kwargs):
  167. # This function is just kept for backwards compatibility
  168. # but should not be used
  169. return self._eval_rewrite_as_Sum(n, a, b, x, **kwargs)
  170. def _eval_conjugate(self):
  171. n, a, b, x = self.args
  172. return self.func(n, a.conjugate(), b.conjugate(), x.conjugate())
  173. def jacobi_normalized(n, a, b, x):
  174. r"""
  175. Jacobi polynomial $P_n^{\left(\alpha, \beta\right)}(x)$.
  176. Explanation
  177. ===========
  178. ``jacobi_normalized(n, alpha, beta, x)`` gives the $n$th
  179. Jacobi polynomial in $x$, $P_n^{\left(\alpha, \beta\right)}(x)$.
  180. The Jacobi polynomials are orthogonal on $[-1, 1]$ with respect
  181. to the weight $\left(1-x\right)^\alpha \left(1+x\right)^\beta$.
  182. This functions returns the polynomials normilzed:
  183. .. math::
  184. \int_{-1}^{1}
  185. P_m^{\left(\alpha, \beta\right)}(x)
  186. P_n^{\left(\alpha, \beta\right)}(x)
  187. (1-x)^{\alpha} (1+x)^{\beta} \mathrm{d}x
  188. = \delta_{m,n}
  189. Examples
  190. ========
  191. >>> from sympy import jacobi_normalized
  192. >>> from sympy.abc import n,a,b,x
  193. >>> jacobi_normalized(n, a, b, x)
  194. jacobi(n, a, b, x)/sqrt(2**(a + b + 1)*gamma(a + n + 1)*gamma(b + n + 1)/((a + b + 2*n + 1)*factorial(n)*gamma(a + b + n + 1)))
  195. Parameters
  196. ==========
  197. n : integer degree of polynomial
  198. a : alpha value
  199. b : beta value
  200. x : symbol
  201. See Also
  202. ========
  203. gegenbauer,
  204. chebyshevt_root, chebyshevu, chebyshevu_root,
  205. legendre, assoc_legendre,
  206. hermite, hermite_prob,
  207. laguerre, assoc_laguerre,
  208. sympy.polys.orthopolys.jacobi_poly,
  209. sympy.polys.orthopolys.gegenbauer_poly
  210. sympy.polys.orthopolys.chebyshevt_poly
  211. sympy.polys.orthopolys.chebyshevu_poly
  212. sympy.polys.orthopolys.hermite_poly
  213. sympy.polys.orthopolys.legendre_poly
  214. sympy.polys.orthopolys.laguerre_poly
  215. References
  216. ==========
  217. .. [1] https://en.wikipedia.org/wiki/Jacobi_polynomials
  218. .. [2] https://mathworld.wolfram.com/JacobiPolynomial.html
  219. .. [3] https://functions.wolfram.com/Polynomials/JacobiP/
  220. """
  221. nfactor = (S(2)**(a + b + 1) * (gamma(n + a + 1) * gamma(n + b + 1))
  222. / (2*n + a + b + 1) / (factorial(n) * gamma(n + a + b + 1)))
  223. return jacobi(n, a, b, x) / sqrt(nfactor)
  224. #----------------------------------------------------------------------------
  225. # Gegenbauer polynomials
  226. #
  227. class gegenbauer(OrthogonalPolynomial):
  228. r"""
  229. Gegenbauer polynomial $C_n^{\left(\alpha\right)}(x)$.
  230. Explanation
  231. ===========
  232. ``gegenbauer(n, alpha, x)`` gives the $n$th Gegenbauer polynomial
  233. in $x$, $C_n^{\left(\alpha\right)}(x)$.
  234. The Gegenbauer polynomials are orthogonal on $[-1, 1]$ with
  235. respect to the weight $\left(1-x^2\right)^{\alpha-\frac{1}{2}}$.
  236. Examples
  237. ========
  238. >>> from sympy import gegenbauer, conjugate, diff
  239. >>> from sympy.abc import n,a,x
  240. >>> gegenbauer(0, a, x)
  241. 1
  242. >>> gegenbauer(1, a, x)
  243. 2*a*x
  244. >>> gegenbauer(2, a, x)
  245. -a + x**2*(2*a**2 + 2*a)
  246. >>> gegenbauer(3, a, x)
  247. x**3*(4*a**3/3 + 4*a**2 + 8*a/3) + x*(-2*a**2 - 2*a)
  248. >>> gegenbauer(n, a, x)
  249. gegenbauer(n, a, x)
  250. >>> gegenbauer(n, a, -x)
  251. (-1)**n*gegenbauer(n, a, x)
  252. >>> gegenbauer(n, a, 0)
  253. 2**n*sqrt(pi)*gamma(a + n/2)/(gamma(a)*gamma(1/2 - n/2)*gamma(n + 1))
  254. >>> gegenbauer(n, a, 1)
  255. gamma(2*a + n)/(gamma(2*a)*gamma(n + 1))
  256. >>> conjugate(gegenbauer(n, a, x))
  257. gegenbauer(n, conjugate(a), conjugate(x))
  258. >>> diff(gegenbauer(n, a, x), x)
  259. 2*a*gegenbauer(n - 1, a + 1, x)
  260. See Also
  261. ========
  262. jacobi,
  263. chebyshevt_root, chebyshevu, chebyshevu_root,
  264. legendre, assoc_legendre,
  265. hermite, hermite_prob,
  266. laguerre, assoc_laguerre,
  267. sympy.polys.orthopolys.jacobi_poly
  268. sympy.polys.orthopolys.gegenbauer_poly
  269. sympy.polys.orthopolys.chebyshevt_poly
  270. sympy.polys.orthopolys.chebyshevu_poly
  271. sympy.polys.orthopolys.hermite_poly
  272. sympy.polys.orthopolys.hermite_prob_poly
  273. sympy.polys.orthopolys.legendre_poly
  274. sympy.polys.orthopolys.laguerre_poly
  275. References
  276. ==========
  277. .. [1] https://en.wikipedia.org/wiki/Gegenbauer_polynomials
  278. .. [2] https://mathworld.wolfram.com/GegenbauerPolynomial.html
  279. .. [3] https://functions.wolfram.com/Polynomials/GegenbauerC3/
  280. """
  281. @classmethod
  282. def eval(cls, n, a, x):
  283. # For negative n the polynomials vanish
  284. # See https://functions.wolfram.com/Polynomials/GegenbauerC3/03/01/03/0012/
  285. if n.is_negative:
  286. return S.Zero
  287. # Some special values for fixed a
  288. if a == S.Half:
  289. return legendre(n, x)
  290. elif a == S.One:
  291. return chebyshevu(n, x)
  292. elif a == S.NegativeOne:
  293. return S.Zero
  294. if not n.is_Number:
  295. # Handle this before the general sign extraction rule
  296. if x == S.NegativeOne:
  297. if (re(a) > S.Half) == True:
  298. return S.ComplexInfinity
  299. else:
  300. return (cos(S.Pi*(a+n)) * sec(S.Pi*a) * gamma(2*a+n) /
  301. (gamma(2*a) * gamma(n+1)))
  302. # Symbolic result C^a_n(x)
  303. # C^a_n(-x) ---> (-1)**n * C^a_n(x)
  304. if x.could_extract_minus_sign():
  305. return S.NegativeOne**n * gegenbauer(n, a, -x)
  306. # We can evaluate for some special values of x
  307. if x.is_zero:
  308. return (2**n * sqrt(S.Pi) * gamma(a + S.Half*n) /
  309. (gamma((1 - n)/2) * gamma(n + 1) * gamma(a)) )
  310. if x == S.One:
  311. return gamma(2*a + n) / (gamma(2*a) * gamma(n + 1))
  312. elif x is S.Infinity:
  313. if n.is_positive:
  314. return RisingFactorial(a, n) * S.Infinity
  315. else:
  316. # n is a given fixed integer, evaluate into polynomial
  317. return gegenbauer_poly(n, a, x)
  318. def fdiff(self, argindex=3):
  319. from sympy.concrete.summations import Sum
  320. if argindex == 1:
  321. # Diff wrt n
  322. raise ArgumentIndexError(self, argindex)
  323. elif argindex == 2:
  324. # Diff wrt a
  325. n, a, x = self.args
  326. k = Dummy("k")
  327. factor1 = 2 * (1 + (-1)**(n - k)) * (k + a) / ((k +
  328. n + 2*a) * (n - k))
  329. factor2 = 2*(k + 1) / ((k + 2*a) * (2*k + 2*a + 1)) + \
  330. 2 / (k + n + 2*a)
  331. kern = factor1*gegenbauer(k, a, x) + factor2*gegenbauer(n, a, x)
  332. return Sum(kern, (k, 0, n - 1))
  333. elif argindex == 3:
  334. # Diff wrt x
  335. n, a, x = self.args
  336. return 2*a*gegenbauer(n - 1, a + 1, x)
  337. else:
  338. raise ArgumentIndexError(self, argindex)
  339. def _eval_rewrite_as_Sum(self, n, a, x, **kwargs):
  340. from sympy.concrete.summations import Sum
  341. k = Dummy("k")
  342. kern = ((-1)**k * RisingFactorial(a, n - k) * (2*x)**(n - 2*k) /
  343. (factorial(k) * factorial(n - 2*k)))
  344. return Sum(kern, (k, 0, floor(n/2)))
  345. def _eval_rewrite_as_polynomial(self, n, a, x, **kwargs):
  346. # This function is just kept for backwards compatibility
  347. # but should not be used
  348. return self._eval_rewrite_as_Sum(n, a, x, **kwargs)
  349. def _eval_conjugate(self):
  350. n, a, x = self.args
  351. return self.func(n, a.conjugate(), x.conjugate())
  352. #----------------------------------------------------------------------------
  353. # Chebyshev polynomials of first and second kind
  354. #
  355. class chebyshevt(OrthogonalPolynomial):
  356. r"""
  357. Chebyshev polynomial of the first kind, $T_n(x)$.
  358. Explanation
  359. ===========
  360. ``chebyshevt(n, x)`` gives the $n$th Chebyshev polynomial (of the first
  361. kind) in $x$, $T_n(x)$.
  362. The Chebyshev polynomials of the first kind are orthogonal on
  363. $[-1, 1]$ with respect to the weight $\frac{1}{\sqrt{1-x^2}}$.
  364. Examples
  365. ========
  366. >>> from sympy import chebyshevt, diff
  367. >>> from sympy.abc import n,x
  368. >>> chebyshevt(0, x)
  369. 1
  370. >>> chebyshevt(1, x)
  371. x
  372. >>> chebyshevt(2, x)
  373. 2*x**2 - 1
  374. >>> chebyshevt(n, x)
  375. chebyshevt(n, x)
  376. >>> chebyshevt(n, -x)
  377. (-1)**n*chebyshevt(n, x)
  378. >>> chebyshevt(-n, x)
  379. chebyshevt(n, x)
  380. >>> chebyshevt(n, 0)
  381. cos(pi*n/2)
  382. >>> chebyshevt(n, -1)
  383. (-1)**n
  384. >>> diff(chebyshevt(n, x), x)
  385. n*chebyshevu(n - 1, x)
  386. See Also
  387. ========
  388. jacobi, gegenbauer,
  389. chebyshevt_root, chebyshevu, chebyshevu_root,
  390. legendre, assoc_legendre,
  391. hermite, hermite_prob,
  392. laguerre, assoc_laguerre,
  393. sympy.polys.orthopolys.jacobi_poly
  394. sympy.polys.orthopolys.gegenbauer_poly
  395. sympy.polys.orthopolys.chebyshevt_poly
  396. sympy.polys.orthopolys.chebyshevu_poly
  397. sympy.polys.orthopolys.hermite_poly
  398. sympy.polys.orthopolys.hermite_prob_poly
  399. sympy.polys.orthopolys.legendre_poly
  400. sympy.polys.orthopolys.laguerre_poly
  401. References
  402. ==========
  403. .. [1] https://en.wikipedia.org/wiki/Chebyshev_polynomial
  404. .. [2] https://mathworld.wolfram.com/ChebyshevPolynomialoftheFirstKind.html
  405. .. [3] https://mathworld.wolfram.com/ChebyshevPolynomialoftheSecondKind.html
  406. .. [4] https://functions.wolfram.com/Polynomials/ChebyshevT/
  407. .. [5] https://functions.wolfram.com/Polynomials/ChebyshevU/
  408. """
  409. _ortho_poly = staticmethod(chebyshevt_poly)
  410. @classmethod
  411. def eval(cls, n, x):
  412. if not n.is_Number:
  413. # Symbolic result T_n(x)
  414. # T_n(-x) ---> (-1)**n * T_n(x)
  415. if x.could_extract_minus_sign():
  416. return S.NegativeOne**n * chebyshevt(n, -x)
  417. # T_{-n}(x) ---> T_n(x)
  418. if n.could_extract_minus_sign():
  419. return chebyshevt(-n, x)
  420. # We can evaluate for some special values of x
  421. if x.is_zero:
  422. return cos(S.Half * S.Pi * n)
  423. if x == S.One:
  424. return S.One
  425. elif x is S.Infinity:
  426. return S.Infinity
  427. else:
  428. # n is a given fixed integer, evaluate into polynomial
  429. if n.is_negative:
  430. # T_{-n}(x) == T_n(x)
  431. return cls._eval_at_order(-n, x)
  432. else:
  433. return cls._eval_at_order(n, x)
  434. def fdiff(self, argindex=2):
  435. if argindex == 1:
  436. # Diff wrt n
  437. raise ArgumentIndexError(self, argindex)
  438. elif argindex == 2:
  439. # Diff wrt x
  440. n, x = self.args
  441. return n * chebyshevu(n - 1, x)
  442. else:
  443. raise ArgumentIndexError(self, argindex)
  444. def _eval_rewrite_as_Sum(self, n, x, **kwargs):
  445. from sympy.concrete.summations import Sum
  446. k = Dummy("k")
  447. kern = binomial(n, 2*k) * (x**2 - 1)**k * x**(n - 2*k)
  448. return Sum(kern, (k, 0, floor(n/2)))
  449. def _eval_rewrite_as_polynomial(self, n, x, **kwargs):
  450. # This function is just kept for backwards compatibility
  451. # but should not be used
  452. return self._eval_rewrite_as_Sum(n, x, **kwargs)
  453. class chebyshevu(OrthogonalPolynomial):
  454. r"""
  455. Chebyshev polynomial of the second kind, $U_n(x)$.
  456. Explanation
  457. ===========
  458. ``chebyshevu(n, x)`` gives the $n$th Chebyshev polynomial of the second
  459. kind in x, $U_n(x)$.
  460. The Chebyshev polynomials of the second kind are orthogonal on
  461. $[-1, 1]$ with respect to the weight $\sqrt{1-x^2}$.
  462. Examples
  463. ========
  464. >>> from sympy import chebyshevu, diff
  465. >>> from sympy.abc import n,x
  466. >>> chebyshevu(0, x)
  467. 1
  468. >>> chebyshevu(1, x)
  469. 2*x
  470. >>> chebyshevu(2, x)
  471. 4*x**2 - 1
  472. >>> chebyshevu(n, x)
  473. chebyshevu(n, x)
  474. >>> chebyshevu(n, -x)
  475. (-1)**n*chebyshevu(n, x)
  476. >>> chebyshevu(-n, x)
  477. -chebyshevu(n - 2, x)
  478. >>> chebyshevu(n, 0)
  479. cos(pi*n/2)
  480. >>> chebyshevu(n, 1)
  481. n + 1
  482. >>> diff(chebyshevu(n, x), x)
  483. (-x*chebyshevu(n, x) + (n + 1)*chebyshevt(n + 1, x))/(x**2 - 1)
  484. See Also
  485. ========
  486. jacobi, gegenbauer,
  487. chebyshevt, chebyshevt_root, chebyshevu_root,
  488. legendre, assoc_legendre,
  489. hermite, hermite_prob,
  490. laguerre, assoc_laguerre,
  491. sympy.polys.orthopolys.jacobi_poly
  492. sympy.polys.orthopolys.gegenbauer_poly
  493. sympy.polys.orthopolys.chebyshevt_poly
  494. sympy.polys.orthopolys.chebyshevu_poly
  495. sympy.polys.orthopolys.hermite_poly
  496. sympy.polys.orthopolys.hermite_prob_poly
  497. sympy.polys.orthopolys.legendre_poly
  498. sympy.polys.orthopolys.laguerre_poly
  499. References
  500. ==========
  501. .. [1] https://en.wikipedia.org/wiki/Chebyshev_polynomial
  502. .. [2] https://mathworld.wolfram.com/ChebyshevPolynomialoftheFirstKind.html
  503. .. [3] https://mathworld.wolfram.com/ChebyshevPolynomialoftheSecondKind.html
  504. .. [4] https://functions.wolfram.com/Polynomials/ChebyshevT/
  505. .. [5] https://functions.wolfram.com/Polynomials/ChebyshevU/
  506. """
  507. _ortho_poly = staticmethod(chebyshevu_poly)
  508. @classmethod
  509. def eval(cls, n, x):
  510. if not n.is_Number:
  511. # Symbolic result U_n(x)
  512. # U_n(-x) ---> (-1)**n * U_n(x)
  513. if x.could_extract_minus_sign():
  514. return S.NegativeOne**n * chebyshevu(n, -x)
  515. # U_{-n}(x) ---> -U_{n-2}(x)
  516. if n.could_extract_minus_sign():
  517. if n == S.NegativeOne:
  518. # n can not be -1 here
  519. return S.Zero
  520. elif not (-n - 2).could_extract_minus_sign():
  521. return -chebyshevu(-n - 2, x)
  522. # We can evaluate for some special values of x
  523. if x.is_zero:
  524. return cos(S.Half * S.Pi * n)
  525. if x == S.One:
  526. return S.One + n
  527. elif x is S.Infinity:
  528. return S.Infinity
  529. else:
  530. # n is a given fixed integer, evaluate into polynomial
  531. if n.is_negative:
  532. # U_{-n}(x) ---> -U_{n-2}(x)
  533. if n == S.NegativeOne:
  534. return S.Zero
  535. else:
  536. return -cls._eval_at_order(-n - 2, x)
  537. else:
  538. return cls._eval_at_order(n, x)
  539. def fdiff(self, argindex=2):
  540. if argindex == 1:
  541. # Diff wrt n
  542. raise ArgumentIndexError(self, argindex)
  543. elif argindex == 2:
  544. # Diff wrt x
  545. n, x = self.args
  546. return ((n + 1) * chebyshevt(n + 1, x) - x * chebyshevu(n, x)) / (x**2 - 1)
  547. else:
  548. raise ArgumentIndexError(self, argindex)
  549. def _eval_rewrite_as_Sum(self, n, x, **kwargs):
  550. from sympy.concrete.summations import Sum
  551. k = Dummy("k")
  552. kern = S.NegativeOne**k * factorial(
  553. n - k) * (2*x)**(n - 2*k) / (factorial(k) * factorial(n - 2*k))
  554. return Sum(kern, (k, 0, floor(n/2)))
  555. def _eval_rewrite_as_polynomial(self, n, x, **kwargs):
  556. # This function is just kept for backwards compatibility
  557. # but should not be used
  558. return self._eval_rewrite_as_Sum(n, x, **kwargs)
  559. class chebyshevt_root(Function):
  560. r"""
  561. ``chebyshev_root(n, k)`` returns the $k$th root (indexed from zero) of
  562. the $n$th Chebyshev polynomial of the first kind; that is, if
  563. $0 \le k < n$, ``chebyshevt(n, chebyshevt_root(n, k)) == 0``.
  564. Examples
  565. ========
  566. >>> from sympy import chebyshevt, chebyshevt_root
  567. >>> chebyshevt_root(3, 2)
  568. -sqrt(3)/2
  569. >>> chebyshevt(3, chebyshevt_root(3, 2))
  570. 0
  571. See Also
  572. ========
  573. jacobi, gegenbauer,
  574. chebyshevt, chebyshevu, chebyshevu_root,
  575. legendre, assoc_legendre,
  576. hermite, hermite_prob,
  577. laguerre, assoc_laguerre,
  578. sympy.polys.orthopolys.jacobi_poly
  579. sympy.polys.orthopolys.gegenbauer_poly
  580. sympy.polys.orthopolys.chebyshevt_poly
  581. sympy.polys.orthopolys.chebyshevu_poly
  582. sympy.polys.orthopolys.hermite_poly
  583. sympy.polys.orthopolys.hermite_prob_poly
  584. sympy.polys.orthopolys.legendre_poly
  585. sympy.polys.orthopolys.laguerre_poly
  586. """
  587. @classmethod
  588. def eval(cls, n, k):
  589. if not ((0 <= k) and (k < n)):
  590. raise ValueError("must have 0 <= k < n, "
  591. "got k = %s and n = %s" % (k, n))
  592. return cos(S.Pi*(2*k + 1)/(2*n))
  593. class chebyshevu_root(Function):
  594. r"""
  595. ``chebyshevu_root(n, k)`` returns the $k$th root (indexed from zero) of the
  596. $n$th Chebyshev polynomial of the second kind; that is, if $0 \le k < n$,
  597. ``chebyshevu(n, chebyshevu_root(n, k)) == 0``.
  598. Examples
  599. ========
  600. >>> from sympy import chebyshevu, chebyshevu_root
  601. >>> chebyshevu_root(3, 2)
  602. -sqrt(2)/2
  603. >>> chebyshevu(3, chebyshevu_root(3, 2))
  604. 0
  605. See Also
  606. ========
  607. chebyshevt, chebyshevt_root, chebyshevu,
  608. legendre, assoc_legendre,
  609. hermite, hermite_prob,
  610. laguerre, assoc_laguerre,
  611. sympy.polys.orthopolys.jacobi_poly
  612. sympy.polys.orthopolys.gegenbauer_poly
  613. sympy.polys.orthopolys.chebyshevt_poly
  614. sympy.polys.orthopolys.chebyshevu_poly
  615. sympy.polys.orthopolys.hermite_poly
  616. sympy.polys.orthopolys.hermite_prob_poly
  617. sympy.polys.orthopolys.legendre_poly
  618. sympy.polys.orthopolys.laguerre_poly
  619. """
  620. @classmethod
  621. def eval(cls, n, k):
  622. if not ((0 <= k) and (k < n)):
  623. raise ValueError("must have 0 <= k < n, "
  624. "got k = %s and n = %s" % (k, n))
  625. return cos(S.Pi*(k + 1)/(n + 1))
  626. #----------------------------------------------------------------------------
  627. # Legendre polynomials and Associated Legendre polynomials
  628. #
  629. class legendre(OrthogonalPolynomial):
  630. r"""
  631. ``legendre(n, x)`` gives the $n$th Legendre polynomial of $x$, $P_n(x)$
  632. Explanation
  633. ===========
  634. The Legendre polynomials are orthogonal on $[-1, 1]$ with respect to
  635. the constant weight 1. They satisfy $P_n(1) = 1$ for all $n$; further,
  636. $P_n$ is odd for odd $n$ and even for even $n$.
  637. Examples
  638. ========
  639. >>> from sympy import legendre, diff
  640. >>> from sympy.abc import x, n
  641. >>> legendre(0, x)
  642. 1
  643. >>> legendre(1, x)
  644. x
  645. >>> legendre(2, x)
  646. 3*x**2/2 - 1/2
  647. >>> legendre(n, x)
  648. legendre(n, x)
  649. >>> diff(legendre(n,x), x)
  650. n*(x*legendre(n, x) - legendre(n - 1, x))/(x**2 - 1)
  651. See Also
  652. ========
  653. jacobi, gegenbauer,
  654. chebyshevt, chebyshevt_root, chebyshevu, chebyshevu_root,
  655. assoc_legendre,
  656. hermite, hermite_prob,
  657. laguerre, assoc_laguerre,
  658. sympy.polys.orthopolys.jacobi_poly
  659. sympy.polys.orthopolys.gegenbauer_poly
  660. sympy.polys.orthopolys.chebyshevt_poly
  661. sympy.polys.orthopolys.chebyshevu_poly
  662. sympy.polys.orthopolys.hermite_poly
  663. sympy.polys.orthopolys.hermite_prob_poly
  664. sympy.polys.orthopolys.legendre_poly
  665. sympy.polys.orthopolys.laguerre_poly
  666. References
  667. ==========
  668. .. [1] https://en.wikipedia.org/wiki/Legendre_polynomial
  669. .. [2] https://mathworld.wolfram.com/LegendrePolynomial.html
  670. .. [3] https://functions.wolfram.com/Polynomials/LegendreP/
  671. .. [4] https://functions.wolfram.com/Polynomials/LegendreP2/
  672. """
  673. _ortho_poly = staticmethod(legendre_poly)
  674. @classmethod
  675. def eval(cls, n, x):
  676. if not n.is_Number:
  677. # Symbolic result L_n(x)
  678. # L_n(-x) ---> (-1)**n * L_n(x)
  679. if x.could_extract_minus_sign():
  680. return S.NegativeOne**n * legendre(n, -x)
  681. # L_{-n}(x) ---> L_{n-1}(x)
  682. if n.could_extract_minus_sign() and not(-n - 1).could_extract_minus_sign():
  683. return legendre(-n - S.One, x)
  684. # We can evaluate for some special values of x
  685. if x.is_zero:
  686. return sqrt(S.Pi)/(gamma(S.Half - n/2)*gamma(S.One + n/2))
  687. elif x == S.One:
  688. return S.One
  689. elif x is S.Infinity:
  690. return S.Infinity
  691. else:
  692. # n is a given fixed integer, evaluate into polynomial;
  693. # L_{-n}(x) ---> L_{n-1}(x)
  694. if n.is_negative:
  695. n = -n - S.One
  696. return cls._eval_at_order(n, x)
  697. def fdiff(self, argindex=2):
  698. if argindex == 1:
  699. # Diff wrt n
  700. raise ArgumentIndexError(self, argindex)
  701. elif argindex == 2:
  702. # Diff wrt x
  703. # Find better formula, this is unsuitable for x = +/-1
  704. # https://www.autodiff.org/ad16/Oral/Buecker_Legendre.pdf says
  705. # at x = 1:
  706. # n*(n + 1)/2 , m = 0
  707. # oo , m = 1
  708. # -(n-1)*n*(n+1)*(n+2)/4 , m = 2
  709. # 0 , m = 3, 4, ..., n
  710. #
  711. # at x = -1
  712. # (-1)**(n+1)*n*(n + 1)/2 , m = 0
  713. # (-1)**n*oo , m = 1
  714. # (-1)**n*(n-1)*n*(n+1)*(n+2)/4 , m = 2
  715. # 0 , m = 3, 4, ..., n
  716. n, x = self.args
  717. return n/(x**2 - 1)*(x*legendre(n, x) - legendre(n - 1, x))
  718. else:
  719. raise ArgumentIndexError(self, argindex)
  720. def _eval_rewrite_as_Sum(self, n, x, **kwargs):
  721. from sympy.concrete.summations import Sum
  722. k = Dummy("k")
  723. kern = S.NegativeOne**k*binomial(n, k)**2*((1 + x)/2)**(n - k)*((1 - x)/2)**k
  724. return Sum(kern, (k, 0, n))
  725. def _eval_rewrite_as_polynomial(self, n, x, **kwargs):
  726. # This function is just kept for backwards compatibility
  727. # but should not be used
  728. return self._eval_rewrite_as_Sum(n, x, **kwargs)
  729. class assoc_legendre(Function):
  730. r"""
  731. ``assoc_legendre(n, m, x)`` gives $P_n^m(x)$, where $n$ and $m$ are
  732. the degree and order or an expression which is related to the nth
  733. order Legendre polynomial, $P_n(x)$ in the following manner:
  734. .. math::
  735. P_n^m(x) = (-1)^m (1 - x^2)^{\frac{m}{2}}
  736. \frac{\mathrm{d}^m P_n(x)}{\mathrm{d} x^m}
  737. Explanation
  738. ===========
  739. Associated Legendre polynomials are orthogonal on $[-1, 1]$ with:
  740. - weight $= 1$ for the same $m$ and different $n$.
  741. - weight $= \frac{1}{1-x^2}$ for the same $n$ and different $m$.
  742. Examples
  743. ========
  744. >>> from sympy import assoc_legendre
  745. >>> from sympy.abc import x, m, n
  746. >>> assoc_legendre(0,0, x)
  747. 1
  748. >>> assoc_legendre(1,0, x)
  749. x
  750. >>> assoc_legendre(1,1, x)
  751. -sqrt(1 - x**2)
  752. >>> assoc_legendre(n,m,x)
  753. assoc_legendre(n, m, x)
  754. See Also
  755. ========
  756. jacobi, gegenbauer,
  757. chebyshevt, chebyshevt_root, chebyshevu, chebyshevu_root,
  758. legendre,
  759. hermite, hermite_prob,
  760. laguerre, assoc_laguerre,
  761. sympy.polys.orthopolys.jacobi_poly
  762. sympy.polys.orthopolys.gegenbauer_poly
  763. sympy.polys.orthopolys.chebyshevt_poly
  764. sympy.polys.orthopolys.chebyshevu_poly
  765. sympy.polys.orthopolys.hermite_poly
  766. sympy.polys.orthopolys.hermite_prob_poly
  767. sympy.polys.orthopolys.legendre_poly
  768. sympy.polys.orthopolys.laguerre_poly
  769. References
  770. ==========
  771. .. [1] https://en.wikipedia.org/wiki/Associated_Legendre_polynomials
  772. .. [2] https://mathworld.wolfram.com/LegendrePolynomial.html
  773. .. [3] https://functions.wolfram.com/Polynomials/LegendreP/
  774. .. [4] https://functions.wolfram.com/Polynomials/LegendreP2/
  775. """
  776. @classmethod
  777. def _eval_at_order(cls, n, m):
  778. P = legendre_poly(n, _x, polys=True).diff((_x, m))
  779. return S.NegativeOne**m * (1 - _x**2)**Rational(m, 2) * P.as_expr()
  780. @classmethod
  781. def eval(cls, n, m, x):
  782. if m.could_extract_minus_sign():
  783. # P^{-m}_n ---> F * P^m_n
  784. return S.NegativeOne**(-m) * (factorial(m + n)/factorial(n - m)) * assoc_legendre(n, -m, x)
  785. if m == 0:
  786. # P^0_n ---> L_n
  787. return legendre(n, x)
  788. if x == 0:
  789. return 2**m*sqrt(S.Pi) / (gamma((1 - m - n)/2)*gamma(1 - (m - n)/2))
  790. if n.is_Number and m.is_Number and n.is_integer and m.is_integer:
  791. if n.is_negative:
  792. raise ValueError("%s : 1st index must be nonnegative integer (got %r)" % (cls, n))
  793. if abs(m) > n:
  794. raise ValueError("%s : abs('2nd index') must be <= '1st index' (got %r, %r)" % (cls, n, m))
  795. return cls._eval_at_order(int(n), abs(int(m))).subs(_x, x)
  796. def fdiff(self, argindex=3):
  797. if argindex == 1:
  798. # Diff wrt n
  799. raise ArgumentIndexError(self, argindex)
  800. elif argindex == 2:
  801. # Diff wrt m
  802. raise ArgumentIndexError(self, argindex)
  803. elif argindex == 3:
  804. # Diff wrt x
  805. # Find better formula, this is unsuitable for x = 1
  806. n, m, x = self.args
  807. return 1/(x**2 - 1)*(x*n*assoc_legendre(n, m, x) - (m + n)*assoc_legendre(n - 1, m, x))
  808. else:
  809. raise ArgumentIndexError(self, argindex)
  810. def _eval_rewrite_as_Sum(self, n, m, x, **kwargs):
  811. from sympy.concrete.summations import Sum
  812. k = Dummy("k")
  813. kern = factorial(2*n - 2*k)/(2**n*factorial(n - k)*factorial(
  814. k)*factorial(n - 2*k - m))*S.NegativeOne**k*x**(n - m - 2*k)
  815. return (1 - x**2)**(m/2) * Sum(kern, (k, 0, floor((n - m)*S.Half)))
  816. def _eval_rewrite_as_polynomial(self, n, m, x, **kwargs):
  817. # This function is just kept for backwards compatibility
  818. # but should not be used
  819. return self._eval_rewrite_as_Sum(n, m, x, **kwargs)
  820. def _eval_conjugate(self):
  821. n, m, x = self.args
  822. return self.func(n, m.conjugate(), x.conjugate())
  823. #----------------------------------------------------------------------------
  824. # Hermite polynomials
  825. #
  826. class hermite(OrthogonalPolynomial):
  827. r"""
  828. ``hermite(n, x)`` gives the $n$th Hermite polynomial in $x$, $H_n(x)$.
  829. Explanation
  830. ===========
  831. The Hermite polynomials are orthogonal on $(-\infty, \infty)$
  832. with respect to the weight $\exp\left(-x^2\right)$.
  833. Examples
  834. ========
  835. >>> from sympy import hermite, diff
  836. >>> from sympy.abc import x, n
  837. >>> hermite(0, x)
  838. 1
  839. >>> hermite(1, x)
  840. 2*x
  841. >>> hermite(2, x)
  842. 4*x**2 - 2
  843. >>> hermite(n, x)
  844. hermite(n, x)
  845. >>> diff(hermite(n,x), x)
  846. 2*n*hermite(n - 1, x)
  847. >>> hermite(n, -x)
  848. (-1)**n*hermite(n, x)
  849. See Also
  850. ========
  851. jacobi, gegenbauer,
  852. chebyshevt, chebyshevt_root, chebyshevu, chebyshevu_root,
  853. legendre, assoc_legendre,
  854. hermite_prob,
  855. laguerre, assoc_laguerre,
  856. sympy.polys.orthopolys.jacobi_poly
  857. sympy.polys.orthopolys.gegenbauer_poly
  858. sympy.polys.orthopolys.chebyshevt_poly
  859. sympy.polys.orthopolys.chebyshevu_poly
  860. sympy.polys.orthopolys.hermite_poly
  861. sympy.polys.orthopolys.hermite_prob_poly
  862. sympy.polys.orthopolys.legendre_poly
  863. sympy.polys.orthopolys.laguerre_poly
  864. References
  865. ==========
  866. .. [1] https://en.wikipedia.org/wiki/Hermite_polynomial
  867. .. [2] https://mathworld.wolfram.com/HermitePolynomial.html
  868. .. [3] https://functions.wolfram.com/Polynomials/HermiteH/
  869. """
  870. _ortho_poly = staticmethod(hermite_poly)
  871. @classmethod
  872. def eval(cls, n, x):
  873. if not n.is_Number:
  874. # Symbolic result H_n(x)
  875. # H_n(-x) ---> (-1)**n * H_n(x)
  876. if x.could_extract_minus_sign():
  877. return S.NegativeOne**n * hermite(n, -x)
  878. # We can evaluate for some special values of x
  879. if x.is_zero:
  880. return 2**n * sqrt(S.Pi) / gamma((S.One - n)/2)
  881. elif x is S.Infinity:
  882. return S.Infinity
  883. else:
  884. # n is a given fixed integer, evaluate into polynomial
  885. if n.is_negative:
  886. raise ValueError(
  887. "The index n must be nonnegative integer (got %r)" % n)
  888. else:
  889. return cls._eval_at_order(n, x)
  890. def fdiff(self, argindex=2):
  891. if argindex == 1:
  892. # Diff wrt n
  893. raise ArgumentIndexError(self, argindex)
  894. elif argindex == 2:
  895. # Diff wrt x
  896. n, x = self.args
  897. return 2*n*hermite(n - 1, x)
  898. else:
  899. raise ArgumentIndexError(self, argindex)
  900. def _eval_rewrite_as_Sum(self, n, x, **kwargs):
  901. from sympy.concrete.summations import Sum
  902. k = Dummy("k")
  903. kern = S.NegativeOne**k / (factorial(k)*factorial(n - 2*k)) * (2*x)**(n - 2*k)
  904. return factorial(n)*Sum(kern, (k, 0, floor(n/2)))
  905. def _eval_rewrite_as_polynomial(self, n, x, **kwargs):
  906. # This function is just kept for backwards compatibility
  907. # but should not be used
  908. return self._eval_rewrite_as_Sum(n, x, **kwargs)
  909. def _eval_rewrite_as_hermite_prob(self, n, x, **kwargs):
  910. return sqrt(2)**n * hermite_prob(n, x*sqrt(2))
  911. class hermite_prob(OrthogonalPolynomial):
  912. r"""
  913. ``hermite_prob(n, x)`` gives the $n$th probabilist's Hermite polynomial
  914. in $x$, $He_n(x)$.
  915. Explanation
  916. ===========
  917. The probabilist's Hermite polynomials are orthogonal on $(-\infty, \infty)$
  918. with respect to the weight $\exp\left(-\frac{x^2}{2}\right)$. They are monic
  919. polynomials, related to the plain Hermite polynomials (:py:class:`~.hermite`) by
  920. .. math :: He_n(x) = 2^{-n/2} H_n(x/\sqrt{2})
  921. Examples
  922. ========
  923. >>> from sympy import hermite_prob, diff, I
  924. >>> from sympy.abc import x, n
  925. >>> hermite_prob(1, x)
  926. x
  927. >>> hermite_prob(5, x)
  928. x**5 - 10*x**3 + 15*x
  929. >>> diff(hermite_prob(n,x), x)
  930. n*hermite_prob(n - 1, x)
  931. >>> hermite_prob(n, -x)
  932. (-1)**n*hermite_prob(n, x)
  933. The sum of absolute values of coefficients of $He_n(x)$ is the number of
  934. matchings in the complete graph $K_n$ or telephone number, A000085 in the OEIS:
  935. >>> [hermite_prob(n,I) / I**n for n in range(11)]
  936. [1, 1, 2, 4, 10, 26, 76, 232, 764, 2620, 9496]
  937. See Also
  938. ========
  939. jacobi, gegenbauer,
  940. chebyshevt, chebyshevt_root, chebyshevu, chebyshevu_root,
  941. legendre, assoc_legendre,
  942. hermite,
  943. laguerre, assoc_laguerre,
  944. sympy.polys.orthopolys.jacobi_poly
  945. sympy.polys.orthopolys.gegenbauer_poly
  946. sympy.polys.orthopolys.chebyshevt_poly
  947. sympy.polys.orthopolys.chebyshevu_poly
  948. sympy.polys.orthopolys.hermite_poly
  949. sympy.polys.orthopolys.hermite_prob_poly
  950. sympy.polys.orthopolys.legendre_poly
  951. sympy.polys.orthopolys.laguerre_poly
  952. References
  953. ==========
  954. .. [1] https://en.wikipedia.org/wiki/Hermite_polynomial
  955. .. [2] https://mathworld.wolfram.com/HermitePolynomial.html
  956. """
  957. _ortho_poly = staticmethod(hermite_prob_poly)
  958. @classmethod
  959. def eval(cls, n, x):
  960. if not n.is_Number:
  961. if x.could_extract_minus_sign():
  962. return S.NegativeOne**n * hermite_prob(n, -x)
  963. if x.is_zero:
  964. return sqrt(S.Pi) / gamma((S.One-n) / 2)
  965. elif x is S.Infinity:
  966. return S.Infinity
  967. else:
  968. if n.is_negative:
  969. ValueError("n must be a nonnegative integer, not %r" % n)
  970. else:
  971. return cls._eval_at_order(n, x)
  972. def fdiff(self, argindex=2):
  973. if argindex == 2:
  974. n, x = self.args
  975. return n*hermite_prob(n-1, x)
  976. else:
  977. raise ArgumentIndexError(self, argindex)
  978. def _eval_rewrite_as_Sum(self, n, x, **kwargs):
  979. from sympy.concrete.summations import Sum
  980. k = Dummy("k")
  981. kern = (-S.Half)**k * x**(n-2*k) / (factorial(k) * factorial(n-2*k))
  982. return factorial(n)*Sum(kern, (k, 0, floor(n/2)))
  983. def _eval_rewrite_as_polynomial(self, n, x, **kwargs):
  984. # This function is just kept for backwards compatibility
  985. # but should not be used
  986. return self._eval_rewrite_as_Sum(n, x, **kwargs)
  987. def _eval_rewrite_as_hermite(self, n, x, **kwargs):
  988. return sqrt(2)**(-n) * hermite(n, x/sqrt(2))
  989. #----------------------------------------------------------------------------
  990. # Laguerre polynomials
  991. #
  992. class laguerre(OrthogonalPolynomial):
  993. r"""
  994. Returns the $n$th Laguerre polynomial in $x$, $L_n(x)$.
  995. Examples
  996. ========
  997. >>> from sympy import laguerre, diff
  998. >>> from sympy.abc import x, n
  999. >>> laguerre(0, x)
  1000. 1
  1001. >>> laguerre(1, x)
  1002. 1 - x
  1003. >>> laguerre(2, x)
  1004. x**2/2 - 2*x + 1
  1005. >>> laguerre(3, x)
  1006. -x**3/6 + 3*x**2/2 - 3*x + 1
  1007. >>> laguerre(n, x)
  1008. laguerre(n, x)
  1009. >>> diff(laguerre(n, x), x)
  1010. -assoc_laguerre(n - 1, 1, x)
  1011. Parameters
  1012. ==========
  1013. n : int
  1014. Degree of Laguerre polynomial. Must be `n \ge 0`.
  1015. See Also
  1016. ========
  1017. jacobi, gegenbauer,
  1018. chebyshevt, chebyshevt_root, chebyshevu, chebyshevu_root,
  1019. legendre, assoc_legendre,
  1020. hermite, hermite_prob,
  1021. assoc_laguerre,
  1022. sympy.polys.orthopolys.jacobi_poly
  1023. sympy.polys.orthopolys.gegenbauer_poly
  1024. sympy.polys.orthopolys.chebyshevt_poly
  1025. sympy.polys.orthopolys.chebyshevu_poly
  1026. sympy.polys.orthopolys.hermite_poly
  1027. sympy.polys.orthopolys.hermite_prob_poly
  1028. sympy.polys.orthopolys.legendre_poly
  1029. sympy.polys.orthopolys.laguerre_poly
  1030. References
  1031. ==========
  1032. .. [1] https://en.wikipedia.org/wiki/Laguerre_polynomial
  1033. .. [2] https://mathworld.wolfram.com/LaguerrePolynomial.html
  1034. .. [3] https://functions.wolfram.com/Polynomials/LaguerreL/
  1035. .. [4] https://functions.wolfram.com/Polynomials/LaguerreL3/
  1036. """
  1037. _ortho_poly = staticmethod(laguerre_poly)
  1038. @classmethod
  1039. def eval(cls, n, x):
  1040. if n.is_integer is False:
  1041. raise ValueError("Error: n should be an integer.")
  1042. if not n.is_Number:
  1043. # Symbolic result L_n(x)
  1044. # L_{n}(-x) ---> exp(-x) * L_{-n-1}(x)
  1045. # L_{-n}(x) ---> exp(x) * L_{n-1}(-x)
  1046. if n.could_extract_minus_sign() and not(-n - 1).could_extract_minus_sign():
  1047. return exp(x)*laguerre(-n - 1, -x)
  1048. # We can evaluate for some special values of x
  1049. if x.is_zero:
  1050. return S.One
  1051. elif x is S.NegativeInfinity:
  1052. return S.Infinity
  1053. elif x is S.Infinity:
  1054. return S.NegativeOne**n * S.Infinity
  1055. else:
  1056. if n.is_negative:
  1057. return exp(x)*laguerre(-n - 1, -x)
  1058. else:
  1059. return cls._eval_at_order(n, x)
  1060. def fdiff(self, argindex=2):
  1061. if argindex == 1:
  1062. # Diff wrt n
  1063. raise ArgumentIndexError(self, argindex)
  1064. elif argindex == 2:
  1065. # Diff wrt x
  1066. n, x = self.args
  1067. return -assoc_laguerre(n - 1, 1, x)
  1068. else:
  1069. raise ArgumentIndexError(self, argindex)
  1070. def _eval_rewrite_as_Sum(self, n, x, **kwargs):
  1071. from sympy.concrete.summations import Sum
  1072. # Make sure n \in N_0
  1073. if n.is_negative:
  1074. return exp(x) * self._eval_rewrite_as_Sum(-n - 1, -x, **kwargs)
  1075. if n.is_integer is False:
  1076. raise ValueError("Error: n should be an integer.")
  1077. k = Dummy("k")
  1078. kern = RisingFactorial(-n, k) / factorial(k)**2 * x**k
  1079. return Sum(kern, (k, 0, n))
  1080. def _eval_rewrite_as_polynomial(self, n, x, **kwargs):
  1081. # This function is just kept for backwards compatibility
  1082. # but should not be used
  1083. return self._eval_rewrite_as_Sum(n, x, **kwargs)
  1084. class assoc_laguerre(OrthogonalPolynomial):
  1085. r"""
  1086. Returns the $n$th generalized Laguerre polynomial in $x$, $L_n(x)$.
  1087. Examples
  1088. ========
  1089. >>> from sympy import assoc_laguerre, diff
  1090. >>> from sympy.abc import x, n, a
  1091. >>> assoc_laguerre(0, a, x)
  1092. 1
  1093. >>> assoc_laguerre(1, a, x)
  1094. a - x + 1
  1095. >>> assoc_laguerre(2, a, x)
  1096. a**2/2 + 3*a/2 + x**2/2 + x*(-a - 2) + 1
  1097. >>> assoc_laguerre(3, a, x)
  1098. a**3/6 + a**2 + 11*a/6 - x**3/6 + x**2*(a/2 + 3/2) +
  1099. x*(-a**2/2 - 5*a/2 - 3) + 1
  1100. >>> assoc_laguerre(n, a, 0)
  1101. binomial(a + n, a)
  1102. >>> assoc_laguerre(n, a, x)
  1103. assoc_laguerre(n, a, x)
  1104. >>> assoc_laguerre(n, 0, x)
  1105. laguerre(n, x)
  1106. >>> diff(assoc_laguerre(n, a, x), x)
  1107. -assoc_laguerre(n - 1, a + 1, x)
  1108. >>> diff(assoc_laguerre(n, a, x), a)
  1109. Sum(assoc_laguerre(_k, a, x)/(-a + n), (_k, 0, n - 1))
  1110. Parameters
  1111. ==========
  1112. n : int
  1113. Degree of Laguerre polynomial. Must be `n \ge 0`.
  1114. alpha : Expr
  1115. Arbitrary expression. For ``alpha=0`` regular Laguerre
  1116. polynomials will be generated.
  1117. See Also
  1118. ========
  1119. jacobi, gegenbauer,
  1120. chebyshevt, chebyshevt_root, chebyshevu, chebyshevu_root,
  1121. legendre, assoc_legendre,
  1122. hermite, hermite_prob,
  1123. laguerre,
  1124. sympy.polys.orthopolys.jacobi_poly
  1125. sympy.polys.orthopolys.gegenbauer_poly
  1126. sympy.polys.orthopolys.chebyshevt_poly
  1127. sympy.polys.orthopolys.chebyshevu_poly
  1128. sympy.polys.orthopolys.hermite_poly
  1129. sympy.polys.orthopolys.hermite_prob_poly
  1130. sympy.polys.orthopolys.legendre_poly
  1131. sympy.polys.orthopolys.laguerre_poly
  1132. References
  1133. ==========
  1134. .. [1] https://en.wikipedia.org/wiki/Laguerre_polynomial#Generalized_Laguerre_polynomials
  1135. .. [2] https://mathworld.wolfram.com/AssociatedLaguerrePolynomial.html
  1136. .. [3] https://functions.wolfram.com/Polynomials/LaguerreL/
  1137. .. [4] https://functions.wolfram.com/Polynomials/LaguerreL3/
  1138. """
  1139. @classmethod
  1140. def eval(cls, n, alpha, x):
  1141. # L_{n}^{0}(x) ---> L_{n}(x)
  1142. if alpha.is_zero:
  1143. return laguerre(n, x)
  1144. if not n.is_Number:
  1145. # We can evaluate for some special values of x
  1146. if x.is_zero:
  1147. return binomial(n + alpha, alpha)
  1148. elif x is S.Infinity and n > 0:
  1149. return S.NegativeOne**n * S.Infinity
  1150. elif x is S.NegativeInfinity and n > 0:
  1151. return S.Infinity
  1152. else:
  1153. # n is a given fixed integer, evaluate into polynomial
  1154. if n.is_negative:
  1155. raise ValueError(
  1156. "The index n must be nonnegative integer (got %r)" % n)
  1157. else:
  1158. return laguerre_poly(n, x, alpha)
  1159. def fdiff(self, argindex=3):
  1160. from sympy.concrete.summations import Sum
  1161. if argindex == 1:
  1162. # Diff wrt n
  1163. raise ArgumentIndexError(self, argindex)
  1164. elif argindex == 2:
  1165. # Diff wrt alpha
  1166. n, alpha, x = self.args
  1167. k = Dummy("k")
  1168. return Sum(assoc_laguerre(k, alpha, x) / (n - alpha), (k, 0, n - 1))
  1169. elif argindex == 3:
  1170. # Diff wrt x
  1171. n, alpha, x = self.args
  1172. return -assoc_laguerre(n - 1, alpha + 1, x)
  1173. else:
  1174. raise ArgumentIndexError(self, argindex)
  1175. def _eval_rewrite_as_Sum(self, n, alpha, x, **kwargs):
  1176. from sympy.concrete.summations import Sum
  1177. # Make sure n \in N_0
  1178. if n.is_negative or n.is_integer is False:
  1179. raise ValueError("Error: n should be a non-negative integer.")
  1180. k = Dummy("k")
  1181. kern = RisingFactorial(
  1182. -n, k) / (gamma(k + alpha + 1) * factorial(k)) * x**k
  1183. return gamma(n + alpha + 1) / factorial(n) * Sum(kern, (k, 0, n))
  1184. def _eval_rewrite_as_polynomial(self, n, alpha, x, **kwargs):
  1185. # This function is just kept for backwards compatibility
  1186. # but should not be used
  1187. return self._eval_rewrite_as_Sum(n, alpha, x, **kwargs)
  1188. def _eval_conjugate(self):
  1189. n, alpha, x = self.args
  1190. return self.func(n, alpha.conjugate(), x.conjugate())