Path: blob/master/src/sage/functions/orthogonal_polys.py
8815 views
r"""1Orthogonal Polynomials23This module wraps some of the orthogonal/special functions in the4Maxima package "orthopoly". This package was written by Barton5Willis of the University of Nebraska at Kearney. It is released6under the terms of the General Public License (GPL). Send7Maxima-related bug reports and comments on this module to8[email protected]. In your report, please include Maxima and specfun9version information.101112- The Chebyshev polynomial of the first kind arises as a solution13to the differential equation1415.. math::1617(1-x^2)\,y'' - x\,y' + n^2\,y = 0181920and those of the second kind as a solution to2122.. math::2324(1-x^2)\,y'' - 3x\,y' + n(n+2)\,y = 0.252627The Chebyshev polynomials of the first kind are defined by the28recurrence relation2930.. math::3132T_0(x) = 1 \, T_1(x) = x \, T_{n+1}(x) = 2xT_n(x) - T_{n-1}(x). \,333435The Chebyshev polynomials of the second kind are defined by the36recurrence relation3738.. math::3940U_0(x) = 1 \, U_1(x) = 2x \, U_{n+1}(x) = 2xU_n(x) - U_{n-1}(x). \,41424344For integers `m,n`, they satisfy the orthogonality45relations4647.. math::4849\int_{-1}^1 T_n(x)T_m(x)\,\frac{dx}{\sqrt{1-x^2}} =\left\{ \begin{matrix} 0 &: n\ne m~~~~~\\ \pi &: n=m=0\\ \pi/2 &: n=m\ne 0 \end{matrix} \right.505152and535455.. math::5657\int_{-1}^1 U_n(x)U_m(x)\sqrt{1-x^2}\,dx =\frac{\pi}{2}\delta_{m,n}.58596061They are named after Pafnuty Chebyshev (alternative62transliterations: Tchebyshef or Tschebyscheff).6364- The Hermite polynomials are defined either by6566.. math::6768H_n(x)=(-1)^n e^{x^2/2}\frac{d^n}{dx^n}e^{-x^2/2}697071(the "probabilists' Hermite polynomials"), or by727374.. math::7576H_n(x)=(-1)^n e^{x^2}\frac{d^n}{dx^n}e^{-x^2}777879(the "physicists' Hermite polynomials"). Sage (via Maxima)80implements the latter flavor. These satisfy the orthogonality81relation8283.. math::8485\int_{-\infty}^\infty H_n(x)H_m(x)\,e^{-x^2}\,dx ={n!2^n}{\sqrt{\pi}}\delta_{nm}86878889They are named in honor of Charles Hermite.9091- Each *Legendre polynomial* `P_n(x)` is an `n`-th degree polynomial.92It may be expressed using Rodrigues' formula:9394.. math::9596P_n(x) = (2^n n!)^{-1} {\frac{d^n}{dx^n} } \left[ (x^2 -1)^n \right].9798These are solutions to Legendre's differential equation:99100.. math::101102{\frac{d}{dx}} \left[ (1-x^2) {\frac{d}{dx}} P(x) \right] + n(n+1)P(x) = 0.103104and satisfy the orthogonality relation105106.. math::107108\int_{-1}^{1} P_m(x) P_n(x)\,dx = {\frac{2}{2n + 1}} \delta_{mn}109110The *Legendre function of the second kind* `Q_n(x)` is another111(linearly independent) solution to the Legendre differential equation.112It is not an "orthogonal polynomial" however.113114The associated Legendre functions of the first kind115`P_\ell^m(x)` can be given in terms of the "usual"116Legendre polynomials by117118.. math::119120\begin{array}{ll} P_\ell^m(x) &= (-1)^m(1-x^2)^{m/2}\frac{d^m}{dx^m}P_\ell(x) \\ &= \frac{(-1)^m}{2^\ell \ell!} (1-x^2)^{m/2}\frac{d^{\ell+m}}{dx^{\ell+m}}(x^2-1)^\ell. \end{array}121122123Assuming `0 \le m \le \ell`, they satisfy the orthogonality124relation:125126.. math::127128\int_{-1}^{1} P_k ^{(m)} P_\ell ^{(m)} dx = \frac{2 (\ell+m)!}{(2\ell+1)(\ell-m)!}\ \delta _{k,\ell},129130131where `\delta _{k,\ell}` is the Kronecker delta.132133The associated Legendre functions of the second kind134`Q_\ell^m(x)` can be given in terms of the "usual"135Legendre polynomials by136137138.. math::139140Q_\ell^m(x) = (-1)^m(1-x^2)^{m/2}\frac{d^m}{dx^m}Q_\ell(x).141142143144They are named after Adrien-Marie Legendre.145146- Laguerre polynomials may be defined by the Rodrigues formula147148.. math::149150L_n(x)=\frac{e^x}{n!}\frac{d^n}{dx^n}\left(e^{-x} x^n\right).151152153They are solutions of Laguerre's equation:154155156.. math::157158x\,y'' + (1 - x)\,y' + n\,y = 0\,159160and satisfy the orthogonality relation161162163.. math::164165\int_0^\infty L_m(x) L_n(x) e^{-x}\,dx = \delta_{mn}.166167168169The generalized Laguerre polynomials may be defined by the170Rodrigues formula:171172173.. math::174175L_n^{(\alpha)}(x) = {\frac{x^{-\alpha} e^x}{n!}}{\frac{d^n}{dx^n}} \left(e^{-x} x^{n+\alpha}\right) .176177178(These are also sometimes called the associated Laguerre179polynomials.) The simple Laguerre polynomials are recovered from180the generalized polynomials by setting `\alpha =0`.181182They are named after Edmond Laguerre.183184- Jacobi polynomials are a class of orthogonal polynomials. They185are obtained from hypergeometric series in cases where the series186is in fact finite:187188.. math::189190P_n^{(\alpha,\beta)}(z) =\frac{(\alpha+1)_n}{n!} \,_2F_1\left(-n,1+\alpha+\beta+n;\alpha+1;\frac{1-z}{2}\right) ,191192193where `()_n` is Pochhammer's symbol (for the rising194factorial), (Abramowitz and Stegun p561.) and thus have the195explicit expression196197198.. math::199200P_n^{(\alpha,\beta)} (z) = \frac{\Gamma (\alpha+n+1)}{n!\Gamma (\alpha+\beta+n+1)} \sum_{m=0}^n {n\choose m} \frac{\Gamma (\alpha + \beta + n + m + 1)}{\Gamma (\alpha + m + 1)} \left(\frac{z-1}{2}\right)^m .201202203204They are named after Carl Jacobi.205206- Ultraspherical or Gegenbauer polynomials are given in terms of207the Jacobi polynomials `P_n^{(\alpha,\beta)}(x)` with208`\alpha=\beta=a-1/2` by209210211.. math::212213C_n^{(a)}(x)= \frac{\Gamma(a+1/2)}{\Gamma(2a)}\frac{\Gamma(n+2a)}{\Gamma(n+a+1/2)} P_n^{(a-1/2,a-1/2)}(x).214215216They satisfy the orthogonality relation217218.. math::219220\int_{-1}^1(1-x^2)^{a-1/2}C_m^{(a)}(x)C_n^{(a)}(x)\, dx =\delta_{mn}2^{1-2a}\pi \frac{\Gamma(n+2a)}{(n+a)\Gamma^2(a)\Gamma(n+1)} ,221222223for `a>-1/2`. They are obtained from hypergeometric series224in cases where the series is in fact finite:225226227.. math::228229C_n^{(a)}(z) =\frac{(2a)^{\underline{n}}}{n!} \,_2F_1\left(-n,2a+n;a+\frac{1}{2};\frac{1-z}{2}\right)230231232where `\underline{n}` is the falling factorial. (See233Abramowitz and Stegun p561)234235They are named for Leopold Gegenbauer (1849-1903).236237238For completeness, the Pochhammer symbol, introduced by Leo August239Pochhammer, `(x)_n`, is used in the theory of special240functions to represent the "rising factorial" or "upper factorial"241242.. math::243244(x)_n=x(x+1)(x+2)\cdots(x+n-1)=\frac{(x+n-1)!}{(x-1)!}.245246247On the other hand, the "falling factorial" or "lower factorial" is248249.. math::250251x^{\underline{n}}=\frac{x!}{(x-n)!} ,252253254in the notation of Ronald L. Graham, Donald E. Knuth and Oren255Patashnik in their book Concrete Mathematics.256257.. note::258259The first call of any of these will usually cost a bit extra260(it loads "specfun", but I'm not sure if that is the real reason).261The next call is usually faster but not always.262263.. TODO::264265Implement associated Legendre polynomials and Zernike266polynomials. (Neither is in Maxima.)267:wikipedia:`Associated_Legendre_polynomials`268:wikipedia:`Zernike_polynomials`269270REFERENCES:271272.. [ASHandbook] Abramowitz and Stegun: Handbook of Mathematical Functions,273http://www.math.sfu.ca/ cbm/aands/274275.. :wikipedia:`Chebyshev_polynomials`276277.. :wikipedia:`Legendre_polynomials`278279.. :wikipedia:`Hermite_polynomials`280281.. http://mathworld.wolfram.com/GegenbauerPolynomial.html282283.. :wikipedia:`Jacobi_polynomials`284285.. :wikipedia:`Laguerre_polynomia`286287.. :wikipedia:`Associated_Legendre_polynomials`288289.. [EffCheby] Wolfram Koepf: Effcient Computation of Chebyshev Polynomials290in Computer Algebra291Computer Algebra Systems: A Practical Guide.292John Wiley, Chichester (1999): 79-99.293294AUTHORS:295296- David Joyner (2006-06)297- Stefan Reiterer (2010-)298"""299300#*****************************************************************************301# Copyright (C) 2006 William Stein <[email protected]>302# 2006 David Joyner <[email protected]>303# 2010 Stefan Reiterer <[email protected]>304#305# Distributed under the terms of the GNU General Public License (GPL)306#307# This code is distributed in the hope that it will be useful,308# but WITHOUT ANY WARRANTY; without even the implied warranty of309# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU310# General Public License for more details.311#312# The full text of the GPL is available at:313#314# http://www.gnu.org/licenses/315#*****************************************************************************316317import warnings318319from sage.misc.sage_eval import sage_eval320from sage.rings.all import ZZ, RR, CC321from sage.rings.real_mpfr import is_RealField322from sage.rings.complex_field import is_ComplexField323from sage.calculus.calculus import maxima324325326from sage.symbolic.function import BuiltinFunction327from sage.symbolic.expression import is_Expression328from sage.functions.other import factorial, binomial329from sage.structure.coerce import parent330331_done = False332def _init():333"""334Internal function which checks if Maxima has loaded the335"orthopoly" package. All functions using this in this336file should call this function first.337338TEST:339340The global starts ``False``::341342sage: sage.functions.orthogonal_polys._done343False344345Then after using one of these functions, it changes::346347sage: from sage.functions.orthogonal_polys import legendre_P348sage: legendre_P(2,x)3493/2*(x - 1)^2 + 3*x - 2350sage: sage.functions.orthogonal_polys._done351True352353354Note that because here we use a Pynac variable ``x``,355the representation of the function is different from356its actual doctest, where a polynomial indeterminate357``x`` is used.358"""359global _done360if _done:361return362maxima.eval('load("orthopoly");')363# TODO -- make it possible to use the intervals returned364# instead of just discarding this info!365maxima.eval('orthopoly_returns_intervals:false;')366_done = True367368369class OrthogonalPolynomial(BuiltinFunction):370"""371Base class for orthogonal polynomials.372373This class is an abstract base class for all orthogonal polynomials since374they share similar properties. The evaluation as a polynomial375is either done via maxima, or with pynac.376377Convention: The first argument is always the order of the polynomial,378the others are other values or parameters where the polynomial is379evaluated.380"""381def __init__(self, name, nargs=2, latex_name=None, conversions={}):382"""383:class:`OrthogonalPolynomial` class needs the same input parameter as384it's parent class.385386EXAMPLES::387388sage: from sage.functions.orthogonal_polys import OrthogonalPolynomial389sage: new = OrthogonalPolynomial('testo_P')390sage: new391testo_P392"""393try:394self._maxima_name = conversions['maxima']395except KeyError:396self._maxima_name = None397398super(OrthogonalPolynomial,self).__init__(name=name, nargs=nargs,399latex_name=latex_name, conversions=conversions)400401def _maxima_init_evaled_(self, *args):402r"""403Return a string which represents this function evaluated at404``n, x`` in Maxima.405406EXAMPLES::407408sage: from sage.functions.orthogonal_polys import OrthogonalPolynomial409sage: P = OrthogonalPolynomial('testo_P')410sage: P._maxima_init_evaled_(2, 5) is None411True412"""413return None414415def eval_formula(self, *args):416"""417Evaluate this polynomial using an explicit formula.418419EXAMPLES::420421sage: from sage.functions.orthogonal_polys import OrthogonalPolynomial422sage: P = OrthogonalPolynomial('testo_P')423sage: P.eval_formula(1,2.0)424Traceback (most recent call last):425...426NotImplementedError: no explicit calculation of values implemented427"""428raise NotImplementedError("no explicit calculation of values implemented")429430def _eval_special_values_(self, *args):431"""432Evaluate the polynomial explicitly for special values.433434EXAMPLES::435436sage: var('n')437n438sage: chebyshev_T(n,-1)439(-1)^n440"""441raise ValueError("no special values known")442443def _eval_(self, n, *args):444"""445The :meth:`_eval_()` method decides which evaluation suits best446for the given input, and returns a proper value.447448EXAMPLES::449450sage: var('n,x')451(n, x)452sage: chebyshev_T(5,x)45316*x^5 - 20*x^3 + 5*x454"""455return None456457def __call__(self, n, *args, **kwds):458"""459This overides the call method from SageObject to avoid problems with coercions,460since the _eval_ method is able to handle more data types than symbolic functions461would normally allow.462Thus we have the distinction between algebraic objects (if n is an integer),463and else as symbolic function.464465EXAMPLES::466467sage: K.<a> = NumberField(x^3-x-1)468sage: chebyshev_T(5, a)46916*a^2 + a - 4470"""471return super(OrthogonalPolynomial,self).__call__(n, *args, **kwds)472473class ChebyshevPolynomial(OrthogonalPolynomial):474"""475Abstract base class for Chebyshev polynomials of the first and second kind.476477EXAMPLES::478479sage: chebyshev_T(3,x)4804*x^3 - 3*x481"""482def __call__(self, n, *args, **kwds):483"""484This overides the call method from SageObject to avoid problems with coercions,485since the _eval_ method is able to handle more data types than symbolic functions486would normally allow.487Thus we have the distinction between algebraic objects (if n is an integer),488and else as symbolic function.489490EXAMPLES::491492sage: K.<a> = NumberField(x^3-x-1)493sage: chebyshev_T(5, a)49416*a^2 + a - 4495sage: chebyshev_T(5,MatrixSpace(ZZ, 2)([1, 2, -4, 7]))496[-40799 44162]497[-88324 91687]498sage: R.<x> = QQ[]499sage: parent(chebyshev_T(5, x))500Univariate Polynomial Ring in x over Rational Field501sage: chebyshev_T(5, 2, hold=True)502chebyshev_T(5, 2)503sage: chebyshev_T(1,2,3)504Traceback (most recent call last):505...506TypeError: Symbolic function chebyshev_T takes exactly 2 arguments (3 given)507"""508# If n is an integer: consider the polynomial as an algebraic (not symbolic) object509if n in ZZ and not kwds.get('hold', False):510try:511return self._eval_(n, *args)512except Exception:513pass514515return super(ChebyshevPolynomial,self).__call__(n, *args, **kwds)516517def _eval_(self, n, x):518"""519The :meth:`_eval_()` method decides which evaluation suits best520for the given input, and returns a proper value.521522EXAMPLES::523524sage: var('n,x')525(n, x)526sage: chebyshev_T(5,x)52716*x^5 - 20*x^3 + 5*x528sage: chebyshev_T(64, x)5292*(2*(2*(2*(2*(2*x^2 - 1)^2 - 1)^2 - 1)^2 - 1)^2 - 1)^2 - 1530sage: chebyshev_T(n,-1)531(-1)^n532sage: chebyshev_T(-7,x)53364*x^7 - 112*x^5 + 56*x^3 - 7*x534sage: chebyshev_T(3/2,x)535chebyshev_T(3/2, x)536sage: R.<t> = QQ[]537sage: chebyshev_T(2,t)5382*t^2 - 1539sage: chebyshev_U(2,t)5404*t^2 - 1541sage: parent(chebyshev_T(4, RIF(5)))542Real Interval Field with 53 bits of precision543sage: RR2 = RealField(5)544sage: chebyshev_T(100000,RR2(2))5458.9e57180546sage: chebyshev_T(5,Qp(3)(2))5472 + 3^2 + 3^3 + 3^4 + 3^5 + O(3^20)548sage: chebyshev_T(100001/2, 2)549doctest:...: RuntimeWarning: mpmath failed, keeping expression unevaluated550chebyshev_T(100001/2, 2)551sage: chebyshev_U._eval_(1.5, Mod(8,9)) is None552True553"""554# n is an integer => evaluate algebraically (as polynomial)555if n in ZZ:556n = ZZ(n)557# Expanded symbolic expression only for small values of n558if is_Expression(x) and n.abs() < 32:559return self.eval_formula(n, x)560return self.eval_algebraic(n, x)561562if is_Expression(x) or is_Expression(n):563# Check for known identities564try:565return self._eval_special_values_(n, x)566except ValueError:567# Don't evaluate => keep symbolic568return None569570# n is not an integer and neither n nor x is symbolic.571# We assume n and x are real/complex and evaluate numerically572try:573import sage.libs.mpmath.all as mpmath574return self._evalf_(n, x)575except mpmath.NoConvergence:576warnings.warn("mpmath failed, keeping expression unevaluated",577RuntimeWarning)578return None579except Exception:580# Numerical evaluation failed => keep symbolic581return None582583584class Func_chebyshev_T(ChebyshevPolynomial):585"""586Chebyshev polynomials of the first kind.587588REFERENCE:589590- [ASHandbook]_ 22.5.31 page 778 and 6.1.22 page 256.591592EXAMPLES::593594sage: chebyshev_T(5,x)59516*x^5 - 20*x^3 + 5*x596sage: var('k')597k598sage: test = chebyshev_T(k,x)599sage: test600chebyshev_T(k, x)601"""602def __init__(self):603"""604Init method for the chebyshev polynomials of the first kind.605606EXAMPLES::607608sage: from sage.functions.orthogonal_polys import Func_chebyshev_T609sage: chebyshev_T2 = Func_chebyshev_T()610sage: chebyshev_T2(1,x)611x612"""613ChebyshevPolynomial.__init__(self, "chebyshev_T", nargs=2,614conversions=dict(maxima='chebyshev_t',615mathematica='ChebyshevT'))616617def _eval_special_values_(self, n, x):618"""619Values known for special values of x.620For details see [ASHandbook]_ 22.4 (p. 777)621622EXAMPLES:623624sage: var('n')625n626sage: chebyshev_T(n,1)6271628sage: chebyshev_T(n,0)6291/2*(-1)^(1/2*n)*((-1)^n + 1)630sage: chebyshev_T(n,-1)631(-1)^n632sage: chebyshev_T._eval_special_values_(3/2,x)633Traceback (most recent call last):634...635ValueError: no special value found636sage: chebyshev_T._eval_special_values_(n, 0.1)637Traceback (most recent call last):638...639ValueError: no special value found640"""641if x == 1:642return x643644if x == -1:645return x**n646647if x == 0:648return (1+(-1)**n)*(-1)**(n/2)/2649650raise ValueError("no special value found")651652def _evalf_(self, n, x, **kwds):653"""654Evaluates :class:`chebyshev_T` numerically with mpmath.655656EXAMPLES::657658sage: chebyshev_T._evalf_(10,3)6592.26195370000000e7660sage: chebyshev_T._evalf_(10,3,parent=RealField(75))6612.261953700000000000000e7662sage: chebyshev_T._evalf_(10,I)663-3363.00000000000664sage: chebyshev_T._evalf_(5,0.3)6650.998880000000000666sage: chebyshev_T(1/2, 0)6670.707106781186548668sage: chebyshev_T(1/2, 3/2)6691.11803398874989670sage: chebyshev_T._evalf_(1.5, Mod(8,9))671Traceback (most recent call last):672...673TypeError: cannot evaluate chebyshev_T with parent Ring of integers modulo 9674675This simply evaluates using :class:`RealField` or :class:`ComplexField`::676677sage: chebyshev_T(1234.5, RDF(2.1))6785.48174256255782e735679sage: chebyshev_T(1234.5, I)680-1.21629397684152e472 - 1.21629397684152e472*I681682For large values of ``n``, mpmath fails (but the algebraic formula683still works)::684685sage: chebyshev_T._evalf_(10^6, 0.1)686Traceback (most recent call last):687...688NoConvergence: Hypergeometric series converges too slowly. Try increasing maxterms.689sage: chebyshev_T(10^6, 0.1)6900.636384327171504691"""692try:693real_parent = kwds['parent']694except KeyError:695real_parent = parent(x)696697if not is_RealField(real_parent) and not is_ComplexField(real_parent):698# parent is not a real or complex field: figure out a good parent699if x in RR:700x = RR(x)701real_parent = RR702elif x in CC:703x = CC(x)704real_parent = CC705706if not is_RealField(real_parent) and not is_ComplexField(real_parent):707raise TypeError("cannot evaluate chebyshev_T with parent {}".format(real_parent))708709from sage.libs.mpmath.all import call as mpcall710from sage.libs.mpmath.all import chebyt as mpchebyt711712return mpcall(mpchebyt, n, x, parent=real_parent)713714def _maxima_init_evaled_(self, n, x):715"""716Evaluate the Chebyshev polynomial ``self`` with maxima.717718EXAMPLES::719720sage: var('n, x')721(n, x)722sage: chebyshev_T._maxima_init_evaled_(1,x)723'x'724sage: maxima(chebyshev_T(n, chebyshev_T(n, x)))725chebyshev_t(n,chebyshev_t(n,x))726"""727return maxima.eval('chebyshev_t({0},{1})'.format(n._maxima_init_(), x._maxima_init_()))728729def eval_formula(self, n, x):730"""731Evaluate ``chebyshev_T`` using an explicit formula.732See [ASHandbook]_ 227 (p. 782) for details for the recurions.733See also [EffCheby]_ for fast evaluation techniques.734735INPUT:736737- ``n`` -- an integer738739- ``x`` -- a value to evaluate the polynomial at (this can be740any ring element)741742EXAMPLES::743744sage: chebyshev_T.eval_formula(-1,x)745x746sage: chebyshev_T.eval_formula(0,x)7471748sage: chebyshev_T.eval_formula(1,x)749x750sage: chebyshev_T.eval_formula(2,0.1) == chebyshev_T._evalf_(2,0.1)751True752sage: chebyshev_T.eval_formula(10,x)753512*x^10 - 1280*x^8 + 1120*x^6 - 400*x^4 + 50*x^2 - 1754sage: chebyshev_T.eval_algebraic(10,x).expand()755512*x^10 - 1280*x^8 + 1120*x^6 - 400*x^4 + 50*x^2 - 1756"""757if n < 0:758return self.eval_formula(-n, x)759elif n == 0:760return parent(x).one()761762res = parent(x).zero()763for j in xrange(0, n//2+1):764f = factorial(n-1-j) / factorial(j) / factorial(n-2*j)765res += (-1)**j * (2*x)**(n-2*j) * f766res *= n/2767return res768769def eval_algebraic(self, n, x):770"""771Evaluate :class:`chebyshev_T` as polynomial, using a recursive772formula.773774INPUT:775776- ``n`` -- an integer777778- ``x`` -- a value to evaluate the polynomial at (this can be779any ring element)780781EXAMPLES::782783sage: chebyshev_T.eval_algebraic(5, x)7842*(2*(2*x^2 - 1)*x - x)*(2*x^2 - 1) - x785sage: chebyshev_T(-7, x) - chebyshev_T(7,x)7860787sage: R.<t> = ZZ[]788sage: chebyshev_T.eval_algebraic(-1, t)789t790sage: chebyshev_T.eval_algebraic(0, t)7911792sage: chebyshev_T.eval_algebraic(1, t)793t794sage: chebyshev_T(7^100, 1/2)7951/2796sage: chebyshev_T(7^100, Mod(2,3))7972798sage: n = 97; x = RIF(pi/2/n)799sage: chebyshev_T(n, cos(x)).contains_zero()800True801sage: R.<t> = Zp(2, 8, 'capped-abs')[]802sage: chebyshev_T(10^6+1, t)803(2^7 + O(2^8))*t^5 + (O(2^8))*t^4 + (2^6 + O(2^8))*t^3 + (O(2^8))*t^2 + (1 + 2^6 + O(2^8))*t + (O(2^8))804"""805if n == 0:806return parent(x).one()807if n < 0:808return self._eval_recursive_(-n, x)[0]809return self._eval_recursive_(n, x)[0]810811def _eval_recursive_(self, n, x, both=False):812"""813If ``both=True``, compute ``(T(n,x), T(n-1,x))`` using a814recursive formula.815If ``both=False``, return instead a tuple ``(T(n,x), False)``.816817EXAMPLES::818819sage: chebyshev_T._eval_recursive_(5, x)820(2*(2*(2*x^2 - 1)*x - x)*(2*x^2 - 1) - x, False)821sage: chebyshev_T._eval_recursive_(5, x, True)822(2*(2*(2*x^2 - 1)*x - x)*(2*x^2 - 1) - x, 2*(2*x^2 - 1)^2 - 1)823"""824if n == 1:825return x, parent(x).one()826827assert n >= 2828a, b = self._eval_recursive_((n+1)//2, x, both or n % 2)829if n % 2 == 0:830return 2*a*a - 1, both and 2*a*b - x831else:832return 2*a*b - x, both and 2*b*b - 1833834835def _eval_numpy_(self, n, x):836"""837Evaluate ``self`` using numpy.838839EXAMPLES::840841sage: import numpy842sage: z = numpy.array([1,2])843sage: z2 = numpy.array([[1,2],[1,2]])844sage: z3 = numpy.array([1,2,3.])845sage: chebyshev_T(1,z)846array([ 1., 2.])847sage: chebyshev_T(1,z2)848array([[ 1., 2.],849[ 1., 2.]])850sage: chebyshev_T(1,z3)851array([ 1., 2., 3.])852sage: chebyshev_T(z,0.1)853array([ 0.1 , -0.98])854"""855from scipy.special import eval_chebyt856return eval_chebyt(n, x)857858def _derivative_(self, n, x, diff_param):859"""860Return the derivative of :class:`chebyshev_T` in form of the Chebyshev861polynomial of the second kind :class:`chebyshev_U`.862863EXAMPLES::864865sage: var('k')866k867sage: derivative(chebyshev_T(k,x),x)868k*chebyshev_U(k - 1, x)869sage: derivative(chebyshev_T(3,x),x)87012*x^2 - 3871sage: derivative(chebyshev_T(k,x),k)872Traceback (most recent call last):873...874NotImplementedError: derivative w.r.t. to the index is not supported yet875"""876if diff_param == 0:877raise NotImplementedError("derivative w.r.t. to the index is not supported yet")878elif diff_param == 1:879return n*chebyshev_U(n-1, x)880raise ValueError("illegal differentiation parameter {}".format(diff_param))881882chebyshev_T = Func_chebyshev_T()883884class Func_chebyshev_U(ChebyshevPolynomial):885"""886Class for the Chebyshev polynomial of the second kind.887888REFERENCE:889890- [ASHandbook]_ 22.8.3 page 783 and 6.1.22 page 256.891892EXAMPLES::893894sage: R.<t> = QQ[]895sage: chebyshev_U(2,t)8964*t^2 - 1897sage: chebyshev_U(3,t)8988*t^3 - 4*t899"""900def __init__(self):901"""902Init method for the chebyshev polynomials of the second kind.903904EXAMPLES::905906sage: from sage.functions.orthogonal_polys import Func_chebyshev_U907sage: chebyshev_U2 = Func_chebyshev_U()908sage: chebyshev_U2(1,x)9092*x910"""911ChebyshevPolynomial.__init__(self, "chebyshev_U", nargs=2,912conversions=dict(maxima='chebyshev_u',913mathematica='ChebyshevU'))914915def eval_formula(self, n, x):916"""917Evaluate ``chebyshev_U`` using an explicit formula.918See [ASHandbook]_ 227 (p. 782) for details on the recurions.919See also [EffCheby]_ for the recursion formulas.920921INPUT:922923- ``n`` -- an integer924925- ``x`` -- a value to evaluate the polynomial at (this can be926any ring element)927928EXAMPLES::929930sage: chebyshev_U.eval_formula(10, x)9311024*x^10 - 2304*x^8 + 1792*x^6 - 560*x^4 + 60*x^2 - 1932sage: chebyshev_U.eval_formula(-2, x)933-1934sage: chebyshev_U.eval_formula(-1, x)9350936sage: chebyshev_U.eval_formula(0, x)9371938sage: chebyshev_U.eval_formula(1, x)9392*x940sage: chebyshev_U.eval_formula(2,0.1) == chebyshev_U._evalf_(2,0.1)941True942"""943if n < -1:944return -self.eval_formula(-n-2, x)945946res = parent(x).zero()947for j in xrange(0, n//2+1):948f = binomial(n-j, j)949res += (-1)**j * (2*x)**(n-2*j) * f950return res951952def eval_algebraic(self, n, x):953"""954Evaluate :class:`chebyshev_U` as polynomial, using a recursive955formula.956957INPUT:958959- ``n`` -- an integer960961- ``x`` -- a value to evaluate the polynomial at (this can be962any ring element)963964EXAMPLES::965966sage: chebyshev_U.eval_algebraic(5,x)967-2*((2*x + 1)*(2*x - 1)*x - 4*(2*x^2 - 1)*x)*(2*x + 1)*(2*x - 1)968sage: parent(chebyshev_U(3, Mod(8,9)))969Ring of integers modulo 9970sage: parent(chebyshev_U(3, Mod(1,9)))971Ring of integers modulo 9972sage: chebyshev_U(-3,x) + chebyshev_U(1,x)9730974sage: chebyshev_U(-1,Mod(5,8))9750976sage: parent(chebyshev_U(-1,Mod(5,8)))977Ring of integers modulo 8978sage: R.<t> = ZZ[]979sage: chebyshev_U.eval_algebraic(-2, t)980-1981sage: chebyshev_U.eval_algebraic(-1, t)9820983sage: chebyshev_U.eval_algebraic(0, t)9841985sage: chebyshev_U.eval_algebraic(1, t)9862*t987sage: n = 97; x = RIF(pi/n)988sage: chebyshev_U(n-1, cos(x)).contains_zero()989True990sage: R.<t> = Zp(2, 6, 'capped-abs')[]991sage: chebyshev_U(10^6+1, t)992(2 + O(2^6))*t + (O(2^6))993"""994if n == -1:995return parent(x).zero()996if n < 0:997return -self._eval_recursive_(-n-2, x)[0]998return self._eval_recursive_(n, x)[0]9991000def _eval_recursive_(self, n, x, both=False):1001"""1002If ``both=True``, compute ``(U(n,x), U(n-1,x))`` using a1003recursive formula.1004If ``both=False``, return instead a tuple ``(U(n,x), False)``.10051006EXAMPLES::10071008sage: chebyshev_U._eval_recursive_(3, x)1009(4*((2*x + 1)*(2*x - 1) - 2*x^2)*x, False)1010sage: chebyshev_U._eval_recursive_(3, x, True)1011(4*((2*x + 1)*(2*x - 1) - 2*x^2)*x, ((2*x + 1)*(2*x - 1) + 2*x)*((2*x + 1)*(2*x - 1) - 2*x))1012"""1013if n == 0:1014return parent(x).one(), 2*x10151016assert n >= 11017a, b = self._eval_recursive_((n-1)//2, x, True)1018if n % 2 == 0:1019return (b+a)*(b-a), both and 2*b*(x*b-a)1020else:1021return 2*a*(b-x*a), both and (b+a)*(b-a)10221023def _maxima_init_evaled_(self, n, x):1024"""1025Uses maxima to evaluate ``self``.10261027EXAMPLES::10281029sage: var('n, x')1030(n, x)1031sage: maxima(chebyshev_U(5,x))103232*x^5-32*x^3+6*x1033sage: maxima(chebyshev_U(n,x))1034chebyshev_u(n,x)1035sage: maxima(chebyshev_U(2,x))10364*x^2-11037"""1038return maxima.eval('chebyshev_u({0},{1})'.format(n._maxima_init_(), x._maxima_init_()))10391040def _evalf_(self, n, x, **kwds):1041"""1042Evaluate :class:`chebyshev_U` numerically with mpmath.10431044EXAMPLES::10451046sage: chebyshev_U(5,-4+3.*I)104798280.0000000000 - 11310.0000000000*I1048sage: chebyshev_U(10,3).n(75)10494.661117900000000000000e71050sage: chebyshev_U._evalf_(1.5, Mod(8,9))1051Traceback (most recent call last):1052...1053TypeError: cannot evaluate chebyshev_U with parent Ring of integers modulo 91054"""1055try:1056real_parent = kwds['parent']1057except KeyError:1058real_parent = parent(x)10591060if not is_RealField(real_parent) and not is_ComplexField(real_parent):1061# parent is not a real or complex field: figure out a good parent1062if x in RR:1063x = RR(x)1064real_parent = RR1065elif x in CC:1066x = CC(x)1067real_parent = CC10681069if not is_RealField(real_parent) and not is_ComplexField(real_parent):1070raise TypeError("cannot evaluate chebyshev_U with parent {}".format(real_parent))10711072from sage.libs.mpmath.all import call as mpcall1073from sage.libs.mpmath.all import chebyu as mpchebyu10741075return mpcall(mpchebyu, n, x, parent=real_parent)10761077def _eval_special_values_(self, n, x):1078"""1079Values known for special values of x.1080See [ASHandbook]_ 22.4 (p.777).10811082EXAMPLES::10831084sage: var('n')1085n1086sage: chebyshev_U(n,1)1087n + 11088sage: chebyshev_U(n,0)10891/2*(-1)^(1/2*n)*((-1)^n + 1)1090sage: chebyshev_U(n,-1)1091(-1)^n*(n + 1)1092sage: chebyshev_U._eval_special_values_(n, 2)1093Traceback (most recent call last):1094...1095ValueError: no special value found1096"""1097if x == 1:1098return x*(n+1)10991100if x == -1:1101return x**n*(n+1)11021103if x == 0:1104return (1+(-1)**n)*(-1)**(n/2)/211051106raise ValueError("no special value found")11071108def _eval_numpy_(self, n, x):1109"""1110Evaluate ``self`` using numpy.11111112EXAMPLES::11131114sage: import numpy1115sage: z = numpy.array([1,2])1116sage: z2 = numpy.array([[1,2],[1,2]])1117sage: z3 = numpy.array([1,2,3.])1118sage: chebyshev_U(1,z)1119array([ 2., 4.])1120sage: chebyshev_U(1,z2)1121array([[ 2., 4.],1122[ 2., 4.]])1123sage: chebyshev_U(1,z3)1124array([ 2., 4., 6.])1125sage: chebyshev_U(z,0.1)1126array([ 0.2 , -0.96])1127"""1128from scipy.special import eval_chebyu1129return eval_chebyu(n, x)11301131def _derivative_(self, n, x, diff_param):1132"""1133Return the derivative of :class:`chebyshev_U` in form of the Chebyshev1134polynomials of the first and second kind.11351136EXAMPLES::11371138sage: var('k')1139k1140sage: derivative(chebyshev_U(k,x),x)1141((k + 1)*chebyshev_T(k + 1, x) - x*chebyshev_U(k, x))/(x^2 - 1)1142sage: derivative(chebyshev_U(3,x),x)114324*x^2 - 41144sage: derivative(chebyshev_U(k,x),k)1145Traceback (most recent call last):1146...1147NotImplementedError: derivative w.r.t. to the index is not supported yet1148"""1149if diff_param == 0:1150raise NotImplementedError("derivative w.r.t. to the index is not supported yet")1151elif diff_param == 1:1152return ((n+1)*chebyshev_T(n+1, x) - x*chebyshev_U(n,x)) / (x*x-1)1153raise ValueError("illegal differentiation parameter {}".format(diff_param))11541155chebyshev_U = Func_chebyshev_U()115611571158def gen_laguerre(n,a,x):1159"""1160Returns the generalized Laguerre polynomial for integers `n > -1`.1161Typically, `a = 1/2` or `a = -1/2`.11621163REFERENCES:11641165- Table on page 789 in [ASHandbook]_.11661167EXAMPLES::11681169sage: x = PolynomialRing(QQ, 'x').gen()1170sage: gen_laguerre(2,1,x)11711/2*x^2 - 3*x + 31172sage: gen_laguerre(2,1/2,x)11731/2*x^2 - 5/2*x + 15/81174sage: gen_laguerre(2,-1/2,x)11751/2*x^2 - 3/2*x + 3/81176sage: gen_laguerre(2,0,x)11771/2*x^2 - 2*x + 11178sage: gen_laguerre(3,0,x)1179-1/6*x^3 + 3/2*x^2 - 3*x + 11180"""1181_init()1182return sage_eval(maxima.eval('gen_laguerre(%s,%s,x)'%(ZZ(n),a)), locals={'x':x})11831184def gen_legendre_P(n,m,x):1185r"""1186Returns the generalized (or associated) Legendre function of the1187first kind for integers `n > -1, m > -1`.11881189The awkward code for when m is odd and 1 results from the fact that1190Maxima is happy with, for example, `(1 - t^2)^3/2`, but1191Sage is not. For these cases the function is computed from the1192(m-1)-case using one of the recursions satisfied by the Legendre1193functions.11941195REFERENCE:11961197- Gradshteyn and Ryzhik 8.706 page 1000.11981199EXAMPLES::12001201sage: P.<t> = QQ[]1202sage: gen_legendre_P(2, 0, t)12033/2*t^2 - 1/21204sage: gen_legendre_P(2, 0, t) == legendre_P(2, t)1205True1206sage: gen_legendre_P(3, 1, t)1207-3/2*(5*t^2 - 1)*sqrt(-t^2 + 1)1208sage: gen_legendre_P(4, 3, t)1209105*(t^2 - 1)*sqrt(-t^2 + 1)*t1210sage: gen_legendre_P(7, 3, I).expand()1211-16695*sqrt(2)1212sage: gen_legendre_P(4, 1, 2.5)1213-583.562373654533*I1214"""1215from sage.functions.all import sqrt1216_init()1217if m.mod(2).is_zero() or m.is_one():1218return sage_eval(maxima.eval('assoc_legendre_p(%s,%s,x)'%(ZZ(n),ZZ(m))), locals={'x':x})1219else:1220return sqrt(1-x**2)*(((n-m+1)*x*gen_legendre_P(n,m-1,x)-(n+m-1)*gen_legendre_P(n-1,m-1,x))/(1-x**2))12211222def gen_legendre_Q(n,m,x):1223"""1224Returns the generalized (or associated) Legendre function of the1225second kind for integers `n>-1`, `m>-1`.12261227Maxima restricts m = n. Hence the cases m n are computed using the1228same recursion used for gen_legendre_P(n,m,x) when m is odd and12291.12301231EXAMPLES::12321233sage: P.<t> = QQ[]1234sage: gen_legendre_Q(2,0,t)12353/4*t^2*log(-(t + 1)/(t - 1)) - 3/2*t - 1/4*log(-(t + 1)/(t - 1))1236sage: gen_legendre_Q(2,0,t) - legendre_Q(2, t)123701238sage: gen_legendre_Q(3,1,0.5)12392.491852591708951240sage: gen_legendre_Q(0, 1, x)1241-1/sqrt(-x^2 + 1)1242sage: gen_legendre_Q(2, 4, x).factor()124348*x/((x + 1)^2*(x - 1)^2)1244"""1245from sage.functions.all import sqrt1246if m <= n:1247_init()1248return sage_eval(maxima.eval('assoc_legendre_q(%s,%s,x)'%(ZZ(n),ZZ(m))), locals={'x':x})1249if m == n + 1 or n == 0:1250if m.mod(2).is_zero():1251denom = (1 - x**2)**(m/2)1252else:1253denom = sqrt(1 - x**2)*(1 - x**2)**((m-1)/2)1254if m == n + 1:1255return (-1)**m*(m-1).factorial()*2**n/denom1256else:1257return (-1)**m*(m-1).factorial()*((x+1)**m - (x-1)**m)/(2*denom)1258else:1259return ((n-m+1)*x*gen_legendre_Q(n,m-1,x)-(n+m-1)*gen_legendre_Q(n-1,m-1,x))/sqrt(1-x**2)12601261def hermite(n,x):1262"""1263Returns the Hermite polynomial for integers `n > -1`.12641265REFERENCE:12661267- [ASHandbook]_ 22.5.40 and 22.5.41, page 779.12681269EXAMPLES::12701271sage: x = PolynomialRing(QQ, 'x').gen()1272sage: hermite(2,x)12734*x^2 - 21274sage: hermite(3,x)12758*x^3 - 12*x1276sage: hermite(3,2)1277401278sage: S.<y> = PolynomialRing(RR)1279sage: hermite(3,y)12808.00000000000000*y^3 - 12.0000000000000*y1281sage: R.<x,y> = QQ[]1282sage: hermite(3,y^2)12838*y^6 - 12*y^21284sage: w = var('w')1285sage: hermite(3,2*w)12868*(8*w^2 - 3)*w1287"""1288_init()1289return sage_eval(maxima.eval('hermite(%s,x)'%ZZ(n)), locals={'x':x})12901291def jacobi_P(n,a,b,x):1292r"""1293Returns the Jacobi polynomial `P_n^{(a,b)}(x)` for1294integers `n > -1` and a and b symbolic or `a > -1`1295and `b > -1`. The Jacobi polynomials are actually defined1296for all a and b. However, the Jacobi polynomial weight1297`(1-x)^a(1+x)^b` isn't integrable for `a \leq -1`1298or `b \leq -1`.12991300REFERENCE:13011302- Table on page 789 in [ASHandbook]_.13031304EXAMPLES::13051306sage: x = PolynomialRing(QQ, 'x').gen()1307sage: jacobi_P(2,0,0,x)13083/2*x^2 - 1/21309sage: jacobi_P(2,1,2,1.2) # random output of low order bits13105.0099999999999981311"""1312_init()1313return sage_eval(maxima.eval('jacobi_p(%s,%s,%s,x)'%(ZZ(n),a,b)), locals={'x':x})13141315def laguerre(n,x):1316"""1317Return the Laguerre polynomial for integers `n > -1`.13181319REFERENCE:13201321- [ASHandbook]_ 22.5.16, page 778 and page 789.13221323EXAMPLES::13241325sage: x = PolynomialRing(QQ, 'x').gen()1326sage: laguerre(2,x)13271/2*x^2 - 2*x + 11328sage: laguerre(3,x)1329-1/6*x^3 + 3/2*x^2 - 3*x + 11330sage: laguerre(2,2)1331-11332"""1333_init()1334return sage_eval(maxima.eval('laguerre(%s,x)'%ZZ(n)), locals={'x':x})13351336def legendre_P(n,x):1337"""1338Returns the Legendre polynomial of the first kind for integers1339`n > -1`.13401341REFERENCE:13421343- [ASHandbook]_ 22.5.35 page 779.13441345EXAMPLES::13461347sage: P.<t> = QQ[]1348sage: legendre_P(2,t)13493/2*t^2 - 1/21350sage: legendre_P(3, 1.1)13511.677500000000001352sage: legendre_P(3, 1 + I)13537/2*I - 13/21354sage: legendre_P(3, MatrixSpace(ZZ, 2)([1, 2, -4, 7]))1355[-179 242]1356[-484 547]1357sage: legendre_P(3, GF(11)(5))135881359"""1360_init()1361return sage_eval(maxima.eval('legendre_p(%s,x)'%ZZ(n)), locals={'x':x})13621363def legendre_Q(n,x):1364"""1365Returns the Legendre function of the second kind for integers1366`n > -1`.13671368Computed using Maxima.13691370EXAMPLES::13711372sage: P.<t> = QQ[]1373sage: legendre_Q(2, t)13743/4*t^2*log(-(t + 1)/(t - 1)) - 3/2*t - 1/4*log(-(t + 1)/(t - 1))1375sage: legendre_Q(3, 0.5)1376-0.1986547714794821377sage: legendre_Q(4, 2)1378443/16*I*pi + 443/16*log(3) - 365/121379sage: legendre_Q(4, 2.0)13800.00116107583162324 + 86.9828465962674*I1381"""1382_init()1383return sage_eval(maxima.eval('legendre_q(%s,x)'%ZZ(n)), locals={'x':x})13841385def ultraspherical(n,a,x):1386"""1387Returns the ultraspherical (or Gegenbauer) polynomial for integers1388`n > -1`.13891390Computed using Maxima.13911392REFERENCE:13931394- [ASHandbook]_ 22.5.2713951396EXAMPLES::13971398sage: x = PolynomialRing(QQ, 'x').gen()1399sage: ultraspherical(2,3/2,x)140015/2*x^2 - 3/21401sage: ultraspherical(2,1/2,x)14023/2*x^2 - 1/21403sage: ultraspherical(1,1,x)14042*x1405sage: t = PolynomialRing(RationalField(),"t").gen()1406sage: gegenbauer(3,2,t)140732*t^3 - 12*t1408"""1409_init()1410return sage_eval(maxima.eval('ultraspherical(%s,%s,x)'%(ZZ(n),a)), locals={'x':x})14111412gegenbauer = ultraspherical141314141415