_orthogonal.py 73 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606
  1. """
  2. A collection of functions to find the weights and abscissas for
  3. Gaussian Quadrature.
  4. These calculations are done by finding the eigenvalues of a
  5. tridiagonal matrix whose entries are dependent on the coefficients
  6. in the recursion formula for the orthogonal polynomials with the
  7. corresponding weighting function over the interval.
  8. Many recursion relations for orthogonal polynomials are given:
  9. .. math::
  10. a1n f_{n+1} (x) = (a2n + a3n x ) f_n (x) - a4n f_{n-1} (x)
  11. The recursion relation of interest is
  12. .. math::
  13. P_{n+1} (x) = (x - A_n) P_n (x) - B_n P_{n-1} (x)
  14. where :math:`P` has a different normalization than :math:`f`.
  15. The coefficients can be found as:
  16. .. math::
  17. A_n = -a2n / a3n
  18. \\qquad
  19. B_n = ( a4n / a3n \\sqrt{h_n-1 / h_n})^2
  20. where
  21. .. math::
  22. h_n = \\int_a^b w(x) f_n(x)^2
  23. assume:
  24. .. math::
  25. P_0 (x) = 1
  26. \\qquad
  27. P_{-1} (x) == 0
  28. For the mathematical background, see [golub.welsch-1969-mathcomp]_ and
  29. [abramowitz.stegun-1965]_.
  30. References
  31. ----------
  32. .. [golub.welsch-1969-mathcomp]
  33. Golub, Gene H, and John H Welsch. 1969. Calculation of Gauss
  34. Quadrature Rules. *Mathematics of Computation* 23, 221-230+s1--s10.
  35. .. [abramowitz.stegun-1965]
  36. Abramowitz, Milton, and Irene A Stegun. (1965) *Handbook of
  37. Mathematical Functions: with Formulas, Graphs, and Mathematical
  38. Tables*. Gaithersburg, MD: National Bureau of Standards.
  39. http://www.math.sfu.ca/~cbm/aands/
  40. .. [townsend.trogdon.olver-2014]
  41. Townsend, A. and Trogdon, T. and Olver, S. (2014)
  42. *Fast computation of Gauss quadrature nodes and
  43. weights on the whole real line*. :arXiv:`1410.5286`.
  44. .. [townsend.trogdon.olver-2015]
  45. Townsend, A. and Trogdon, T. and Olver, S. (2015)
  46. *Fast computation of Gauss quadrature nodes and
  47. weights on the whole real line*.
  48. IMA Journal of Numerical Analysis
  49. :doi:`10.1093/imanum/drv002`.
  50. """
  51. #
  52. # Author: Travis Oliphant 2000
  53. # Updated Sep. 2003 (fixed bugs --- tested to be accurate)
  54. # SciPy imports.
  55. import numpy as np
  56. from numpy import (exp, inf, pi, sqrt, floor, sin, cos, around,
  57. hstack, arccos, arange)
  58. from scipy.special import airy
  59. # Local imports.
  60. # There is no .pyi file for _specfun
  61. from . import _specfun # type: ignore
  62. from . import _ufuncs
  63. _gam = _ufuncs.gamma
  64. _polyfuns = ['legendre', 'chebyt', 'chebyu', 'chebyc', 'chebys',
  65. 'jacobi', 'laguerre', 'genlaguerre', 'hermite',
  66. 'hermitenorm', 'gegenbauer', 'sh_legendre', 'sh_chebyt',
  67. 'sh_chebyu', 'sh_jacobi']
  68. # Correspondence between new and old names of root functions
  69. _rootfuns_map = {'roots_legendre': 'p_roots',
  70. 'roots_chebyt': 't_roots',
  71. 'roots_chebyu': 'u_roots',
  72. 'roots_chebyc': 'c_roots',
  73. 'roots_chebys': 's_roots',
  74. 'roots_jacobi': 'j_roots',
  75. 'roots_laguerre': 'l_roots',
  76. 'roots_genlaguerre': 'la_roots',
  77. 'roots_hermite': 'h_roots',
  78. 'roots_hermitenorm': 'he_roots',
  79. 'roots_gegenbauer': 'cg_roots',
  80. 'roots_sh_legendre': 'ps_roots',
  81. 'roots_sh_chebyt': 'ts_roots',
  82. 'roots_sh_chebyu': 'us_roots',
  83. 'roots_sh_jacobi': 'js_roots'}
  84. __all__ = _polyfuns + list(_rootfuns_map.keys())
  85. class orthopoly1d(np.poly1d):
  86. def __init__(self, roots, weights=None, hn=1.0, kn=1.0, wfunc=None,
  87. limits=None, monic=False, eval_func=None):
  88. equiv_weights = [weights[k] / wfunc(roots[k]) for
  89. k in range(len(roots))]
  90. mu = sqrt(hn)
  91. if monic:
  92. evf = eval_func
  93. if evf:
  94. knn = kn
  95. def eval_func(x):
  96. return evf(x) / knn
  97. mu = mu / abs(kn)
  98. kn = 1.0
  99. # compute coefficients from roots, then scale
  100. poly = np.poly1d(roots, r=True)
  101. np.poly1d.__init__(self, poly.coeffs * float(kn))
  102. self.weights = np.array(list(zip(roots, weights, equiv_weights)))
  103. self.weight_func = wfunc
  104. self.limits = limits
  105. self.normcoef = mu
  106. # Note: eval_func will be discarded on arithmetic
  107. self._eval_func = eval_func
  108. def __call__(self, v):
  109. if self._eval_func and not isinstance(v, np.poly1d):
  110. return self._eval_func(v)
  111. else:
  112. return np.poly1d.__call__(self, v)
  113. def _scale(self, p):
  114. if p == 1.0:
  115. return
  116. self._coeffs *= p
  117. evf = self._eval_func
  118. if evf:
  119. self._eval_func = lambda x: evf(x) * p
  120. self.normcoef *= p
  121. def _gen_roots_and_weights(n, mu0, an_func, bn_func, f, df, symmetrize, mu):
  122. """[x,w] = gen_roots_and_weights(n,an_func,sqrt_bn_func,mu)
  123. Returns the roots (x) of an nth order orthogonal polynomial,
  124. and weights (w) to use in appropriate Gaussian quadrature with that
  125. orthogonal polynomial.
  126. The polynomials have the recurrence relation
  127. P_n+1(x) = (x - A_n) P_n(x) - B_n P_n-1(x)
  128. an_func(n) should return A_n
  129. sqrt_bn_func(n) should return sqrt(B_n)
  130. mu ( = h_0 ) is the integral of the weight over the orthogonal
  131. interval
  132. """
  133. # lazy import to prevent to prevent linalg dependency for whole module (gh-23420)
  134. from scipy import linalg
  135. k = np.arange(n, dtype='d')
  136. c = np.zeros((2, n))
  137. c[0,1:] = bn_func(k[1:])
  138. c[1,:] = an_func(k)
  139. x = linalg.eigvals_banded(c, overwrite_a_band=True)
  140. # improve roots by one application of Newton's method
  141. y = f(n, x)
  142. dy = df(n, x)
  143. x -= y/dy
  144. # fm and dy may contain very large/small values, so we
  145. # log-normalize them to maintain precision in the product fm*dy
  146. fm = f(n-1, x)
  147. log_fm = np.log(np.abs(fm))
  148. log_dy = np.log(np.abs(dy))
  149. fm /= np.exp((log_fm.max() + log_fm.min()) / 2.)
  150. dy /= np.exp((log_dy.max() + log_dy.min()) / 2.)
  151. w = 1.0 / (fm * dy)
  152. if symmetrize:
  153. w = (w + w[::-1]) / 2
  154. x = (x - x[::-1]) / 2
  155. w *= mu0 / w.sum()
  156. if mu:
  157. return x, w, mu0
  158. else:
  159. return x, w
  160. # Jacobi Polynomials 1 P^(alpha,beta)_n(x)
  161. def roots_jacobi(n, alpha, beta, mu=False):
  162. r"""Gauss-Jacobi quadrature.
  163. Compute the sample points and weights for Gauss-Jacobi
  164. quadrature. The sample points are the roots of the nth degree
  165. Jacobi polynomial, :math:`P^{\alpha, \beta}_n(x)`. These sample
  166. points and weights correctly integrate polynomials of degree
  167. :math:`2n - 1` or less over the interval :math:`[-1, 1]` with
  168. weight function :math:`w(x) = (1 - x)^{\alpha} (1 +
  169. x)^{\beta}`. See 22.2.1 in [AS]_ for details.
  170. Parameters
  171. ----------
  172. n : int
  173. Quadrature order.
  174. alpha : float
  175. alpha must be > -1
  176. beta : float
  177. beta must be > -1
  178. mu : bool, optional
  179. If True, return the sum of the weights in addition to sample points and weights.
  180. Returns
  181. -------
  182. x : ndarray
  183. Sample points.
  184. w : ndarray
  185. Weights.
  186. mu : float, optional
  187. Sum of the weights, only returned if `mu=True`.
  188. See Also
  189. --------
  190. scipy.integrate.fixed_quad
  191. References
  192. ----------
  193. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  194. Handbook of Mathematical Functions with Formulas,
  195. Graphs, and Mathematical Tables. New York: Dover, 1972.
  196. Examples
  197. --------
  198. >>> from scipy.special import roots_jacobi
  199. >>> x, w = roots_jacobi(3, 0.5, 0.5)
  200. >>> x
  201. array([-0.70710678, 0. , 0.70710678])
  202. >>> w
  203. array([0.39269908, 0.78539816, 0.39269908])
  204. >>> x, w, mu = roots_jacobi(3, 0.5, 0.5, mu=True)
  205. >>> mu
  206. 1.5707963267948966 # Sum of weights, equals pi/2 for alpha = beta = 0.5
  207. """
  208. m = int(n)
  209. if n < 1 or n != m:
  210. raise ValueError("n must be a positive integer.")
  211. if alpha <= -1 or beta <= -1:
  212. raise ValueError("alpha and beta must be greater than -1.")
  213. if alpha == 0.0 and beta == 0.0:
  214. return roots_legendre(m, mu)
  215. if alpha == beta:
  216. return roots_gegenbauer(m, alpha+0.5, mu)
  217. if (alpha + beta) <= 1000:
  218. mu0 = 2.0**(alpha+beta+1) * _ufuncs.beta(alpha+1, beta+1)
  219. else:
  220. # Avoid overflows in pow and beta for very large parameters
  221. mu0 = np.exp((alpha + beta + 1) * np.log(2.0)
  222. + _ufuncs.betaln(alpha+1, beta+1))
  223. a = alpha
  224. b = beta
  225. if a + b == 0.0:
  226. def an_func(k):
  227. return np.where(k == 0, (b - a) / (2 + a + b), 0.0)
  228. else:
  229. def an_func(k):
  230. return np.where(
  231. k == 0,
  232. (b - a) / (2 + a + b),
  233. (b * b - a * a) / ((2.0 * k + a + b) * (2.0 * k + a + b + 2))
  234. )
  235. def bn_func(k):
  236. return (
  237. 2.0 / (2.0 * k + a + b)
  238. * np.sqrt((k + a) * (k + b) / (2 * k + a + b + 1))
  239. * np.where(k == 1, 1.0, np.sqrt(k * (k + a + b) / (2.0 * k + a + b - 1)))
  240. )
  241. def f(n, x):
  242. return _ufuncs.eval_jacobi(n, a, b, x)
  243. def df(n, x):
  244. return 0.5 * (n + a + b + 1) * _ufuncs.eval_jacobi(n - 1, a + 1, b + 1, x)
  245. return _gen_roots_and_weights(m, mu0, an_func, bn_func, f, df, False, mu)
  246. def jacobi(n, alpha, beta, monic=False):
  247. r"""Jacobi polynomial.
  248. Defined to be the solution of
  249. .. math::
  250. (1 - x^2)\frac{d^2}{dx^2}P_n^{(\alpha, \beta)}
  251. + (\beta - \alpha - (\alpha + \beta + 2)x)
  252. \frac{d}{dx}P_n^{(\alpha, \beta)}
  253. + n(n + \alpha + \beta + 1)P_n^{(\alpha, \beta)} = 0
  254. for :math:`\alpha, \beta > -1`; :math:`P_n^{(\alpha, \beta)}` is a
  255. polynomial of degree :math:`n`.
  256. Parameters
  257. ----------
  258. n : int
  259. Degree of the polynomial.
  260. alpha : float
  261. Parameter, must be greater than -1.
  262. beta : float
  263. Parameter, must be greater than -1.
  264. monic : bool, optional
  265. If `True`, scale the leading coefficient to be 1. Default is
  266. `False`.
  267. Returns
  268. -------
  269. P : orthopoly1d
  270. Jacobi polynomial.
  271. Notes
  272. -----
  273. For fixed :math:`\alpha, \beta`, the polynomials
  274. :math:`P_n^{(\alpha, \beta)}` are orthogonal over :math:`[-1, 1]`
  275. with weight function :math:`(1 - x)^\alpha(1 + x)^\beta`.
  276. References
  277. ----------
  278. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  279. Handbook of Mathematical Functions with Formulas,
  280. Graphs, and Mathematical Tables. New York: Dover, 1972.
  281. Examples
  282. --------
  283. The Jacobi polynomials satisfy the recurrence relation:
  284. .. math::
  285. P_n^{(\alpha, \beta-1)}(x) - P_n^{(\alpha-1, \beta)}(x)
  286. = P_{n-1}^{(\alpha, \beta)}(x)
  287. This can be verified, for example, for :math:`\alpha = \beta = 2`
  288. and :math:`n = 1` over the interval :math:`[-1, 1]`:
  289. >>> import numpy as np
  290. >>> from scipy.special import jacobi
  291. >>> x = np.arange(-1.0, 1.0, 0.01)
  292. >>> np.allclose(jacobi(0, 2, 2)(x),
  293. ... jacobi(1, 2, 1)(x) - jacobi(1, 1, 2)(x))
  294. True
  295. Plot of the Jacobi polynomial :math:`P_5^{(\alpha, -0.5)}` for
  296. different values of :math:`\alpha`:
  297. >>> import matplotlib.pyplot as plt
  298. >>> x = np.arange(-1.0, 1.0, 0.01)
  299. >>> fig, ax = plt.subplots()
  300. >>> ax.set_ylim(-2.0, 2.0)
  301. >>> ax.set_title(r'Jacobi polynomials $P_5^{(\alpha, -0.5)}$')
  302. >>> for alpha in np.arange(0, 4, 1):
  303. ... ax.plot(x, jacobi(5, alpha, -0.5)(x), label=rf'$\alpha={alpha}$')
  304. >>> plt.legend(loc='best')
  305. >>> plt.show()
  306. """
  307. if n < 0:
  308. raise ValueError("n must be nonnegative.")
  309. def wfunc(x):
  310. return (1 - x) ** alpha * (1 + x) ** beta
  311. if n == 0:
  312. return orthopoly1d([], [], 1.0, 1.0, wfunc, (-1, 1), monic,
  313. eval_func=np.ones_like)
  314. x, w, mu = roots_jacobi(n, alpha, beta, mu=True)
  315. ab1 = alpha + beta + 1.0
  316. hn = 2**ab1 / (2 * n + ab1) * _gam(n + alpha + 1)
  317. hn *= _gam(n + beta + 1.0) / _gam(n + 1) / _gam(n + ab1)
  318. kn = _gam(2 * n + ab1) / 2.0**n / _gam(n + 1) / _gam(n + ab1)
  319. # here kn = coefficient on x^n term
  320. p = orthopoly1d(x, w, hn, kn, wfunc, (-1, 1), monic,
  321. lambda x: _ufuncs.eval_jacobi(n, alpha, beta, x))
  322. return p
  323. # Jacobi Polynomials shifted G_n(p,q,x)
  324. def roots_sh_jacobi(n, p1, q1, mu=False):
  325. """Gauss-Jacobi (shifted) quadrature.
  326. Compute the sample points and weights for Gauss-Jacobi (shifted)
  327. quadrature. The sample points are the roots of the nth degree
  328. shifted Jacobi polynomial, :math:`G^{p,q}_n(x)`. These sample
  329. points and weights correctly integrate polynomials of degree
  330. :math:`2n - 1` or less over the interval :math:`[0, 1]` with
  331. weight function :math:`w(x) = (1 - x)^{p-q} x^{q-1}`. See 22.2.2
  332. in [AS]_ for details.
  333. Parameters
  334. ----------
  335. n : int
  336. quadrature order
  337. p1 : float
  338. (p1 - q1) must be > -1
  339. q1 : float
  340. q1 must be > 0
  341. mu : bool, optional
  342. If True, return the sum of the weights, optional.
  343. Returns
  344. -------
  345. x : ndarray
  346. Sample points
  347. w : ndarray
  348. Weights
  349. mu : float
  350. Sum of the weights
  351. See Also
  352. --------
  353. scipy.integrate.fixed_quad
  354. References
  355. ----------
  356. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  357. Handbook of Mathematical Functions with Formulas,
  358. Graphs, and Mathematical Tables. New York: Dover, 1972.
  359. """
  360. if (p1-q1) <= -1 or q1 <= 0:
  361. message = "(p - q) must be greater than -1, and q must be greater than 0."
  362. raise ValueError(message)
  363. x, w, m = roots_jacobi(n, p1-q1, q1-1, True)
  364. x = (x + 1) / 2
  365. scale = 2.0**p1
  366. w /= scale
  367. m /= scale
  368. if mu:
  369. return x, w, m
  370. else:
  371. return x, w
  372. def sh_jacobi(n, p, q, monic=False):
  373. r"""Shifted Jacobi polynomial.
  374. Defined by
  375. .. math::
  376. G_n^{(p, q)}(x)
  377. = \binom{2n + p - 1}{n}^{-1}P_n^{(p - q, q - 1)}(2x - 1),
  378. where :math:`P_n^{(\cdot, \cdot)}` is the nth Jacobi polynomial.
  379. Parameters
  380. ----------
  381. n : int
  382. Degree of the polynomial.
  383. p : float
  384. Parameter, must have :math:`p > q - 1`.
  385. q : float
  386. Parameter, must be greater than 0.
  387. monic : bool, optional
  388. If `True`, scale the leading coefficient to be 1. Default is
  389. `False`.
  390. Returns
  391. -------
  392. G : orthopoly1d
  393. Shifted Jacobi polynomial.
  394. Notes
  395. -----
  396. For fixed :math:`p, q`, the polynomials :math:`G_n^{(p, q)}` are
  397. orthogonal over :math:`[0, 1]` with weight function :math:`(1 -
  398. x)^{p - q}x^{q - 1}`.
  399. """
  400. if n < 0:
  401. raise ValueError("n must be nonnegative.")
  402. def wfunc(x):
  403. return (1.0 - x) ** (p - q) * x ** (q - 1.0)
  404. if n == 0:
  405. return orthopoly1d([], [], 1.0, 1.0, wfunc, (-1, 1), monic,
  406. eval_func=np.ones_like)
  407. n1 = n
  408. x, w = roots_sh_jacobi(n1, p, q)
  409. hn = _gam(n + 1) * _gam(n + q) * _gam(n + p) * _gam(n + p - q + 1)
  410. hn /= (2 * n + p) * (_gam(2 * n + p)**2)
  411. # kn = 1.0 in standard form so monic is redundant. Kept for compatibility.
  412. kn = 1.0
  413. pp = orthopoly1d(x, w, hn, kn, wfunc=wfunc, limits=(0, 1), monic=monic,
  414. eval_func=lambda x: _ufuncs.eval_sh_jacobi(n, p, q, x))
  415. return pp
  416. # Generalized Laguerre L^(alpha)_n(x)
  417. def roots_genlaguerre(n, alpha, mu=False):
  418. r"""Gauss-generalized Laguerre quadrature.
  419. Compute the sample points and weights for Gauss-generalized
  420. Laguerre quadrature. The sample points are the roots of the nth
  421. degree generalized Laguerre polynomial, :math:`L^{\alpha}_n(x)`.
  422. These sample points and weights correctly integrate polynomials of
  423. degree :math:`2n - 1` or less over the interval :math:`[0,
  424. \infty]` with weight function :math:`w(x) = x^{\alpha}
  425. e^{-x}`. See 22.3.9 in [AS]_ for details.
  426. Parameters
  427. ----------
  428. n : int
  429. quadrature order
  430. alpha : float
  431. alpha must be > -1
  432. mu : bool, optional
  433. If True, return the sum of the weights, optional.
  434. Returns
  435. -------
  436. x : ndarray
  437. Sample points
  438. w : ndarray
  439. Weights
  440. mu : float
  441. Sum of the weights
  442. See Also
  443. --------
  444. scipy.integrate.fixed_quad
  445. References
  446. ----------
  447. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  448. Handbook of Mathematical Functions with Formulas,
  449. Graphs, and Mathematical Tables. New York: Dover, 1972.
  450. """
  451. m = int(n)
  452. if n < 1 or n != m:
  453. raise ValueError("n must be a positive integer.")
  454. if alpha < -1:
  455. raise ValueError("alpha must be greater than -1.")
  456. mu0 = _ufuncs.gamma(alpha + 1)
  457. if m == 1:
  458. x = np.array([alpha+1.0], 'd')
  459. w = np.array([mu0], 'd')
  460. if mu:
  461. return x, w, mu0
  462. else:
  463. return x, w
  464. def an_func(k):
  465. return 2 * k + alpha + 1
  466. def bn_func(k):
  467. return -np.sqrt(k * (k + alpha))
  468. def f(n, x):
  469. return _ufuncs.eval_genlaguerre(n, alpha, x)
  470. def df(n, x):
  471. return (n * _ufuncs.eval_genlaguerre(n, alpha, x)
  472. - (n + alpha) * _ufuncs.eval_genlaguerre(n - 1, alpha, x)) / x
  473. return _gen_roots_and_weights(m, mu0, an_func, bn_func, f, df, False, mu)
  474. def genlaguerre(n, alpha, monic=False):
  475. r"""Generalized (associated) Laguerre polynomial.
  476. Defined to be the solution of
  477. .. math::
  478. x\frac{d^2}{dx^2}L_n^{(\alpha)}
  479. + (\alpha + 1 - x)\frac{d}{dx}L_n^{(\alpha)}
  480. + nL_n^{(\alpha)} = 0,
  481. where :math:`\alpha > -1`; :math:`L_n^{(\alpha)}` is a polynomial
  482. of degree :math:`n`.
  483. Parameters
  484. ----------
  485. n : int
  486. Degree of the polynomial.
  487. alpha : float
  488. Parameter, must be greater than -1.
  489. monic : bool, optional
  490. If `True`, scale the leading coefficient to be 1. Default is
  491. `False`.
  492. Returns
  493. -------
  494. L : orthopoly1d
  495. Generalized Laguerre polynomial.
  496. See Also
  497. --------
  498. laguerre : Laguerre polynomial.
  499. hyp1f1 : confluent hypergeometric function
  500. Notes
  501. -----
  502. For fixed :math:`\alpha`, the polynomials :math:`L_n^{(\alpha)}`
  503. are orthogonal over :math:`[0, \infty)` with weight function
  504. :math:`e^{-x}x^\alpha`.
  505. The Laguerre polynomials are the special case where :math:`\alpha
  506. = 0`.
  507. References
  508. ----------
  509. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  510. Handbook of Mathematical Functions with Formulas,
  511. Graphs, and Mathematical Tables. New York: Dover, 1972.
  512. Examples
  513. --------
  514. The generalized Laguerre polynomials are closely related to the confluent
  515. hypergeometric function :math:`{}_1F_1`:
  516. .. math::
  517. L_n^{(\alpha)} = \binom{n + \alpha}{n} {}_1F_1(-n, \alpha +1, x)
  518. This can be verified, for example, for :math:`n = \alpha = 3` over the
  519. interval :math:`[-1, 1]`:
  520. >>> import numpy as np
  521. >>> from scipy.special import binom
  522. >>> from scipy.special import genlaguerre
  523. >>> from scipy.special import hyp1f1
  524. >>> x = np.arange(-1.0, 1.0, 0.01)
  525. >>> np.allclose(genlaguerre(3, 3)(x), binom(6, 3) * hyp1f1(-3, 4, x))
  526. True
  527. This is the plot of the generalized Laguerre polynomials
  528. :math:`L_3^{(\alpha)}` for some values of :math:`\alpha`:
  529. >>> import matplotlib.pyplot as plt
  530. >>> x = np.arange(-4.0, 12.0, 0.01)
  531. >>> fig, ax = plt.subplots()
  532. >>> ax.set_ylim(-5.0, 10.0)
  533. >>> ax.set_title(r'Generalized Laguerre polynomials $L_3^{\alpha}$')
  534. >>> for alpha in np.arange(0, 5):
  535. ... ax.plot(x, genlaguerre(3, alpha)(x), label=rf'$L_3^{(alpha)}$')
  536. >>> plt.legend(loc='best')
  537. >>> plt.show()
  538. """
  539. if alpha <= -1:
  540. raise ValueError("alpha must be > -1")
  541. if n < 0:
  542. raise ValueError("n must be nonnegative.")
  543. if n == 0:
  544. n1 = n + 1
  545. else:
  546. n1 = n
  547. x, w = roots_genlaguerre(n1, alpha)
  548. def wfunc(x):
  549. return exp(-x) * x ** alpha
  550. if n == 0:
  551. x, w = [], []
  552. hn = _gam(n + alpha + 1) / _gam(n + 1)
  553. kn = (-1)**n / _gam(n + 1)
  554. p = orthopoly1d(x, w, hn, kn, wfunc, (0, inf), monic,
  555. lambda x: _ufuncs.eval_genlaguerre(n, alpha, x))
  556. return p
  557. # Laguerre L_n(x)
  558. def roots_laguerre(n, mu=False):
  559. r"""Gauss-Laguerre quadrature.
  560. Compute the sample points and weights for Gauss-Laguerre
  561. quadrature. The sample points are the roots of the nth degree
  562. Laguerre polynomial, :math:`L_n(x)`. These sample points and
  563. weights correctly integrate polynomials of degree :math:`2n - 1`
  564. or less over the interval :math:`[0, \infty]` with weight function
  565. :math:`w(x) = e^{-x}`. See 22.2.13 in [AS]_ for details.
  566. Parameters
  567. ----------
  568. n : int
  569. quadrature order
  570. mu : bool, optional
  571. If True, return the sum of the weights, optional.
  572. Returns
  573. -------
  574. x : ndarray
  575. Sample points
  576. w : ndarray
  577. Weights
  578. mu : float
  579. Sum of the weights
  580. See Also
  581. --------
  582. scipy.integrate.fixed_quad
  583. numpy.polynomial.laguerre.laggauss
  584. References
  585. ----------
  586. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  587. Handbook of Mathematical Functions with Formulas,
  588. Graphs, and Mathematical Tables. New York: Dover, 1972.
  589. """
  590. return roots_genlaguerre(n, 0.0, mu=mu)
  591. def laguerre(n, monic=False):
  592. r"""Laguerre polynomial.
  593. Defined to be the solution of
  594. .. math::
  595. x\frac{d^2}{dx^2}L_n + (1 - x)\frac{d}{dx}L_n + nL_n = 0;
  596. :math:`L_n` is a polynomial of degree :math:`n`.
  597. Parameters
  598. ----------
  599. n : int
  600. Degree of the polynomial.
  601. monic : bool, optional
  602. If `True`, scale the leading coefficient to be 1. Default is
  603. `False`.
  604. Returns
  605. -------
  606. L : orthopoly1d
  607. Laguerre Polynomial.
  608. See Also
  609. --------
  610. genlaguerre : Generalized (associated) Laguerre polynomial.
  611. Notes
  612. -----
  613. The polynomials :math:`L_n` are orthogonal over :math:`[0,
  614. \infty)` with weight function :math:`e^{-x}`.
  615. References
  616. ----------
  617. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  618. Handbook of Mathematical Functions with Formulas,
  619. Graphs, and Mathematical Tables. New York: Dover, 1972.
  620. Examples
  621. --------
  622. The Laguerre polynomials :math:`L_n` are the special case
  623. :math:`\alpha = 0` of the generalized Laguerre polynomials
  624. :math:`L_n^{(\alpha)}`.
  625. Let's verify it on the interval :math:`[-1, 1]`:
  626. >>> import numpy as np
  627. >>> from scipy.special import genlaguerre
  628. >>> from scipy.special import laguerre
  629. >>> x = np.arange(-1.0, 1.0, 0.01)
  630. >>> np.allclose(genlaguerre(3, 0)(x), laguerre(3)(x))
  631. True
  632. The polynomials :math:`L_n` also satisfy the recurrence relation:
  633. .. math::
  634. (n + 1)L_{n+1}(x) = (2n +1 -x)L_n(x) - nL_{n-1}(x)
  635. This can be easily checked on :math:`[0, 1]` for :math:`n = 3`:
  636. >>> x = np.arange(0.0, 1.0, 0.01)
  637. >>> np.allclose(4 * laguerre(4)(x),
  638. ... (7 - x) * laguerre(3)(x) - 3 * laguerre(2)(x))
  639. True
  640. This is the plot of the first few Laguerre polynomials :math:`L_n`:
  641. >>> import matplotlib.pyplot as plt
  642. >>> x = np.arange(-1.0, 5.0, 0.01)
  643. >>> fig, ax = plt.subplots()
  644. >>> ax.set_ylim(-5.0, 5.0)
  645. >>> ax.set_title(r'Laguerre polynomials $L_n$')
  646. >>> for n in np.arange(0, 5):
  647. ... ax.plot(x, laguerre(n)(x), label=rf'$L_{n}$')
  648. >>> plt.legend(loc='best')
  649. >>> plt.show()
  650. """
  651. if n < 0:
  652. raise ValueError("n must be nonnegative.")
  653. if n == 0:
  654. n1 = n + 1
  655. else:
  656. n1 = n
  657. x, w = roots_laguerre(n1)
  658. if n == 0:
  659. x, w = [], []
  660. hn = 1.0
  661. kn = (-1)**n / _gam(n + 1)
  662. p = orthopoly1d(x, w, hn, kn, lambda x: exp(-x), (0, inf), monic,
  663. lambda x: _ufuncs.eval_laguerre(n, x))
  664. return p
  665. # Hermite 1 H_n(x)
  666. def roots_hermite(n, mu=False):
  667. r"""Gauss-Hermite (physicist's) quadrature.
  668. Compute the sample points and weights for Gauss-Hermite
  669. quadrature. The sample points are the roots of the nth degree
  670. Hermite polynomial, :math:`H_n(x)`. These sample points and
  671. weights correctly integrate polynomials of degree :math:`2n - 1`
  672. or less over the interval :math:`[-\infty, \infty]` with weight
  673. function :math:`w(x) = e^{-x^2}`. See 22.2.14 in [AS]_ for
  674. details.
  675. Parameters
  676. ----------
  677. n : int
  678. quadrature order
  679. mu : bool, optional
  680. If True, return the sum of the weights, optional.
  681. Returns
  682. -------
  683. x : ndarray
  684. Sample points
  685. w : ndarray
  686. Weights
  687. mu : float
  688. Sum of the weights
  689. See Also
  690. --------
  691. scipy.integrate.fixed_quad
  692. numpy.polynomial.hermite.hermgauss
  693. roots_hermitenorm
  694. Notes
  695. -----
  696. For small n up to 150 a modified version of the Golub-Welsch
  697. algorithm is used. Nodes are computed from the eigenvalue
  698. problem and improved by one step of a Newton iteration.
  699. The weights are computed from the well-known analytical formula.
  700. For n larger than 150 an optimal asymptotic algorithm is applied
  701. which computes nodes and weights in a numerically stable manner.
  702. The algorithm has linear runtime making computation for very
  703. large n (several thousand or more) feasible.
  704. References
  705. ----------
  706. .. [townsend.trogdon.olver-2014]
  707. Townsend, A. and Trogdon, T. and Olver, S. (2014)
  708. *Fast computation of Gauss quadrature nodes and
  709. weights on the whole real line*. :arXiv:`1410.5286`.
  710. .. [townsend.trogdon.olver-2015]
  711. Townsend, A. and Trogdon, T. and Olver, S. (2015)
  712. *Fast computation of Gauss quadrature nodes and
  713. weights on the whole real line*.
  714. IMA Journal of Numerical Analysis
  715. :doi:`10.1093/imanum/drv002`.
  716. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  717. Handbook of Mathematical Functions with Formulas,
  718. Graphs, and Mathematical Tables. New York: Dover, 1972.
  719. """
  720. m = int(n)
  721. if n < 1 or n != m:
  722. raise ValueError("n must be a positive integer.")
  723. mu0 = np.sqrt(np.pi)
  724. if n <= 150:
  725. def an_func(k):
  726. return 0.0 * k
  727. def bn_func(k):
  728. return np.sqrt(k / 2.0)
  729. f = _ufuncs.eval_hermite
  730. def df(n, x):
  731. return 2.0 * n * _ufuncs.eval_hermite(n - 1, x)
  732. return _gen_roots_and_weights(m, mu0, an_func, bn_func, f, df, True, mu)
  733. else:
  734. nodes, weights = _roots_hermite_asy(m)
  735. if mu:
  736. return nodes, weights, mu0
  737. else:
  738. return nodes, weights
  739. def _compute_tauk(n, k, maxit=5):
  740. """Helper function for Tricomi initial guesses
  741. For details, see formula 3.1 in lemma 3.1 in the
  742. original paper.
  743. Parameters
  744. ----------
  745. n : int
  746. Quadrature order
  747. k : ndarray of type int
  748. Index of roots :math:`\tau_k` to compute
  749. maxit : int
  750. Number of Newton maxit performed, the default
  751. value of 5 is sufficient.
  752. Returns
  753. -------
  754. tauk : ndarray
  755. Roots of equation 3.1
  756. See Also
  757. --------
  758. initial_nodes_a
  759. roots_hermite_asy
  760. """
  761. a = n % 2 - 0.5
  762. c = (4.0*floor(n/2.0) - 4.0*k + 3.0)*pi / (4.0*floor(n/2.0) + 2.0*a + 2.0)
  763. def f(x):
  764. return x - sin(x) - c
  765. def df(x):
  766. return 1.0 - cos(x)
  767. xi = 0.5*pi
  768. for i in range(maxit):
  769. xi = xi - f(xi)/df(xi)
  770. return xi
  771. def _initial_nodes_a(n, k):
  772. r"""Tricomi initial guesses
  773. Computes an initial approximation to the square of the `k`-th
  774. (positive) root :math:`x_k` of the Hermite polynomial :math:`H_n`
  775. of order :math:`n`. The formula is the one from lemma 3.1 in the
  776. original paper. The guesses are accurate except in the region
  777. near :math:`\sqrt{2n + 1}`.
  778. Parameters
  779. ----------
  780. n : int
  781. Quadrature order
  782. k : ndarray of type int
  783. Index of roots to compute
  784. Returns
  785. -------
  786. xksq : ndarray
  787. Square of the approximate roots
  788. See Also
  789. --------
  790. initial_nodes
  791. roots_hermite_asy
  792. """
  793. tauk = _compute_tauk(n, k)
  794. sigk = cos(0.5*tauk)**2
  795. a = n % 2 - 0.5
  796. nu = 4.0*floor(n/2.0) + 2.0*a + 2.0
  797. # Initial approximation of Hermite roots (square)
  798. xksq = nu*sigk - 1.0/(3.0*nu) * (5.0/(4.0*(1.0-sigk)**2) - 1.0/(1.0-sigk) - 0.25)
  799. return xksq
  800. def _initial_nodes_b(n, k):
  801. r"""Gatteschi initial guesses
  802. Computes an initial approximation to the square of the kth
  803. (positive) root :math:`x_k` of the Hermite polynomial :math:`H_n`
  804. of order :math:`n`. The formula is the one from lemma 3.2 in the
  805. original paper. The guesses are accurate in the region just
  806. below :math:`\sqrt{2n + 1}`.
  807. Parameters
  808. ----------
  809. n : int
  810. Quadrature order
  811. k : ndarray of type int
  812. Index of roots to compute
  813. Returns
  814. -------
  815. xksq : ndarray
  816. Square of the approximate root
  817. See Also
  818. --------
  819. initial_nodes
  820. roots_hermite_asy
  821. """
  822. a = n % 2 - 0.5
  823. nu = 4.0*floor(n/2.0) + 2.0*a + 2.0
  824. # Airy roots by approximation
  825. ak = _specfun.airyzo(k.max(), 1)[0][::-1]
  826. # Initial approximation of Hermite roots (square)
  827. xksq = (nu
  828. + 2.0**(2.0/3.0) * ak * nu**(1.0/3.0)
  829. + 1.0/5.0 * 2.0**(4.0/3.0) * ak**2 * nu**(-1.0/3.0)
  830. + (9.0/140.0 - 12.0/175.0 * ak**3) * nu**(-1.0)
  831. + (16.0/1575.0 * ak + 92.0/7875.0 * ak**4) * 2.0**(2.0/3.0) * nu**(-5.0/3.0)
  832. - (15152.0/3031875.0 * ak**5 + 1088.0/121275.0 * ak**2)
  833. * 2.0**(1.0/3.0) * nu**(-7.0/3.0))
  834. return xksq
  835. def _initial_nodes(n):
  836. """Initial guesses for the Hermite roots
  837. Computes an initial approximation to the non-negative
  838. roots :math:`x_k` of the Hermite polynomial :math:`H_n`
  839. of order :math:`n`. The Tricomi and Gatteschi initial
  840. guesses are used in the region where they are accurate.
  841. Parameters
  842. ----------
  843. n : int
  844. Quadrature order
  845. Returns
  846. -------
  847. xk : ndarray
  848. Approximate roots
  849. See Also
  850. --------
  851. roots_hermite_asy
  852. """
  853. # Turnover point
  854. # linear polynomial fit to error of 10, 25, 40, ..., 1000 point rules
  855. fit = 0.49082003*n - 4.37859653
  856. turnover = around(fit).astype(int)
  857. # Compute all approximations
  858. ia = arange(1, int(floor(n*0.5)+1))
  859. ib = ia[::-1]
  860. xasq = _initial_nodes_a(n, ia[:turnover+1])
  861. xbsq = _initial_nodes_b(n, ib[turnover+1:])
  862. # Combine
  863. iv = sqrt(hstack([xasq, xbsq]))
  864. # Central node is always zero
  865. if n % 2 == 1:
  866. iv = hstack([0.0, iv])
  867. return iv
  868. def _pbcf(n, theta):
  869. r"""Asymptotic series expansion of parabolic cylinder function
  870. The implementation is based on sections 3.2 and 3.3 from the
  871. original paper. Compared to the published version this code
  872. adds one more term to the asymptotic series. The detailed
  873. formulas can be found at [parabolic-asymptotics]_. The evaluation
  874. is done in a transformed variable :math:`\theta := \arccos(t)`
  875. where :math:`t := x / \mu` and :math:`\mu := \sqrt{2n + 1}`.
  876. Parameters
  877. ----------
  878. n : int
  879. Quadrature order
  880. theta : ndarray
  881. Transformed position variable
  882. Returns
  883. -------
  884. U : ndarray
  885. Value of the parabolic cylinder function :math:`U(a, \theta)`.
  886. Ud : ndarray
  887. Value of the derivative :math:`U^{\prime}(a, \theta)` of
  888. the parabolic cylinder function.
  889. See Also
  890. --------
  891. roots_hermite_asy
  892. References
  893. ----------
  894. .. [parabolic-asymptotics]
  895. https://dlmf.nist.gov/12.10#vii
  896. """
  897. st = sin(theta)
  898. ct = cos(theta)
  899. # https://dlmf.nist.gov/12.10#vii
  900. mu = 2.0*n + 1.0
  901. # https://dlmf.nist.gov/12.10#E23
  902. eta = 0.5*theta - 0.5*st*ct
  903. # https://dlmf.nist.gov/12.10#E39
  904. zeta = -(3.0*eta/2.0) ** (2.0/3.0)
  905. # https://dlmf.nist.gov/12.10#E40
  906. phi = (-zeta / st**2) ** (0.25)
  907. # Coefficients
  908. # https://dlmf.nist.gov/12.10#E43
  909. a0 = 1.0
  910. a1 = 0.10416666666666666667
  911. a2 = 0.08355034722222222222
  912. a3 = 0.12822657455632716049
  913. a4 = 0.29184902646414046425
  914. a5 = 0.88162726744375765242
  915. b0 = 1.0
  916. b1 = -0.14583333333333333333
  917. b2 = -0.09874131944444444444
  918. b3 = -0.14331205391589506173
  919. b4 = -0.31722720267841354810
  920. b5 = -0.94242914795712024914
  921. # Polynomials
  922. # https://dlmf.nist.gov/12.10#E9
  923. # https://dlmf.nist.gov/12.10#E10
  924. ctp = ct ** arange(16).reshape((-1,1))
  925. u0 = 1.0
  926. u1 = (1.0*ctp[3,:] - 6.0*ct) / 24.0
  927. u2 = (-9.0*ctp[4,:] + 249.0*ctp[2,:] + 145.0) / 1152.0
  928. u3 = (-4042.0*ctp[9,:] + 18189.0*ctp[7,:] - 28287.0*ctp[5,:]
  929. - 151995.0*ctp[3,:] - 259290.0*ct) / 414720.0
  930. u4 = (72756.0*ctp[10,:] - 321339.0*ctp[8,:] - 154982.0*ctp[6,:]
  931. + 50938215.0*ctp[4,:] + 122602962.0*ctp[2,:] + 12773113.0) / 39813120.0
  932. u5 = (82393456.0*ctp[15,:] - 617950920.0*ctp[13,:] + 1994971575.0*ctp[11,:]
  933. - 3630137104.0*ctp[9,:] + 4433574213.0*ctp[7,:] - 37370295816.0*ctp[5,:]
  934. - 119582875013.0*ctp[3,:] - 34009066266.0*ct) / 6688604160.0
  935. v0 = 1.0
  936. v1 = (1.0*ctp[3,:] + 6.0*ct) / 24.0
  937. v2 = (15.0*ctp[4,:] - 327.0*ctp[2,:] - 143.0) / 1152.0
  938. v3 = (-4042.0*ctp[9,:] + 18189.0*ctp[7,:] - 36387.0*ctp[5,:]
  939. + 238425.0*ctp[3,:] + 259290.0*ct) / 414720.0
  940. v4 = (-121260.0*ctp[10,:] + 551733.0*ctp[8,:] - 151958.0*ctp[6,:]
  941. - 57484425.0*ctp[4,:] - 132752238.0*ctp[2,:] - 12118727) / 39813120.0
  942. v5 = (82393456.0*ctp[15,:] - 617950920.0*ctp[13,:] + 2025529095.0*ctp[11,:]
  943. - 3750839308.0*ctp[9,:] + 3832454253.0*ctp[7,:] + 35213253348.0*ctp[5,:]
  944. + 130919230435.0*ctp[3,:] + 34009066266*ct) / 6688604160.0
  945. # Airy Evaluation (Bi and Bip unused)
  946. Ai, Aip, Bi, Bip = airy(mu**(4.0/6.0) * zeta)
  947. # Prefactor for U
  948. P = 2.0*sqrt(pi) * mu**(1.0/6.0) * phi
  949. # Terms for U
  950. # https://dlmf.nist.gov/12.10#E42
  951. phip = phi ** arange(6, 31, 6).reshape((-1,1))
  952. A0 = b0*u0
  953. A1 = (b2*u0 + phip[0,:]*b1*u1 + phip[1,:]*b0*u2) / zeta**3
  954. A2 = (b4*u0 + phip[0,:]*b3*u1 + phip[1,:]*b2*u2 + phip[2,:]*b1*u3
  955. + phip[3,:]*b0*u4) / zeta**6
  956. B0 = -(a1*u0 + phip[0,:]*a0*u1) / zeta**2
  957. B1 = -(a3*u0 + phip[0,:]*a2*u1 + phip[1,:]*a1*u2 + phip[2,:]*a0*u3) / zeta**5
  958. B2 = -(a5*u0 + phip[0,:]*a4*u1 + phip[1,:]*a3*u2 + phip[2,:]*a2*u3
  959. + phip[3,:]*a1*u4 + phip[4,:]*a0*u5) / zeta**8
  960. # U
  961. # https://dlmf.nist.gov/12.10#E35
  962. U = P * (Ai * (A0 + A1/mu**2.0 + A2/mu**4.0) +
  963. Aip * (B0 + B1/mu**2.0 + B2/mu**4.0) / mu**(8.0/6.0))
  964. # Prefactor for derivative of U
  965. Pd = sqrt(2.0*pi) * mu**(2.0/6.0) / phi
  966. # Terms for derivative of U
  967. # https://dlmf.nist.gov/12.10#E46
  968. C0 = -(b1*v0 + phip[0,:]*b0*v1) / zeta
  969. C1 = -(b3*v0 + phip[0,:]*b2*v1 + phip[1,:]*b1*v2 + phip[2,:]*b0*v3) / zeta**4
  970. C2 = -(b5*v0 + phip[0,:]*b4*v1 + phip[1,:]*b3*v2 + phip[2,:]*b2*v3
  971. + phip[3,:]*b1*v4 + phip[4,:]*b0*v5) / zeta**7
  972. D0 = a0*v0
  973. D1 = (a2*v0 + phip[0,:]*a1*v1 + phip[1,:]*a0*v2) / zeta**3
  974. D2 = (a4*v0 + phip[0,:]*a3*v1 + phip[1,:]*a2*v2 + phip[2,:]*a1*v3
  975. + phip[3,:]*a0*v4) / zeta**6
  976. # Derivative of U
  977. # https://dlmf.nist.gov/12.10#E36
  978. Ud = Pd * (Ai * (C0 + C1/mu**2.0 + C2/mu**4.0) / mu**(4.0/6.0) +
  979. Aip * (D0 + D1/mu**2.0 + D2/mu**4.0))
  980. return U, Ud
  981. def _newton(n, x_initial, maxit=5):
  982. """Newton iteration for polishing the asymptotic approximation
  983. to the zeros of the Hermite polynomials.
  984. Parameters
  985. ----------
  986. n : int
  987. Quadrature order
  988. x_initial : ndarray
  989. Initial guesses for the roots
  990. maxit : int
  991. Maximal number of Newton iterations.
  992. The default 5 is sufficient, usually
  993. only one or two steps are needed.
  994. Returns
  995. -------
  996. nodes : ndarray
  997. Quadrature nodes
  998. weights : ndarray
  999. Quadrature weights
  1000. See Also
  1001. --------
  1002. roots_hermite_asy
  1003. """
  1004. # Variable transformation
  1005. mu = sqrt(2.0*n + 1.0)
  1006. t = x_initial / mu
  1007. theta = arccos(t)
  1008. # Newton iteration
  1009. for i in range(maxit):
  1010. u, ud = _pbcf(n, theta)
  1011. dtheta = u / (sqrt(2.0) * mu * sin(theta) * ud)
  1012. theta = theta + dtheta
  1013. if max(abs(dtheta)) < 1e-14:
  1014. break
  1015. # Undo variable transformation
  1016. x = mu * cos(theta)
  1017. # Central node is always zero
  1018. if n % 2 == 1:
  1019. x[0] = 0.0
  1020. # Compute weights
  1021. w = exp(-x**2) / (2.0*ud**2)
  1022. return x, w
  1023. def _roots_hermite_asy(n):
  1024. r"""Gauss-Hermite (physicist's) quadrature for large n.
  1025. Computes the sample points and weights for Gauss-Hermite quadrature.
  1026. The sample points are the roots of the nth degree Hermite polynomial,
  1027. :math:`H_n(x)`. These sample points and weights correctly integrate
  1028. polynomials of degree :math:`2n - 1` or less over the interval
  1029. :math:`[-\infty, \infty]` with weight function :math:`f(x) = e^{-x^2}`.
  1030. This method relies on asymptotic expansions which work best for n > 150.
  1031. The algorithm has linear runtime making computation for very large n
  1032. feasible.
  1033. Parameters
  1034. ----------
  1035. n : int
  1036. quadrature order
  1037. Returns
  1038. -------
  1039. nodes : ndarray
  1040. Quadrature nodes
  1041. weights : ndarray
  1042. Quadrature weights
  1043. See Also
  1044. --------
  1045. roots_hermite
  1046. References
  1047. ----------
  1048. .. [townsend.trogdon.olver-2014]
  1049. Townsend, A. and Trogdon, T. and Olver, S. (2014)
  1050. *Fast computation of Gauss quadrature nodes and
  1051. weights on the whole real line*. :arXiv:`1410.5286`.
  1052. .. [townsend.trogdon.olver-2015]
  1053. Townsend, A. and Trogdon, T. and Olver, S. (2015)
  1054. *Fast computation of Gauss quadrature nodes and
  1055. weights on the whole real line*.
  1056. IMA Journal of Numerical Analysis
  1057. :doi:`10.1093/imanum/drv002`.
  1058. """
  1059. iv = _initial_nodes(n)
  1060. nodes, weights = _newton(n, iv)
  1061. # Combine with negative parts
  1062. if n % 2 == 0:
  1063. nodes = hstack([-nodes[::-1], nodes])
  1064. weights = hstack([weights[::-1], weights])
  1065. else:
  1066. nodes = hstack([-nodes[-1:0:-1], nodes])
  1067. weights = hstack([weights[-1:0:-1], weights])
  1068. # Scale weights
  1069. weights *= sqrt(pi) / sum(weights)
  1070. return nodes, weights
  1071. def hermite(n, monic=False):
  1072. r"""Physicist's Hermite polynomial.
  1073. Defined by
  1074. .. math::
  1075. H_n(x) = (-1)^ne^{x^2}\frac{d^n}{dx^n}e^{-x^2};
  1076. :math:`H_n` is a polynomial of degree :math:`n`.
  1077. Parameters
  1078. ----------
  1079. n : int
  1080. Degree of the polynomial.
  1081. monic : bool, optional
  1082. If `True`, scale the leading coefficient to be 1. Default is
  1083. `False`.
  1084. Returns
  1085. -------
  1086. H : orthopoly1d
  1087. Hermite polynomial.
  1088. Notes
  1089. -----
  1090. The polynomials :math:`H_n` are orthogonal over :math:`(-\infty,
  1091. \infty)` with weight function :math:`e^{-x^2}`.
  1092. Examples
  1093. --------
  1094. >>> from scipy import special
  1095. >>> import matplotlib.pyplot as plt
  1096. >>> import numpy as np
  1097. >>> p_monic = special.hermite(3, monic=True)
  1098. >>> p_monic
  1099. poly1d([ 1. , 0. , -1.5, 0. ])
  1100. >>> p_monic(1)
  1101. -0.49999999999999983
  1102. >>> x = np.linspace(-3, 3, 400)
  1103. >>> y = p_monic(x)
  1104. >>> plt.plot(x, y)
  1105. >>> plt.title("Monic Hermite polynomial of degree 3")
  1106. >>> plt.xlabel("x")
  1107. >>> plt.ylabel("H_3(x)")
  1108. >>> plt.show()
  1109. """
  1110. if n < 0:
  1111. raise ValueError("n must be nonnegative.")
  1112. if n == 0:
  1113. n1 = n + 1
  1114. else:
  1115. n1 = n
  1116. x, w = roots_hermite(n1)
  1117. def wfunc(x):
  1118. return exp(-x * x)
  1119. if n == 0:
  1120. x, w = [], []
  1121. hn = 2**n * _gam(n + 1) * sqrt(pi)
  1122. kn = 2**n
  1123. p = orthopoly1d(x, w, hn, kn, wfunc, (-inf, inf), monic,
  1124. lambda x: _ufuncs.eval_hermite(n, x))
  1125. return p
  1126. # Hermite 2 He_n(x)
  1127. def roots_hermitenorm(n, mu=False):
  1128. r"""Gauss-Hermite (statistician's) quadrature.
  1129. Compute the sample points and weights for Gauss-Hermite
  1130. quadrature. The sample points are the roots of the nth degree
  1131. Hermite polynomial, :math:`He_n(x)`. These sample points and
  1132. weights correctly integrate polynomials of degree :math:`2n - 1`
  1133. or less over the interval :math:`[-\infty, \infty]` with weight
  1134. function :math:`w(x) = e^{-x^2/2}`. See 22.2.15 in [AS]_ for more
  1135. details.
  1136. Parameters
  1137. ----------
  1138. n : int
  1139. quadrature order
  1140. mu : bool, optional
  1141. If True, return the sum of the weights, optional.
  1142. Returns
  1143. -------
  1144. x : ndarray
  1145. Sample points
  1146. w : ndarray
  1147. Weights
  1148. mu : float
  1149. Sum of the weights
  1150. See Also
  1151. --------
  1152. scipy.integrate.fixed_quad
  1153. numpy.polynomial.hermite_e.hermegauss
  1154. Notes
  1155. -----
  1156. For small n up to 150 a modified version of the Golub-Welsch
  1157. algorithm is used. Nodes are computed from the eigenvalue
  1158. problem and improved by one step of a Newton iteration.
  1159. The weights are computed from the well-known analytical formula.
  1160. For n larger than 150 an optimal asymptotic algorithm is used
  1161. which computes nodes and weights in a numerical stable manner.
  1162. The algorithm has linear runtime making computation for very
  1163. large n (several thousand or more) feasible.
  1164. References
  1165. ----------
  1166. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  1167. Handbook of Mathematical Functions with Formulas,
  1168. Graphs, and Mathematical Tables. New York: Dover, 1972.
  1169. """
  1170. m = int(n)
  1171. if n < 1 or n != m:
  1172. raise ValueError("n must be a positive integer.")
  1173. mu0 = np.sqrt(2.0*np.pi)
  1174. if n <= 150:
  1175. def an_func(k):
  1176. return 0.0 * k
  1177. def bn_func(k):
  1178. return np.sqrt(k)
  1179. f = _ufuncs.eval_hermitenorm
  1180. def df(n, x):
  1181. return n * _ufuncs.eval_hermitenorm(n - 1, x)
  1182. return _gen_roots_and_weights(m, mu0, an_func, bn_func, f, df, True, mu)
  1183. else:
  1184. nodes, weights = _roots_hermite_asy(m)
  1185. # Transform
  1186. nodes *= sqrt(2)
  1187. weights *= sqrt(2)
  1188. if mu:
  1189. return nodes, weights, mu0
  1190. else:
  1191. return nodes, weights
  1192. def hermitenorm(n, monic=False):
  1193. r"""Normalized (probabilist's) Hermite polynomial.
  1194. Defined by
  1195. .. math::
  1196. He_n(x) = (-1)^ne^{x^2/2}\frac{d^n}{dx^n}e^{-x^2/2};
  1197. :math:`He_n` is a polynomial of degree :math:`n`.
  1198. Parameters
  1199. ----------
  1200. n : int
  1201. Degree of the polynomial.
  1202. monic : bool, optional
  1203. If `True`, scale the leading coefficient to be 1. Default is
  1204. `False`.
  1205. Returns
  1206. -------
  1207. He : orthopoly1d
  1208. Hermite polynomial.
  1209. Notes
  1210. -----
  1211. The polynomials :math:`He_n` are orthogonal over :math:`(-\infty,
  1212. \infty)` with weight function :math:`e^{-x^2/2}`.
  1213. """
  1214. if n < 0:
  1215. raise ValueError("n must be nonnegative.")
  1216. if n == 0:
  1217. n1 = n + 1
  1218. else:
  1219. n1 = n
  1220. x, w = roots_hermitenorm(n1)
  1221. def wfunc(x):
  1222. return exp(-x * x / 2.0)
  1223. if n == 0:
  1224. x, w = [], []
  1225. hn = sqrt(2 * pi) * _gam(n + 1)
  1226. kn = 1.0
  1227. p = orthopoly1d(x, w, hn, kn, wfunc=wfunc, limits=(-inf, inf), monic=monic,
  1228. eval_func=lambda x: _ufuncs.eval_hermitenorm(n, x))
  1229. return p
  1230. # The remainder of the polynomials can be derived from the ones above.
  1231. # Ultraspherical (Gegenbauer) C^(alpha)_n(x)
  1232. def roots_gegenbauer(n, alpha, mu=False):
  1233. r"""Gauss-Gegenbauer quadrature.
  1234. Compute the sample points and weights for Gauss-Gegenbauer
  1235. quadrature. The sample points are the roots of the nth degree
  1236. Gegenbauer polynomial, :math:`C^{\alpha}_n(x)`. These sample
  1237. points and weights correctly integrate polynomials of degree
  1238. :math:`2n - 1` or less over the interval :math:`[-1, 1]` with
  1239. weight function :math:`w(x) = (1 - x^2)^{\alpha - 1/2}`. See
  1240. 22.2.3 in [AS]_ for more details.
  1241. Parameters
  1242. ----------
  1243. n : int
  1244. quadrature order
  1245. alpha : float
  1246. alpha must be > -0.5
  1247. mu : bool, optional
  1248. If True, return the sum of the weights, optional.
  1249. Returns
  1250. -------
  1251. x : ndarray
  1252. Sample points
  1253. w : ndarray
  1254. Weights
  1255. mu : float
  1256. Sum of the weights
  1257. See Also
  1258. --------
  1259. scipy.integrate.fixed_quad
  1260. References
  1261. ----------
  1262. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  1263. Handbook of Mathematical Functions with Formulas,
  1264. Graphs, and Mathematical Tables. New York: Dover, 1972.
  1265. """
  1266. m = int(n)
  1267. if n < 1 or n != m:
  1268. raise ValueError("n must be a positive integer.")
  1269. if alpha < -0.5:
  1270. raise ValueError("alpha must be greater than -0.5.")
  1271. elif alpha == 0.0:
  1272. # C(n,0,x) == 0 uniformly, however, as alpha->0, C(n,alpha,x)->T(n,x)
  1273. # strictly, we should just error out here, since the roots are not
  1274. # really defined, but we used to return something useful, so let's
  1275. # keep doing so.
  1276. return roots_chebyt(n, mu)
  1277. if alpha <= 170:
  1278. mu0 = (np.sqrt(np.pi) * _ufuncs.gamma(alpha + 0.5)) \
  1279. / _ufuncs.gamma(alpha + 1)
  1280. else:
  1281. # For large alpha we use a Taylor series expansion around inf,
  1282. # expressed as a 6th order polynomial of a^-1 and using Horner's
  1283. # method to minimize computation and maximize precision
  1284. inv_alpha = 1. / alpha
  1285. coeffs = np.array([0.000207186, -0.00152206, -0.000640869,
  1286. 0.00488281, 0.0078125, -0.125, 1.])
  1287. mu0 = coeffs[0]
  1288. for term in range(1, len(coeffs)):
  1289. mu0 = mu0 * inv_alpha + coeffs[term]
  1290. mu0 = mu0 * np.sqrt(np.pi / alpha)
  1291. def an_func(k):
  1292. return 0.0 * k
  1293. def bn_func(k):
  1294. return np.sqrt(k * (k + 2 * alpha - 1) / (4 * (k + alpha) * (k + alpha - 1)))
  1295. def f(n, x):
  1296. return _ufuncs.eval_gegenbauer(n, alpha, x)
  1297. def df(n, x):
  1298. return (
  1299. -n * x * _ufuncs.eval_gegenbauer(n, alpha, x)
  1300. + (n + 2 * alpha - 1) * _ufuncs.eval_gegenbauer(n - 1, alpha, x)
  1301. ) / (1 - x ** 2)
  1302. return _gen_roots_and_weights(m, mu0, an_func, bn_func, f, df, True, mu)
  1303. def gegenbauer(n, alpha, monic=False):
  1304. r"""Gegenbauer (ultraspherical) polynomial.
  1305. Defined to be the solution of
  1306. .. math::
  1307. (1 - x^2)\frac{d^2}{dx^2}C_n^{(\alpha)}
  1308. - (2\alpha + 1)x\frac{d}{dx}C_n^{(\alpha)}
  1309. + n(n + 2\alpha)C_n^{(\alpha)} = 0
  1310. for :math:`\alpha > -1/2`; :math:`C_n^{(\alpha)}` is a polynomial
  1311. of degree :math:`n`.
  1312. Parameters
  1313. ----------
  1314. n : int
  1315. Degree of the polynomial.
  1316. alpha : float
  1317. Parameter, must be greater than -0.5.
  1318. monic : bool, optional
  1319. If `True`, scale the leading coefficient to be 1. Default is
  1320. `False`.
  1321. Returns
  1322. -------
  1323. C : orthopoly1d
  1324. Gegenbauer polynomial.
  1325. Notes
  1326. -----
  1327. The polynomials :math:`C_n^{(\alpha)}` are orthogonal over
  1328. :math:`[-1,1]` with weight function :math:`(1 - x^2)^{(\alpha -
  1329. 1/2)}`.
  1330. Examples
  1331. --------
  1332. >>> import numpy as np
  1333. >>> from scipy import special
  1334. >>> import matplotlib.pyplot as plt
  1335. We can initialize a variable ``p`` as a Gegenbauer polynomial using the
  1336. `gegenbauer` function and evaluate at a point ``x = 1``.
  1337. >>> p = special.gegenbauer(3, 0.5, monic=False)
  1338. >>> p
  1339. poly1d([ 2.5, 0. , -1.5, 0. ])
  1340. >>> p(1)
  1341. 1.0
  1342. To evaluate ``p`` at various points ``x`` in the interval ``(-3, 3)``,
  1343. simply pass an array ``x`` to ``p`` as follows:
  1344. >>> x = np.linspace(-3, 3, 400)
  1345. >>> y = p(x)
  1346. We can then visualize ``x, y`` using `matplotlib.pyplot`.
  1347. >>> fig, ax = plt.subplots()
  1348. >>> ax.plot(x, y)
  1349. >>> ax.set_title("Gegenbauer (ultraspherical) polynomial of degree 3")
  1350. >>> ax.set_xlabel("x")
  1351. >>> ax.set_ylabel("G_3(x)")
  1352. >>> plt.show()
  1353. """
  1354. if not np.isfinite(alpha) or alpha <= -0.5 :
  1355. raise ValueError("`alpha` must be a finite number greater than -1/2")
  1356. base = jacobi(n, alpha - 0.5, alpha - 0.5, monic=monic)
  1357. if monic or n == 0:
  1358. return base
  1359. # Abrahmowitz and Stegan 22.5.20
  1360. factor = (_gam(2*alpha + n) * _gam(alpha + 0.5) /
  1361. _gam(2*alpha) / _gam(alpha + 0.5 + n))
  1362. base._scale(factor)
  1363. base.__dict__['_eval_func'] = lambda x: _ufuncs.eval_gegenbauer(float(n),
  1364. alpha, x)
  1365. return base
  1366. # Chebyshev of the first kind: T_n(x) =
  1367. # n! sqrt(pi) / _gam(n+1./2)* P^(-1/2,-1/2)_n(x)
  1368. # Computed anew.
  1369. def roots_chebyt(n, mu=False):
  1370. r"""Gauss-Chebyshev (first kind) quadrature.
  1371. Computes the sample points and weights for Gauss-Chebyshev
  1372. quadrature. The sample points are the roots of the nth degree
  1373. Chebyshev polynomial of the first kind, :math:`T_n(x)`. These
  1374. sample points and weights correctly integrate polynomials of
  1375. degree :math:`2n - 1` or less over the interval :math:`[-1, 1]`
  1376. with weight function :math:`w(x) = 1/\sqrt{1 - x^2}`. See 22.2.4
  1377. in [AS]_ for more details.
  1378. Parameters
  1379. ----------
  1380. n : int
  1381. quadrature order
  1382. mu : bool, optional
  1383. If True, return the sum of the weights, optional.
  1384. Returns
  1385. -------
  1386. x : ndarray
  1387. Sample points
  1388. w : ndarray
  1389. Weights
  1390. mu : float
  1391. Sum of the weights
  1392. See Also
  1393. --------
  1394. scipy.integrate.fixed_quad
  1395. numpy.polynomial.chebyshev.chebgauss
  1396. References
  1397. ----------
  1398. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  1399. Handbook of Mathematical Functions with Formulas,
  1400. Graphs, and Mathematical Tables. New York: Dover, 1972.
  1401. """
  1402. m = int(n)
  1403. if n < 1 or n != m:
  1404. raise ValueError('n must be a positive integer.')
  1405. x = _ufuncs._sinpi(np.arange(-m + 1, m, 2) / (2*m))
  1406. w = np.full_like(x, pi/m)
  1407. if mu:
  1408. return x, w, pi
  1409. else:
  1410. return x, w
  1411. def chebyt(n, monic=False):
  1412. r"""Chebyshev polynomial of the first kind.
  1413. Defined to be the solution of
  1414. .. math::
  1415. (1 - x^2)\frac{d^2}{dx^2}T_n - x\frac{d}{dx}T_n + n^2T_n = 0;
  1416. :math:`T_n` is a polynomial of degree :math:`n`.
  1417. Parameters
  1418. ----------
  1419. n : int
  1420. Degree of the polynomial.
  1421. monic : bool, optional
  1422. If `True`, scale the leading coefficient to be 1. Default is
  1423. `False`.
  1424. Returns
  1425. -------
  1426. T : orthopoly1d
  1427. Chebyshev polynomial of the first kind.
  1428. See Also
  1429. --------
  1430. chebyu : Chebyshev polynomial of the second kind.
  1431. Notes
  1432. -----
  1433. The polynomials :math:`T_n` are orthogonal over :math:`[-1, 1]`
  1434. with weight function :math:`(1 - x^2)^{-1/2}`.
  1435. References
  1436. ----------
  1437. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  1438. Handbook of Mathematical Functions with Formulas,
  1439. Graphs, and Mathematical Tables. New York: Dover, 1972.
  1440. Examples
  1441. --------
  1442. Chebyshev polynomials of the first kind of order :math:`n` can
  1443. be obtained as the determinant of specific :math:`n \times n`
  1444. matrices. As an example we can check how the points obtained from
  1445. the determinant of the following :math:`3 \times 3` matrix
  1446. lay exactly on :math:`T_3`:
  1447. >>> import numpy as np
  1448. >>> import matplotlib.pyplot as plt
  1449. >>> from scipy.linalg import det
  1450. >>> from scipy.special import chebyt
  1451. >>> x = np.arange(-1.0, 1.0, 0.01)
  1452. >>> fig, ax = plt.subplots()
  1453. >>> ax.set_ylim(-2.0, 2.0)
  1454. >>> ax.set_title(r'Chebyshev polynomial $T_3$')
  1455. >>> ax.plot(x, chebyt(3)(x), label=rf'$T_3$')
  1456. >>> for p in np.arange(-1.0, 1.0, 0.1):
  1457. ... ax.plot(p,
  1458. ... det(np.array([[p, 1, 0], [1, 2*p, 1], [0, 1, 2*p]])),
  1459. ... 'rx')
  1460. >>> plt.legend(loc='best')
  1461. >>> plt.show()
  1462. They are also related to the Jacobi Polynomials
  1463. :math:`P_n^{(-0.5, -0.5)}` through the relation:
  1464. .. math::
  1465. P_n^{(-0.5, -0.5)}(x) = \frac{1}{4^n} \binom{2n}{n} T_n(x)
  1466. Let's verify it for :math:`n = 3`:
  1467. >>> from scipy.special import binom
  1468. >>> from scipy.special import jacobi
  1469. >>> x = np.arange(-1.0, 1.0, 0.01)
  1470. >>> np.allclose(jacobi(3, -0.5, -0.5)(x),
  1471. ... 1/64 * binom(6, 3) * chebyt(3)(x))
  1472. True
  1473. We can plot the Chebyshev polynomials :math:`T_n` for some values
  1474. of :math:`n`:
  1475. >>> x = np.arange(-1.5, 1.5, 0.01)
  1476. >>> fig, ax = plt.subplots()
  1477. >>> ax.set_ylim(-4.0, 4.0)
  1478. >>> ax.set_title(r'Chebyshev polynomials $T_n$')
  1479. >>> for n in np.arange(2,5):
  1480. ... ax.plot(x, chebyt(n)(x), label=rf'$T_n={n}$')
  1481. >>> plt.legend(loc='best')
  1482. >>> plt.show()
  1483. """
  1484. if n < 0:
  1485. raise ValueError("n must be nonnegative.")
  1486. def wfunc(x):
  1487. return 1.0 / sqrt(1 - x * x)
  1488. if n == 0:
  1489. return orthopoly1d([], [], pi, 1.0, wfunc, (-1, 1), monic,
  1490. lambda x: _ufuncs.eval_chebyt(n, x))
  1491. n1 = n
  1492. x, w, mu = roots_chebyt(n1, mu=True)
  1493. hn = pi / 2
  1494. kn = 2**(n - 1)
  1495. p = orthopoly1d(x, w, hn, kn, wfunc, (-1, 1), monic,
  1496. lambda x: _ufuncs.eval_chebyt(n, x))
  1497. return p
  1498. # Chebyshev of the second kind
  1499. # U_n(x) = (n+1)! sqrt(pi) / (2*_gam(n+3./2)) * P^(1/2,1/2)_n(x)
  1500. def roots_chebyu(n, mu=False):
  1501. r"""Gauss-Chebyshev (second kind) quadrature.
  1502. Computes the sample points and weights for Gauss-Chebyshev
  1503. quadrature. The sample points are the roots of the nth degree
  1504. Chebyshev polynomial of the second kind, :math:`U_n(x)`. These
  1505. sample points and weights correctly integrate polynomials of
  1506. degree :math:`2n - 1` or less over the interval :math:`[-1, 1]`
  1507. with weight function :math:`w(x) = \sqrt{1 - x^2}`. See 22.2.5 in
  1508. [AS]_ for details.
  1509. Parameters
  1510. ----------
  1511. n : int
  1512. quadrature order
  1513. mu : bool, optional
  1514. If True, return the sum of the weights, optional.
  1515. Returns
  1516. -------
  1517. x : ndarray
  1518. Sample points
  1519. w : ndarray
  1520. Weights
  1521. mu : float
  1522. Sum of the weights
  1523. See Also
  1524. --------
  1525. scipy.integrate.fixed_quad
  1526. References
  1527. ----------
  1528. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  1529. Handbook of Mathematical Functions with Formulas,
  1530. Graphs, and Mathematical Tables. New York: Dover, 1972.
  1531. """
  1532. m = int(n)
  1533. if n < 1 or n != m:
  1534. raise ValueError('n must be a positive integer.')
  1535. t = np.arange(m, 0, -1) * pi / (m + 1)
  1536. x = np.cos(t)
  1537. w = pi * np.sin(t)**2 / (m + 1)
  1538. if mu:
  1539. return x, w, pi / 2
  1540. else:
  1541. return x, w
  1542. def chebyu(n, monic=False):
  1543. r"""Chebyshev polynomial of the second kind.
  1544. Defined to be the solution of
  1545. .. math::
  1546. (1 - x^2)\frac{d^2}{dx^2}U_n - 3x\frac{d}{dx}U_n
  1547. + n(n + 2)U_n = 0;
  1548. :math:`U_n` is a polynomial of degree :math:`n`.
  1549. Parameters
  1550. ----------
  1551. n : int
  1552. Degree of the polynomial.
  1553. monic : bool, optional
  1554. If `True`, scale the leading coefficient to be 1. Default is
  1555. `False`.
  1556. Returns
  1557. -------
  1558. U : orthopoly1d
  1559. Chebyshev polynomial of the second kind.
  1560. See Also
  1561. --------
  1562. chebyt : Chebyshev polynomial of the first kind.
  1563. Notes
  1564. -----
  1565. The polynomials :math:`U_n` are orthogonal over :math:`[-1, 1]`
  1566. with weight function :math:`(1 - x^2)^{1/2}`.
  1567. References
  1568. ----------
  1569. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  1570. Handbook of Mathematical Functions with Formulas,
  1571. Graphs, and Mathematical Tables. New York: Dover, 1972.
  1572. Examples
  1573. --------
  1574. Chebyshev polynomials of the second kind of order :math:`n` can
  1575. be obtained as the determinant of specific :math:`n \times n`
  1576. matrices. As an example we can check how the points obtained from
  1577. the determinant of the following :math:`3 \times 3` matrix
  1578. lay exactly on :math:`U_3`:
  1579. >>> import numpy as np
  1580. >>> import matplotlib.pyplot as plt
  1581. >>> from scipy.linalg import det
  1582. >>> from scipy.special import chebyu
  1583. >>> x = np.arange(-1.0, 1.0, 0.01)
  1584. >>> fig, ax = plt.subplots()
  1585. >>> ax.set_ylim(-2.0, 2.0)
  1586. >>> ax.set_title(r'Chebyshev polynomial $U_3$')
  1587. >>> ax.plot(x, chebyu(3)(x), label=rf'$U_3$')
  1588. >>> for p in np.arange(-1.0, 1.0, 0.1):
  1589. ... ax.plot(p,
  1590. ... det(np.array([[2*p, 1, 0], [1, 2*p, 1], [0, 1, 2*p]])),
  1591. ... 'rx')
  1592. >>> plt.legend(loc='best')
  1593. >>> plt.show()
  1594. They satisfy the recurrence relation:
  1595. .. math::
  1596. U_{2n-1}(x) = 2 T_n(x)U_{n-1}(x)
  1597. where the :math:`T_n` are the Chebyshev polynomial of the first kind.
  1598. Let's verify it for :math:`n = 2`:
  1599. >>> from scipy.special import chebyt
  1600. >>> x = np.arange(-1.0, 1.0, 0.01)
  1601. >>> np.allclose(chebyu(3)(x), 2 * chebyt(2)(x) * chebyu(1)(x))
  1602. True
  1603. We can plot the Chebyshev polynomials :math:`U_n` for some values
  1604. of :math:`n`:
  1605. >>> x = np.arange(-1.0, 1.0, 0.01)
  1606. >>> fig, ax = plt.subplots()
  1607. >>> ax.set_ylim(-1.5, 1.5)
  1608. >>> ax.set_title(r'Chebyshev polynomials $U_n$')
  1609. >>> for n in np.arange(1,5):
  1610. ... ax.plot(x, chebyu(n)(x), label=rf'$U_n={n}$')
  1611. >>> plt.legend(loc='best')
  1612. >>> plt.show()
  1613. """
  1614. base = jacobi(n, 0.5, 0.5, monic=monic)
  1615. if monic:
  1616. return base
  1617. factor = sqrt(pi) / 2.0 * _gam(n + 2) / _gam(n + 1.5)
  1618. base._scale(factor)
  1619. return base
  1620. # Chebyshev of the first kind C_n(x)
  1621. def roots_chebyc(n, mu=False):
  1622. r"""Gauss-Chebyshev (first kind) quadrature.
  1623. Compute the sample points and weights for Gauss-Chebyshev
  1624. quadrature. The sample points are the roots of the nth degree
  1625. Chebyshev polynomial of the first kind, :math:`C_n(x)`. These
  1626. sample points and weights correctly integrate polynomials of
  1627. degree :math:`2n - 1` or less over the interval :math:`[-2, 2]`
  1628. with weight function :math:`w(x) = 1 / \sqrt{1 - (x/2)^2}`. See
  1629. 22.2.6 in [AS]_ for more details.
  1630. Parameters
  1631. ----------
  1632. n : int
  1633. quadrature order
  1634. mu : bool, optional
  1635. If True, return the sum of the weights, optional.
  1636. Returns
  1637. -------
  1638. x : ndarray
  1639. Sample points
  1640. w : ndarray
  1641. Weights
  1642. mu : float
  1643. Sum of the weights
  1644. See Also
  1645. --------
  1646. scipy.integrate.fixed_quad
  1647. References
  1648. ----------
  1649. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  1650. Handbook of Mathematical Functions with Formulas,
  1651. Graphs, and Mathematical Tables. New York: Dover, 1972.
  1652. """
  1653. x, w, m = roots_chebyt(n, True)
  1654. x *= 2
  1655. w *= 2
  1656. m *= 2
  1657. if mu:
  1658. return x, w, m
  1659. else:
  1660. return x, w
  1661. def chebyc(n, monic=False):
  1662. r"""Chebyshev polynomial of the first kind on :math:`[-2, 2]`.
  1663. Defined as :math:`C_n(x) = 2T_n(x/2)`, where :math:`T_n` is the
  1664. nth Chebychev polynomial of the first kind.
  1665. Parameters
  1666. ----------
  1667. n : int
  1668. Degree of the polynomial.
  1669. monic : bool, optional
  1670. If `True`, scale the leading coefficient to be 1. Default is
  1671. `False`.
  1672. Returns
  1673. -------
  1674. C : orthopoly1d
  1675. Chebyshev polynomial of the first kind on :math:`[-2, 2]`.
  1676. See Also
  1677. --------
  1678. chebyt : Chebyshev polynomial of the first kind.
  1679. Notes
  1680. -----
  1681. The polynomials :math:`C_n(x)` are orthogonal over :math:`[-2, 2]`
  1682. with weight function :math:`1/\sqrt{1 - (x/2)^2}`.
  1683. References
  1684. ----------
  1685. .. [1] Abramowitz and Stegun, "Handbook of Mathematical Functions"
  1686. Section 22. National Bureau of Standards, 1972.
  1687. """
  1688. if n < 0:
  1689. raise ValueError("n must be nonnegative.")
  1690. if n == 0:
  1691. n1 = n + 1
  1692. else:
  1693. n1 = n
  1694. x, w = roots_chebyc(n1)
  1695. if n == 0:
  1696. x, w = [], []
  1697. hn = 4 * pi * ((n == 0) + 1)
  1698. kn = 1.0
  1699. p = orthopoly1d(x, w, hn, kn,
  1700. wfunc=lambda x: 1.0 / sqrt(1 - x * x / 4.0),
  1701. limits=(-2, 2), monic=monic)
  1702. if not monic:
  1703. p._scale(2.0 / p(2))
  1704. p.__dict__['_eval_func'] = lambda x: _ufuncs.eval_chebyc(n, x)
  1705. return p
  1706. # Chebyshev of the second kind S_n(x)
  1707. def roots_chebys(n, mu=False):
  1708. r"""Gauss-Chebyshev (second kind) quadrature.
  1709. Compute the sample points and weights for Gauss-Chebyshev
  1710. quadrature. The sample points are the roots of the nth degree
  1711. Chebyshev polynomial of the second kind, :math:`S_n(x)`. These
  1712. sample points and weights correctly integrate polynomials of
  1713. degree :math:`2n - 1` or less over the interval :math:`[-2, 2]`
  1714. with weight function :math:`w(x) = \sqrt{1 - (x/2)^2}`. See 22.2.7
  1715. in [AS]_ for more details.
  1716. Parameters
  1717. ----------
  1718. n : int
  1719. quadrature order
  1720. mu : bool, optional
  1721. If True, return the sum of the weights, optional.
  1722. Returns
  1723. -------
  1724. x : ndarray
  1725. Sample points
  1726. w : ndarray
  1727. Weights
  1728. mu : float
  1729. Sum of the weights
  1730. See Also
  1731. --------
  1732. scipy.integrate.fixed_quad
  1733. References
  1734. ----------
  1735. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  1736. Handbook of Mathematical Functions with Formulas,
  1737. Graphs, and Mathematical Tables. New York: Dover, 1972.
  1738. """
  1739. x, w, m = roots_chebyu(n, True)
  1740. x *= 2
  1741. w *= 2
  1742. m *= 2
  1743. if mu:
  1744. return x, w, m
  1745. else:
  1746. return x, w
  1747. def chebys(n, monic=False):
  1748. r"""Chebyshev polynomial of the second kind on :math:`[-2, 2]`.
  1749. Defined as :math:`S_n(x) = U_n(x/2)` where :math:`U_n` is the
  1750. nth Chebychev polynomial of the second kind.
  1751. Parameters
  1752. ----------
  1753. n : int
  1754. Degree of the polynomial.
  1755. monic : bool, optional
  1756. If `True`, scale the leading coefficient to be 1. Default is
  1757. `False`.
  1758. Returns
  1759. -------
  1760. S : orthopoly1d
  1761. Chebyshev polynomial of the second kind on :math:`[-2, 2]`.
  1762. See Also
  1763. --------
  1764. chebyu : Chebyshev polynomial of the second kind
  1765. Notes
  1766. -----
  1767. The polynomials :math:`S_n(x)` are orthogonal over :math:`[-2, 2]`
  1768. with weight function :math:`\sqrt{1 - (x/2)}^2`.
  1769. References
  1770. ----------
  1771. .. [1] Abramowitz and Stegun, "Handbook of Mathematical Functions"
  1772. Section 22. National Bureau of Standards, 1972.
  1773. """
  1774. if n < 0:
  1775. raise ValueError("n must be nonnegative.")
  1776. if n == 0:
  1777. n1 = n + 1
  1778. else:
  1779. n1 = n
  1780. x, w = roots_chebys(n1)
  1781. if n == 0:
  1782. x, w = [], []
  1783. hn = pi
  1784. kn = 1.0
  1785. p = orthopoly1d(x, w, hn, kn,
  1786. wfunc=lambda x: sqrt(1 - x * x / 4.0),
  1787. limits=(-2, 2), monic=monic)
  1788. if not monic:
  1789. factor = (n + 1.0) / p(2)
  1790. p._scale(factor)
  1791. p.__dict__['_eval_func'] = lambda x: _ufuncs.eval_chebys(n, x)
  1792. return p
  1793. # Shifted Chebyshev of the first kind T^*_n(x)
  1794. def roots_sh_chebyt(n, mu=False):
  1795. r"""Gauss-Chebyshev (first kind, shifted) quadrature.
  1796. Compute the sample points and weights for Gauss-Chebyshev
  1797. quadrature. The sample points are the roots of the nth degree
  1798. shifted Chebyshev polynomial of the first kind, :math:`T_n(x)`.
  1799. These sample points and weights correctly integrate polynomials of
  1800. degree :math:`2n - 1` or less over the interval :math:`[0, 1]`
  1801. with weight function :math:`w(x) = 1/\sqrt{x - x^2}`. See 22.2.8
  1802. in [AS]_ for more details.
  1803. Parameters
  1804. ----------
  1805. n : int
  1806. quadrature order
  1807. mu : bool, optional
  1808. If True, return the sum of the weights, optional.
  1809. Returns
  1810. -------
  1811. x : ndarray
  1812. Sample points
  1813. w : ndarray
  1814. Weights
  1815. mu : float
  1816. Sum of the weights
  1817. See Also
  1818. --------
  1819. scipy.integrate.fixed_quad
  1820. References
  1821. ----------
  1822. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  1823. Handbook of Mathematical Functions with Formulas,
  1824. Graphs, and Mathematical Tables. New York: Dover, 1972.
  1825. """
  1826. xw = roots_chebyt(n, mu)
  1827. return ((xw[0] + 1) / 2,) + xw[1:]
  1828. def sh_chebyt(n, monic=False):
  1829. r"""Shifted Chebyshev polynomial of the first kind.
  1830. Defined as :math:`T^*_n(x) = T_n(2x - 1)` for :math:`T_n` the nth
  1831. Chebyshev polynomial of the first kind.
  1832. Parameters
  1833. ----------
  1834. n : int
  1835. Degree of the polynomial.
  1836. monic : bool, optional
  1837. If `True`, scale the leading coefficient to be 1. Default is
  1838. `False`.
  1839. Returns
  1840. -------
  1841. T : orthopoly1d
  1842. Shifted Chebyshev polynomial of the first kind.
  1843. Notes
  1844. -----
  1845. The polynomials :math:`T^*_n` are orthogonal over :math:`[0, 1]`
  1846. with weight function :math:`(x - x^2)^{-1/2}`.
  1847. """
  1848. base = sh_jacobi(n, 0.0, 0.5, monic=monic)
  1849. if monic:
  1850. return base
  1851. if n > 0:
  1852. factor = 4**n / 2.0
  1853. else:
  1854. factor = 1.0
  1855. base._scale(factor)
  1856. return base
  1857. # Shifted Chebyshev of the second kind U^*_n(x)
  1858. def roots_sh_chebyu(n, mu=False):
  1859. r"""Gauss-Chebyshev (second kind, shifted) quadrature.
  1860. Computes the sample points and weights for Gauss-Chebyshev
  1861. quadrature. The sample points are the roots of the nth degree
  1862. shifted Chebyshev polynomial of the second kind, :math:`U_n(x)`.
  1863. These sample points and weights correctly integrate polynomials of
  1864. degree :math:`2n - 1` or less over the interval :math:`[0, 1]`
  1865. with weight function :math:`w(x) = \sqrt{x - x^2}`. See 22.2.9 in
  1866. [AS]_ for more details.
  1867. Parameters
  1868. ----------
  1869. n : int
  1870. quadrature order
  1871. mu : bool, optional
  1872. If True, return the sum of the weights, optional.
  1873. Returns
  1874. -------
  1875. x : ndarray
  1876. Sample points
  1877. w : ndarray
  1878. Weights
  1879. mu : float
  1880. Sum of the weights
  1881. See Also
  1882. --------
  1883. scipy.integrate.fixed_quad
  1884. References
  1885. ----------
  1886. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  1887. Handbook of Mathematical Functions with Formulas,
  1888. Graphs, and Mathematical Tables. New York: Dover, 1972.
  1889. """
  1890. x, w, m = roots_chebyu(n, True)
  1891. x = (x + 1) / 2
  1892. m_us = _ufuncs.beta(1.5, 1.5)
  1893. w *= m_us / m
  1894. if mu:
  1895. return x, w, m_us
  1896. else:
  1897. return x, w
  1898. def sh_chebyu(n, monic=False):
  1899. r"""Shifted Chebyshev polynomial of the second kind.
  1900. Defined as :math:`U^*_n(x) = U_n(2x - 1)` for :math:`U_n` the nth
  1901. Chebyshev polynomial of the second kind.
  1902. Parameters
  1903. ----------
  1904. n : int
  1905. Degree of the polynomial.
  1906. monic : bool, optional
  1907. If `True`, scale the leading coefficient to be 1. Default is
  1908. `False`.
  1909. Returns
  1910. -------
  1911. U : orthopoly1d
  1912. Shifted Chebyshev polynomial of the second kind.
  1913. Notes
  1914. -----
  1915. The polynomials :math:`U^*_n` are orthogonal over :math:`[0, 1]`
  1916. with weight function :math:`(x - x^2)^{1/2}`.
  1917. """
  1918. base = sh_jacobi(n, 2.0, 1.5, monic=monic)
  1919. if monic:
  1920. return base
  1921. factor = 4**n
  1922. base._scale(factor)
  1923. return base
  1924. # Legendre
  1925. def roots_legendre(n, mu=False):
  1926. r"""Gauss-Legendre quadrature.
  1927. Compute the sample points and weights for Gauss-Legendre
  1928. quadrature [GL]_. The sample points are the roots of the nth degree
  1929. Legendre polynomial :math:`P_n(x)`. These sample points and
  1930. weights correctly integrate polynomials of degree :math:`2n - 1`
  1931. or less over the interval :math:`[-1, 1]` with weight function
  1932. :math:`w(x) = 1`. See 2.2.10 in [AS]_ for more details.
  1933. Parameters
  1934. ----------
  1935. n : int
  1936. quadrature order
  1937. mu : bool, optional
  1938. If True, return the sum of the weights, optional.
  1939. Returns
  1940. -------
  1941. x : ndarray
  1942. Sample points
  1943. w : ndarray
  1944. Weights
  1945. mu : float
  1946. Sum of the weights
  1947. See Also
  1948. --------
  1949. scipy.integrate.fixed_quad
  1950. numpy.polynomial.legendre.leggauss
  1951. References
  1952. ----------
  1953. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  1954. Handbook of Mathematical Functions with Formulas,
  1955. Graphs, and Mathematical Tables. New York: Dover, 1972.
  1956. .. [GL] Gauss-Legendre quadrature, Wikipedia,
  1957. https://en.wikipedia.org/wiki/Gauss%E2%80%93Legendre_quadrature
  1958. Examples
  1959. --------
  1960. >>> import numpy as np
  1961. >>> from scipy.special import roots_legendre, eval_legendre
  1962. >>> roots, weights = roots_legendre(9)
  1963. ``roots`` holds the roots, and ``weights`` holds the weights for
  1964. Gauss-Legendre quadrature.
  1965. >>> roots
  1966. array([-0.96816024, -0.83603111, -0.61337143, -0.32425342, 0. ,
  1967. 0.32425342, 0.61337143, 0.83603111, 0.96816024])
  1968. >>> weights
  1969. array([0.08127439, 0.18064816, 0.2606107 , 0.31234708, 0.33023936,
  1970. 0.31234708, 0.2606107 , 0.18064816, 0.08127439])
  1971. Verify that we have the roots by evaluating the degree 9 Legendre
  1972. polynomial at ``roots``. All the values are approximately zero:
  1973. >>> eval_legendre(9, roots)
  1974. array([-8.88178420e-16, -2.22044605e-16, 1.11022302e-16, 1.11022302e-16,
  1975. 0.00000000e+00, -5.55111512e-17, -1.94289029e-16, 1.38777878e-16,
  1976. -8.32667268e-17])
  1977. Here we'll show how the above values can be used to estimate the
  1978. integral from 1 to 2 of f(t) = t + 1/t with Gauss-Legendre
  1979. quadrature [GL]_. First define the function and the integration
  1980. limits.
  1981. >>> def f(t):
  1982. ... return t + 1/t
  1983. ...
  1984. >>> a = 1
  1985. >>> b = 2
  1986. We'll use ``integral(f(t), t=a, t=b)`` to denote the definite integral
  1987. of f from t=a to t=b. The sample points in ``roots`` are from the
  1988. interval [-1, 1], so we'll rewrite the integral with the simple change
  1989. of variable::
  1990. x = 2/(b - a) * t - (a + b)/(b - a)
  1991. with inverse::
  1992. t = (b - a)/2 * x + (a + b)/2
  1993. Then::
  1994. integral(f(t), a, b) =
  1995. (b - a)/2 * integral(f((b-a)/2*x + (a+b)/2), x=-1, x=1)
  1996. We can approximate the latter integral with the values returned
  1997. by `roots_legendre`.
  1998. Map the roots computed above from [-1, 1] to [a, b].
  1999. >>> t = (b - a)/2 * roots + (a + b)/2
  2000. Approximate the integral as the weighted sum of the function values.
  2001. >>> (b - a)/2 * f(t).dot(weights)
  2002. 2.1931471805599276
  2003. Compare that to the exact result, which is 3/2 + log(2):
  2004. >>> 1.5 + np.log(2)
  2005. 2.1931471805599454
  2006. """
  2007. m = int(n)
  2008. if n < 1 or n != m:
  2009. raise ValueError("n must be a positive integer.")
  2010. mu0 = 2.0
  2011. def an_func(k):
  2012. return 0.0 * k
  2013. def bn_func(k):
  2014. return k * np.sqrt(1.0 / (4 * k * k - 1))
  2015. f = _ufuncs.eval_legendre
  2016. def df(n, x):
  2017. return (-n * x * _ufuncs.eval_legendre(n, x)
  2018. + n * _ufuncs.eval_legendre(n - 1, x)) / (1 - x ** 2)
  2019. return _gen_roots_and_weights(m, mu0, an_func, bn_func, f, df, True, mu)
  2020. def legendre(n, monic=False):
  2021. r"""Legendre polynomial.
  2022. Defined to be the solution of
  2023. .. math::
  2024. \frac{d}{dx}\left[(1 - x^2)\frac{d}{dx}P_n(x)\right]
  2025. + n(n + 1)P_n(x) = 0;
  2026. :math:`P_n(x)` is a polynomial of degree :math:`n`.
  2027. Parameters
  2028. ----------
  2029. n : int
  2030. Degree of the polynomial.
  2031. monic : bool, optional
  2032. If `True`, scale the leading coefficient to be 1. Default is
  2033. `False`.
  2034. Returns
  2035. -------
  2036. P : orthopoly1d
  2037. Legendre polynomial.
  2038. Notes
  2039. -----
  2040. The polynomials :math:`P_n` are orthogonal over :math:`[-1, 1]`
  2041. with weight function 1.
  2042. Examples
  2043. --------
  2044. Generate the 3rd-order Legendre polynomial 1/2*(5x^3 + 0x^2 - 3x + 0):
  2045. >>> from scipy.special import legendre
  2046. >>> legendre(3)
  2047. poly1d([ 2.5, 0. , -1.5, 0. ])
  2048. """
  2049. if n < 0:
  2050. raise ValueError("n must be nonnegative.")
  2051. if n == 0:
  2052. n1 = n + 1
  2053. else:
  2054. n1 = n
  2055. x, w = roots_legendre(n1)
  2056. if n == 0:
  2057. x, w = [], []
  2058. hn = 2.0 / (2 * n + 1)
  2059. kn = _gam(2 * n + 1) / _gam(n + 1)**2 / 2.0**n
  2060. p = orthopoly1d(x, w, hn, kn, wfunc=lambda x: 1.0, limits=(-1, 1),
  2061. monic=monic,
  2062. eval_func=lambda x: _ufuncs.eval_legendre(n, x))
  2063. return p
  2064. # Shifted Legendre P^*_n(x)
  2065. def roots_sh_legendre(n, mu=False):
  2066. r"""Gauss-Legendre (shifted) quadrature.
  2067. Compute the sample points and weights for Gauss-Legendre
  2068. quadrature. The sample points are the roots of the nth degree
  2069. shifted Legendre polynomial :math:`P^*_n(x)`. These sample points
  2070. and weights correctly integrate polynomials of degree :math:`2n -
  2071. 1` or less over the interval :math:`[0, 1]` with weight function
  2072. :math:`w(x) = 1.0`. See 2.2.11 in [AS]_ for details.
  2073. Parameters
  2074. ----------
  2075. n : int
  2076. quadrature order
  2077. mu : bool, optional
  2078. If True, return the sum of the weights, optional.
  2079. Returns
  2080. -------
  2081. x : ndarray
  2082. Sample points
  2083. w : ndarray
  2084. Weights
  2085. mu : float
  2086. Sum of the weights
  2087. See Also
  2088. --------
  2089. scipy.integrate.fixed_quad
  2090. References
  2091. ----------
  2092. .. [AS] Milton Abramowitz and Irene A. Stegun, eds.
  2093. Handbook of Mathematical Functions with Formulas,
  2094. Graphs, and Mathematical Tables. New York: Dover, 1972.
  2095. """
  2096. x, w = roots_legendre(n)
  2097. x = (x + 1) / 2
  2098. w /= 2
  2099. if mu:
  2100. return x, w, 1.0
  2101. else:
  2102. return x, w
  2103. def sh_legendre(n, monic=False):
  2104. r"""Shifted Legendre polynomial.
  2105. Defined as :math:`P^*_n(x) = P_n(2x - 1)` for :math:`P_n` the nth
  2106. Legendre polynomial.
  2107. Parameters
  2108. ----------
  2109. n : int
  2110. Degree of the polynomial.
  2111. monic : bool, optional
  2112. If `True`, scale the leading coefficient to be 1. Default is
  2113. `False`.
  2114. Returns
  2115. -------
  2116. P : orthopoly1d
  2117. Shifted Legendre polynomial.
  2118. Notes
  2119. -----
  2120. The polynomials :math:`P^*_n` are orthogonal over :math:`[0, 1]`
  2121. with weight function 1.
  2122. """
  2123. if n < 0:
  2124. raise ValueError("n must be nonnegative.")
  2125. def wfunc(x):
  2126. return 0.0 * x + 1.0
  2127. if n == 0:
  2128. return orthopoly1d([], [], 1.0, 1.0, wfunc, (0, 1), monic,
  2129. lambda x: _ufuncs.eval_sh_legendre(n, x))
  2130. x, w = roots_sh_legendre(n)
  2131. hn = 1.0 / (2 * n + 1.0)
  2132. kn = _gam(2 * n + 1) / _gam(n + 1)**2
  2133. p = orthopoly1d(x, w, hn, kn, wfunc, limits=(0, 1), monic=monic,
  2134. eval_func=lambda x: _ufuncs.eval_sh_legendre(n, x))
  2135. return p
  2136. # Make the old root function names an alias for the new ones
  2137. _modattrs = globals()
  2138. for newfun, oldfun in _rootfuns_map.items():
  2139. _modattrs[oldfun] = _modattrs[newfun]
  2140. __all__.append(oldfun)