Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/functions/orthogonal_polys.py
8815 views
1
r"""
2
Orthogonal Polynomials
3
4
This module wraps some of the orthogonal/special functions in the
5
Maxima package "orthopoly". This package was written by Barton
6
Willis of the University of Nebraska at Kearney. It is released
7
under the terms of the General Public License (GPL). Send
8
Maxima-related bug reports and comments on this module to
9
[email protected]. In your report, please include Maxima and specfun
10
version information.
11
12
13
- The Chebyshev polynomial of the first kind arises as a solution
14
to the differential equation
15
16
.. math::
17
18
(1-x^2)\,y'' - x\,y' + n^2\,y = 0
19
20
21
and those of the second kind as a solution to
22
23
.. math::
24
25
(1-x^2)\,y'' - 3x\,y' + n(n+2)\,y = 0.
26
27
28
The Chebyshev polynomials of the first kind are defined by the
29
recurrence relation
30
31
.. math::
32
33
T_0(x) = 1 \, T_1(x) = x \, T_{n+1}(x) = 2xT_n(x) - T_{n-1}(x). \,
34
35
36
The Chebyshev polynomials of the second kind are defined by the
37
recurrence relation
38
39
.. math::
40
41
U_0(x) = 1 \, U_1(x) = 2x \, U_{n+1}(x) = 2xU_n(x) - U_{n-1}(x). \,
42
43
44
45
For integers `m,n`, they satisfy the orthogonality
46
relations
47
48
.. math::
49
50
\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.
51
52
53
and
54
55
56
.. math::
57
58
\int_{-1}^1 U_n(x)U_m(x)\sqrt{1-x^2}\,dx =\frac{\pi}{2}\delta_{m,n}.
59
60
61
62
They are named after Pafnuty Chebyshev (alternative
63
transliterations: Tchebyshef or Tschebyscheff).
64
65
- The Hermite polynomials are defined either by
66
67
.. math::
68
69
H_n(x)=(-1)^n e^{x^2/2}\frac{d^n}{dx^n}e^{-x^2/2}
70
71
72
(the "probabilists' Hermite polynomials"), or by
73
74
75
.. math::
76
77
H_n(x)=(-1)^n e^{x^2}\frac{d^n}{dx^n}e^{-x^2}
78
79
80
(the "physicists' Hermite polynomials"). Sage (via Maxima)
81
implements the latter flavor. These satisfy the orthogonality
82
relation
83
84
.. math::
85
86
\int_{-\infty}^\infty H_n(x)H_m(x)\,e^{-x^2}\,dx ={n!2^n}{\sqrt{\pi}}\delta_{nm}
87
88
89
90
They are named in honor of Charles Hermite.
91
92
- Each *Legendre polynomial* `P_n(x)` is an `n`-th degree polynomial.
93
It may be expressed using Rodrigues' formula:
94
95
.. math::
96
97
P_n(x) = (2^n n!)^{-1} {\frac{d^n}{dx^n} } \left[ (x^2 -1)^n \right].
98
99
These are solutions to Legendre's differential equation:
100
101
.. math::
102
103
{\frac{d}{dx}} \left[ (1-x^2) {\frac{d}{dx}} P(x) \right] + n(n+1)P(x) = 0.
104
105
and satisfy the orthogonality relation
106
107
.. math::
108
109
\int_{-1}^{1} P_m(x) P_n(x)\,dx = {\frac{2}{2n + 1}} \delta_{mn}
110
111
The *Legendre function of the second kind* `Q_n(x)` is another
112
(linearly independent) solution to the Legendre differential equation.
113
It is not an "orthogonal polynomial" however.
114
115
The associated Legendre functions of the first kind
116
`P_\ell^m(x)` can be given in terms of the "usual"
117
Legendre polynomials by
118
119
.. math::
120
121
\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}
122
123
124
Assuming `0 \le m \le \ell`, they satisfy the orthogonality
125
relation:
126
127
.. math::
128
129
\int_{-1}^{1} P_k ^{(m)} P_\ell ^{(m)} dx = \frac{2 (\ell+m)!}{(2\ell+1)(\ell-m)!}\ \delta _{k,\ell},
130
131
132
where `\delta _{k,\ell}` is the Kronecker delta.
133
134
The associated Legendre functions of the second kind
135
`Q_\ell^m(x)` can be given in terms of the "usual"
136
Legendre polynomials by
137
138
139
.. math::
140
141
Q_\ell^m(x) = (-1)^m(1-x^2)^{m/2}\frac{d^m}{dx^m}Q_\ell(x).
142
143
144
145
They are named after Adrien-Marie Legendre.
146
147
- Laguerre polynomials may be defined by the Rodrigues formula
148
149
.. math::
150
151
L_n(x)=\frac{e^x}{n!}\frac{d^n}{dx^n}\left(e^{-x} x^n\right).
152
153
154
They are solutions of Laguerre's equation:
155
156
157
.. math::
158
159
x\,y'' + (1 - x)\,y' + n\,y = 0\,
160
161
and satisfy the orthogonality relation
162
163
164
.. math::
165
166
\int_0^\infty L_m(x) L_n(x) e^{-x}\,dx = \delta_{mn}.
167
168
169
170
The generalized Laguerre polynomials may be defined by the
171
Rodrigues formula:
172
173
174
.. math::
175
176
L_n^{(\alpha)}(x) = {\frac{x^{-\alpha} e^x}{n!}}{\frac{d^n}{dx^n}} \left(e^{-x} x^{n+\alpha}\right) .
177
178
179
(These are also sometimes called the associated Laguerre
180
polynomials.) The simple Laguerre polynomials are recovered from
181
the generalized polynomials by setting `\alpha =0`.
182
183
They are named after Edmond Laguerre.
184
185
- Jacobi polynomials are a class of orthogonal polynomials. They
186
are obtained from hypergeometric series in cases where the series
187
is in fact finite:
188
189
.. math::
190
191
P_n^{(\alpha,\beta)}(z) =\frac{(\alpha+1)_n}{n!} \,_2F_1\left(-n,1+\alpha+\beta+n;\alpha+1;\frac{1-z}{2}\right) ,
192
193
194
where `()_n` is Pochhammer's symbol (for the rising
195
factorial), (Abramowitz and Stegun p561.) and thus have the
196
explicit expression
197
198
199
.. math::
200
201
P_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 .
202
203
204
205
They are named after Carl Jacobi.
206
207
- Ultraspherical or Gegenbauer polynomials are given in terms of
208
the Jacobi polynomials `P_n^{(\alpha,\beta)}(x)` with
209
`\alpha=\beta=a-1/2` by
210
211
212
.. math::
213
214
C_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).
215
216
217
They satisfy the orthogonality relation
218
219
.. math::
220
221
\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)} ,
222
223
224
for `a>-1/2`. They are obtained from hypergeometric series
225
in cases where the series is in fact finite:
226
227
228
.. math::
229
230
C_n^{(a)}(z) =\frac{(2a)^{\underline{n}}}{n!} \,_2F_1\left(-n,2a+n;a+\frac{1}{2};\frac{1-z}{2}\right)
231
232
233
where `\underline{n}` is the falling factorial. (See
234
Abramowitz and Stegun p561)
235
236
They are named for Leopold Gegenbauer (1849-1903).
237
238
239
For completeness, the Pochhammer symbol, introduced by Leo August
240
Pochhammer, `(x)_n`, is used in the theory of special
241
functions to represent the "rising factorial" or "upper factorial"
242
243
.. math::
244
245
(x)_n=x(x+1)(x+2)\cdots(x+n-1)=\frac{(x+n-1)!}{(x-1)!}.
246
247
248
On the other hand, the "falling factorial" or "lower factorial" is
249
250
.. math::
251
252
x^{\underline{n}}=\frac{x!}{(x-n)!} ,
253
254
255
in the notation of Ronald L. Graham, Donald E. Knuth and Oren
256
Patashnik in their book Concrete Mathematics.
257
258
.. note::
259
260
The first call of any of these will usually cost a bit extra
261
(it loads "specfun", but I'm not sure if that is the real reason).
262
The next call is usually faster but not always.
263
264
.. TODO::
265
266
Implement associated Legendre polynomials and Zernike
267
polynomials. (Neither is in Maxima.)
268
:wikipedia:`Associated_Legendre_polynomials`
269
:wikipedia:`Zernike_polynomials`
270
271
REFERENCES:
272
273
.. [ASHandbook] Abramowitz and Stegun: Handbook of Mathematical Functions,
274
http://www.math.sfu.ca/ cbm/aands/
275
276
.. :wikipedia:`Chebyshev_polynomials`
277
278
.. :wikipedia:`Legendre_polynomials`
279
280
.. :wikipedia:`Hermite_polynomials`
281
282
.. http://mathworld.wolfram.com/GegenbauerPolynomial.html
283
284
.. :wikipedia:`Jacobi_polynomials`
285
286
.. :wikipedia:`Laguerre_polynomia`
287
288
.. :wikipedia:`Associated_Legendre_polynomials`
289
290
.. [EffCheby] Wolfram Koepf: Effcient Computation of Chebyshev Polynomials
291
in Computer Algebra
292
Computer Algebra Systems: A Practical Guide.
293
John Wiley, Chichester (1999): 79-99.
294
295
AUTHORS:
296
297
- David Joyner (2006-06)
298
- Stefan Reiterer (2010-)
299
"""
300
301
#*****************************************************************************
302
# Copyright (C) 2006 William Stein <[email protected]>
303
# 2006 David Joyner <[email protected]>
304
# 2010 Stefan Reiterer <[email protected]>
305
#
306
# Distributed under the terms of the GNU General Public License (GPL)
307
#
308
# This code is distributed in the hope that it will be useful,
309
# but WITHOUT ANY WARRANTY; without even the implied warranty of
310
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
311
# General Public License for more details.
312
#
313
# The full text of the GPL is available at:
314
#
315
# http://www.gnu.org/licenses/
316
#*****************************************************************************
317
318
import warnings
319
320
from sage.misc.sage_eval import sage_eval
321
from sage.rings.all import ZZ, RR, CC
322
from sage.rings.real_mpfr import is_RealField
323
from sage.rings.complex_field import is_ComplexField
324
from sage.calculus.calculus import maxima
325
326
327
from sage.symbolic.function import BuiltinFunction
328
from sage.symbolic.expression import is_Expression
329
from sage.functions.other import factorial, binomial
330
from sage.structure.coerce import parent
331
332
_done = False
333
def _init():
334
"""
335
Internal function which checks if Maxima has loaded the
336
"orthopoly" package. All functions using this in this
337
file should call this function first.
338
339
TEST:
340
341
The global starts ``False``::
342
343
sage: sage.functions.orthogonal_polys._done
344
False
345
346
Then after using one of these functions, it changes::
347
348
sage: from sage.functions.orthogonal_polys import legendre_P
349
sage: legendre_P(2,x)
350
3/2*(x - 1)^2 + 3*x - 2
351
sage: sage.functions.orthogonal_polys._done
352
True
353
354
355
Note that because here we use a Pynac variable ``x``,
356
the representation of the function is different from
357
its actual doctest, where a polynomial indeterminate
358
``x`` is used.
359
"""
360
global _done
361
if _done:
362
return
363
maxima.eval('load("orthopoly");')
364
# TODO -- make it possible to use the intervals returned
365
# instead of just discarding this info!
366
maxima.eval('orthopoly_returns_intervals:false;')
367
_done = True
368
369
370
class OrthogonalPolynomial(BuiltinFunction):
371
"""
372
Base class for orthogonal polynomials.
373
374
This class is an abstract base class for all orthogonal polynomials since
375
they share similar properties. The evaluation as a polynomial
376
is either done via maxima, or with pynac.
377
378
Convention: The first argument is always the order of the polynomial,
379
the others are other values or parameters where the polynomial is
380
evaluated.
381
"""
382
def __init__(self, name, nargs=2, latex_name=None, conversions={}):
383
"""
384
:class:`OrthogonalPolynomial` class needs the same input parameter as
385
it's parent class.
386
387
EXAMPLES::
388
389
sage: from sage.functions.orthogonal_polys import OrthogonalPolynomial
390
sage: new = OrthogonalPolynomial('testo_P')
391
sage: new
392
testo_P
393
"""
394
try:
395
self._maxima_name = conversions['maxima']
396
except KeyError:
397
self._maxima_name = None
398
399
super(OrthogonalPolynomial,self).__init__(name=name, nargs=nargs,
400
latex_name=latex_name, conversions=conversions)
401
402
def _maxima_init_evaled_(self, *args):
403
r"""
404
Return a string which represents this function evaluated at
405
``n, x`` in Maxima.
406
407
EXAMPLES::
408
409
sage: from sage.functions.orthogonal_polys import OrthogonalPolynomial
410
sage: P = OrthogonalPolynomial('testo_P')
411
sage: P._maxima_init_evaled_(2, 5) is None
412
True
413
"""
414
return None
415
416
def eval_formula(self, *args):
417
"""
418
Evaluate this polynomial using an explicit formula.
419
420
EXAMPLES::
421
422
sage: from sage.functions.orthogonal_polys import OrthogonalPolynomial
423
sage: P = OrthogonalPolynomial('testo_P')
424
sage: P.eval_formula(1,2.0)
425
Traceback (most recent call last):
426
...
427
NotImplementedError: no explicit calculation of values implemented
428
"""
429
raise NotImplementedError("no explicit calculation of values implemented")
430
431
def _eval_special_values_(self, *args):
432
"""
433
Evaluate the polynomial explicitly for special values.
434
435
EXAMPLES::
436
437
sage: var('n')
438
n
439
sage: chebyshev_T(n,-1)
440
(-1)^n
441
"""
442
raise ValueError("no special values known")
443
444
def _eval_(self, n, *args):
445
"""
446
The :meth:`_eval_()` method decides which evaluation suits best
447
for the given input, and returns a proper value.
448
449
EXAMPLES::
450
451
sage: var('n,x')
452
(n, x)
453
sage: chebyshev_T(5,x)
454
16*x^5 - 20*x^3 + 5*x
455
"""
456
return None
457
458
def __call__(self, n, *args, **kwds):
459
"""
460
This overides the call method from SageObject to avoid problems with coercions,
461
since the _eval_ method is able to handle more data types than symbolic functions
462
would normally allow.
463
Thus we have the distinction between algebraic objects (if n is an integer),
464
and else as symbolic function.
465
466
EXAMPLES::
467
468
sage: K.<a> = NumberField(x^3-x-1)
469
sage: chebyshev_T(5, a)
470
16*a^2 + a - 4
471
"""
472
return super(OrthogonalPolynomial,self).__call__(n, *args, **kwds)
473
474
class ChebyshevPolynomial(OrthogonalPolynomial):
475
"""
476
Abstract base class for Chebyshev polynomials of the first and second kind.
477
478
EXAMPLES::
479
480
sage: chebyshev_T(3,x)
481
4*x^3 - 3*x
482
"""
483
def __call__(self, n, *args, **kwds):
484
"""
485
This overides the call method from SageObject to avoid problems with coercions,
486
since the _eval_ method is able to handle more data types than symbolic functions
487
would normally allow.
488
Thus we have the distinction between algebraic objects (if n is an integer),
489
and else as symbolic function.
490
491
EXAMPLES::
492
493
sage: K.<a> = NumberField(x^3-x-1)
494
sage: chebyshev_T(5, a)
495
16*a^2 + a - 4
496
sage: chebyshev_T(5,MatrixSpace(ZZ, 2)([1, 2, -4, 7]))
497
[-40799 44162]
498
[-88324 91687]
499
sage: R.<x> = QQ[]
500
sage: parent(chebyshev_T(5, x))
501
Univariate Polynomial Ring in x over Rational Field
502
sage: chebyshev_T(5, 2, hold=True)
503
chebyshev_T(5, 2)
504
sage: chebyshev_T(1,2,3)
505
Traceback (most recent call last):
506
...
507
TypeError: Symbolic function chebyshev_T takes exactly 2 arguments (3 given)
508
"""
509
# If n is an integer: consider the polynomial as an algebraic (not symbolic) object
510
if n in ZZ and not kwds.get('hold', False):
511
try:
512
return self._eval_(n, *args)
513
except Exception:
514
pass
515
516
return super(ChebyshevPolynomial,self).__call__(n, *args, **kwds)
517
518
def _eval_(self, n, x):
519
"""
520
The :meth:`_eval_()` method decides which evaluation suits best
521
for the given input, and returns a proper value.
522
523
EXAMPLES::
524
525
sage: var('n,x')
526
(n, x)
527
sage: chebyshev_T(5,x)
528
16*x^5 - 20*x^3 + 5*x
529
sage: chebyshev_T(64, x)
530
2*(2*(2*(2*(2*(2*x^2 - 1)^2 - 1)^2 - 1)^2 - 1)^2 - 1)^2 - 1
531
sage: chebyshev_T(n,-1)
532
(-1)^n
533
sage: chebyshev_T(-7,x)
534
64*x^7 - 112*x^5 + 56*x^3 - 7*x
535
sage: chebyshev_T(3/2,x)
536
chebyshev_T(3/2, x)
537
sage: R.<t> = QQ[]
538
sage: chebyshev_T(2,t)
539
2*t^2 - 1
540
sage: chebyshev_U(2,t)
541
4*t^2 - 1
542
sage: parent(chebyshev_T(4, RIF(5)))
543
Real Interval Field with 53 bits of precision
544
sage: RR2 = RealField(5)
545
sage: chebyshev_T(100000,RR2(2))
546
8.9e57180
547
sage: chebyshev_T(5,Qp(3)(2))
548
2 + 3^2 + 3^3 + 3^4 + 3^5 + O(3^20)
549
sage: chebyshev_T(100001/2, 2)
550
doctest:...: RuntimeWarning: mpmath failed, keeping expression unevaluated
551
chebyshev_T(100001/2, 2)
552
sage: chebyshev_U._eval_(1.5, Mod(8,9)) is None
553
True
554
"""
555
# n is an integer => evaluate algebraically (as polynomial)
556
if n in ZZ:
557
n = ZZ(n)
558
# Expanded symbolic expression only for small values of n
559
if is_Expression(x) and n.abs() < 32:
560
return self.eval_formula(n, x)
561
return self.eval_algebraic(n, x)
562
563
if is_Expression(x) or is_Expression(n):
564
# Check for known identities
565
try:
566
return self._eval_special_values_(n, x)
567
except ValueError:
568
# Don't evaluate => keep symbolic
569
return None
570
571
# n is not an integer and neither n nor x is symbolic.
572
# We assume n and x are real/complex and evaluate numerically
573
try:
574
import sage.libs.mpmath.all as mpmath
575
return self._evalf_(n, x)
576
except mpmath.NoConvergence:
577
warnings.warn("mpmath failed, keeping expression unevaluated",
578
RuntimeWarning)
579
return None
580
except Exception:
581
# Numerical evaluation failed => keep symbolic
582
return None
583
584
585
class Func_chebyshev_T(ChebyshevPolynomial):
586
"""
587
Chebyshev polynomials of the first kind.
588
589
REFERENCE:
590
591
- [ASHandbook]_ 22.5.31 page 778 and 6.1.22 page 256.
592
593
EXAMPLES::
594
595
sage: chebyshev_T(5,x)
596
16*x^5 - 20*x^3 + 5*x
597
sage: var('k')
598
k
599
sage: test = chebyshev_T(k,x)
600
sage: test
601
chebyshev_T(k, x)
602
"""
603
def __init__(self):
604
"""
605
Init method for the chebyshev polynomials of the first kind.
606
607
EXAMPLES::
608
609
sage: from sage.functions.orthogonal_polys import Func_chebyshev_T
610
sage: chebyshev_T2 = Func_chebyshev_T()
611
sage: chebyshev_T2(1,x)
612
x
613
"""
614
ChebyshevPolynomial.__init__(self, "chebyshev_T", nargs=2,
615
conversions=dict(maxima='chebyshev_t',
616
mathematica='ChebyshevT'))
617
618
def _eval_special_values_(self, n, x):
619
"""
620
Values known for special values of x.
621
For details see [ASHandbook]_ 22.4 (p. 777)
622
623
EXAMPLES:
624
625
sage: var('n')
626
n
627
sage: chebyshev_T(n,1)
628
1
629
sage: chebyshev_T(n,0)
630
1/2*(-1)^(1/2*n)*((-1)^n + 1)
631
sage: chebyshev_T(n,-1)
632
(-1)^n
633
sage: chebyshev_T._eval_special_values_(3/2,x)
634
Traceback (most recent call last):
635
...
636
ValueError: no special value found
637
sage: chebyshev_T._eval_special_values_(n, 0.1)
638
Traceback (most recent call last):
639
...
640
ValueError: no special value found
641
"""
642
if x == 1:
643
return x
644
645
if x == -1:
646
return x**n
647
648
if x == 0:
649
return (1+(-1)**n)*(-1)**(n/2)/2
650
651
raise ValueError("no special value found")
652
653
def _evalf_(self, n, x, **kwds):
654
"""
655
Evaluates :class:`chebyshev_T` numerically with mpmath.
656
657
EXAMPLES::
658
659
sage: chebyshev_T._evalf_(10,3)
660
2.26195370000000e7
661
sage: chebyshev_T._evalf_(10,3,parent=RealField(75))
662
2.261953700000000000000e7
663
sage: chebyshev_T._evalf_(10,I)
664
-3363.00000000000
665
sage: chebyshev_T._evalf_(5,0.3)
666
0.998880000000000
667
sage: chebyshev_T(1/2, 0)
668
0.707106781186548
669
sage: chebyshev_T(1/2, 3/2)
670
1.11803398874989
671
sage: chebyshev_T._evalf_(1.5, Mod(8,9))
672
Traceback (most recent call last):
673
...
674
TypeError: cannot evaluate chebyshev_T with parent Ring of integers modulo 9
675
676
This simply evaluates using :class:`RealField` or :class:`ComplexField`::
677
678
sage: chebyshev_T(1234.5, RDF(2.1))
679
5.48174256255782e735
680
sage: chebyshev_T(1234.5, I)
681
-1.21629397684152e472 - 1.21629397684152e472*I
682
683
For large values of ``n``, mpmath fails (but the algebraic formula
684
still works)::
685
686
sage: chebyshev_T._evalf_(10^6, 0.1)
687
Traceback (most recent call last):
688
...
689
NoConvergence: Hypergeometric series converges too slowly. Try increasing maxterms.
690
sage: chebyshev_T(10^6, 0.1)
691
0.636384327171504
692
"""
693
try:
694
real_parent = kwds['parent']
695
except KeyError:
696
real_parent = parent(x)
697
698
if not is_RealField(real_parent) and not is_ComplexField(real_parent):
699
# parent is not a real or complex field: figure out a good parent
700
if x in RR:
701
x = RR(x)
702
real_parent = RR
703
elif x in CC:
704
x = CC(x)
705
real_parent = CC
706
707
if not is_RealField(real_parent) and not is_ComplexField(real_parent):
708
raise TypeError("cannot evaluate chebyshev_T with parent {}".format(real_parent))
709
710
from sage.libs.mpmath.all import call as mpcall
711
from sage.libs.mpmath.all import chebyt as mpchebyt
712
713
return mpcall(mpchebyt, n, x, parent=real_parent)
714
715
def _maxima_init_evaled_(self, n, x):
716
"""
717
Evaluate the Chebyshev polynomial ``self`` with maxima.
718
719
EXAMPLES::
720
721
sage: var('n, x')
722
(n, x)
723
sage: chebyshev_T._maxima_init_evaled_(1,x)
724
'x'
725
sage: maxima(chebyshev_T(n, chebyshev_T(n, x)))
726
chebyshev_t(n,chebyshev_t(n,x))
727
"""
728
return maxima.eval('chebyshev_t({0},{1})'.format(n._maxima_init_(), x._maxima_init_()))
729
730
def eval_formula(self, n, x):
731
"""
732
Evaluate ``chebyshev_T`` using an explicit formula.
733
See [ASHandbook]_ 227 (p. 782) for details for the recurions.
734
See also [EffCheby]_ for fast evaluation techniques.
735
736
INPUT:
737
738
- ``n`` -- an integer
739
740
- ``x`` -- a value to evaluate the polynomial at (this can be
741
any ring element)
742
743
EXAMPLES::
744
745
sage: chebyshev_T.eval_formula(-1,x)
746
x
747
sage: chebyshev_T.eval_formula(0,x)
748
1
749
sage: chebyshev_T.eval_formula(1,x)
750
x
751
sage: chebyshev_T.eval_formula(2,0.1) == chebyshev_T._evalf_(2,0.1)
752
True
753
sage: chebyshev_T.eval_formula(10,x)
754
512*x^10 - 1280*x^8 + 1120*x^6 - 400*x^4 + 50*x^2 - 1
755
sage: chebyshev_T.eval_algebraic(10,x).expand()
756
512*x^10 - 1280*x^8 + 1120*x^6 - 400*x^4 + 50*x^2 - 1
757
"""
758
if n < 0:
759
return self.eval_formula(-n, x)
760
elif n == 0:
761
return parent(x).one()
762
763
res = parent(x).zero()
764
for j in xrange(0, n//2+1):
765
f = factorial(n-1-j) / factorial(j) / factorial(n-2*j)
766
res += (-1)**j * (2*x)**(n-2*j) * f
767
res *= n/2
768
return res
769
770
def eval_algebraic(self, n, x):
771
"""
772
Evaluate :class:`chebyshev_T` as polynomial, using a recursive
773
formula.
774
775
INPUT:
776
777
- ``n`` -- an integer
778
779
- ``x`` -- a value to evaluate the polynomial at (this can be
780
any ring element)
781
782
EXAMPLES::
783
784
sage: chebyshev_T.eval_algebraic(5, x)
785
2*(2*(2*x^2 - 1)*x - x)*(2*x^2 - 1) - x
786
sage: chebyshev_T(-7, x) - chebyshev_T(7,x)
787
0
788
sage: R.<t> = ZZ[]
789
sage: chebyshev_T.eval_algebraic(-1, t)
790
t
791
sage: chebyshev_T.eval_algebraic(0, t)
792
1
793
sage: chebyshev_T.eval_algebraic(1, t)
794
t
795
sage: chebyshev_T(7^100, 1/2)
796
1/2
797
sage: chebyshev_T(7^100, Mod(2,3))
798
2
799
sage: n = 97; x = RIF(pi/2/n)
800
sage: chebyshev_T(n, cos(x)).contains_zero()
801
True
802
sage: R.<t> = Zp(2, 8, 'capped-abs')[]
803
sage: chebyshev_T(10^6+1, t)
804
(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))
805
"""
806
if n == 0:
807
return parent(x).one()
808
if n < 0:
809
return self._eval_recursive_(-n, x)[0]
810
return self._eval_recursive_(n, x)[0]
811
812
def _eval_recursive_(self, n, x, both=False):
813
"""
814
If ``both=True``, compute ``(T(n,x), T(n-1,x))`` using a
815
recursive formula.
816
If ``both=False``, return instead a tuple ``(T(n,x), False)``.
817
818
EXAMPLES::
819
820
sage: chebyshev_T._eval_recursive_(5, x)
821
(2*(2*(2*x^2 - 1)*x - x)*(2*x^2 - 1) - x, False)
822
sage: chebyshev_T._eval_recursive_(5, x, True)
823
(2*(2*(2*x^2 - 1)*x - x)*(2*x^2 - 1) - x, 2*(2*x^2 - 1)^2 - 1)
824
"""
825
if n == 1:
826
return x, parent(x).one()
827
828
assert n >= 2
829
a, b = self._eval_recursive_((n+1)//2, x, both or n % 2)
830
if n % 2 == 0:
831
return 2*a*a - 1, both and 2*a*b - x
832
else:
833
return 2*a*b - x, both and 2*b*b - 1
834
835
836
def _eval_numpy_(self, n, x):
837
"""
838
Evaluate ``self`` using numpy.
839
840
EXAMPLES::
841
842
sage: import numpy
843
sage: z = numpy.array([1,2])
844
sage: z2 = numpy.array([[1,2],[1,2]])
845
sage: z3 = numpy.array([1,2,3.])
846
sage: chebyshev_T(1,z)
847
array([ 1., 2.])
848
sage: chebyshev_T(1,z2)
849
array([[ 1., 2.],
850
[ 1., 2.]])
851
sage: chebyshev_T(1,z3)
852
array([ 1., 2., 3.])
853
sage: chebyshev_T(z,0.1)
854
array([ 0.1 , -0.98])
855
"""
856
from scipy.special import eval_chebyt
857
return eval_chebyt(n, x)
858
859
def _derivative_(self, n, x, diff_param):
860
"""
861
Return the derivative of :class:`chebyshev_T` in form of the Chebyshev
862
polynomial of the second kind :class:`chebyshev_U`.
863
864
EXAMPLES::
865
866
sage: var('k')
867
k
868
sage: derivative(chebyshev_T(k,x),x)
869
k*chebyshev_U(k - 1, x)
870
sage: derivative(chebyshev_T(3,x),x)
871
12*x^2 - 3
872
sage: derivative(chebyshev_T(k,x),k)
873
Traceback (most recent call last):
874
...
875
NotImplementedError: derivative w.r.t. to the index is not supported yet
876
"""
877
if diff_param == 0:
878
raise NotImplementedError("derivative w.r.t. to the index is not supported yet")
879
elif diff_param == 1:
880
return n*chebyshev_U(n-1, x)
881
raise ValueError("illegal differentiation parameter {}".format(diff_param))
882
883
chebyshev_T = Func_chebyshev_T()
884
885
class Func_chebyshev_U(ChebyshevPolynomial):
886
"""
887
Class for the Chebyshev polynomial of the second kind.
888
889
REFERENCE:
890
891
- [ASHandbook]_ 22.8.3 page 783 and 6.1.22 page 256.
892
893
EXAMPLES::
894
895
sage: R.<t> = QQ[]
896
sage: chebyshev_U(2,t)
897
4*t^2 - 1
898
sage: chebyshev_U(3,t)
899
8*t^3 - 4*t
900
"""
901
def __init__(self):
902
"""
903
Init method for the chebyshev polynomials of the second kind.
904
905
EXAMPLES::
906
907
sage: from sage.functions.orthogonal_polys import Func_chebyshev_U
908
sage: chebyshev_U2 = Func_chebyshev_U()
909
sage: chebyshev_U2(1,x)
910
2*x
911
"""
912
ChebyshevPolynomial.__init__(self, "chebyshev_U", nargs=2,
913
conversions=dict(maxima='chebyshev_u',
914
mathematica='ChebyshevU'))
915
916
def eval_formula(self, n, x):
917
"""
918
Evaluate ``chebyshev_U`` using an explicit formula.
919
See [ASHandbook]_ 227 (p. 782) for details on the recurions.
920
See also [EffCheby]_ for the recursion formulas.
921
922
INPUT:
923
924
- ``n`` -- an integer
925
926
- ``x`` -- a value to evaluate the polynomial at (this can be
927
any ring element)
928
929
EXAMPLES::
930
931
sage: chebyshev_U.eval_formula(10, x)
932
1024*x^10 - 2304*x^8 + 1792*x^6 - 560*x^4 + 60*x^2 - 1
933
sage: chebyshev_U.eval_formula(-2, x)
934
-1
935
sage: chebyshev_U.eval_formula(-1, x)
936
0
937
sage: chebyshev_U.eval_formula(0, x)
938
1
939
sage: chebyshev_U.eval_formula(1, x)
940
2*x
941
sage: chebyshev_U.eval_formula(2,0.1) == chebyshev_U._evalf_(2,0.1)
942
True
943
"""
944
if n < -1:
945
return -self.eval_formula(-n-2, x)
946
947
res = parent(x).zero()
948
for j in xrange(0, n//2+1):
949
f = binomial(n-j, j)
950
res += (-1)**j * (2*x)**(n-2*j) * f
951
return res
952
953
def eval_algebraic(self, n, x):
954
"""
955
Evaluate :class:`chebyshev_U` as polynomial, using a recursive
956
formula.
957
958
INPUT:
959
960
- ``n`` -- an integer
961
962
- ``x`` -- a value to evaluate the polynomial at (this can be
963
any ring element)
964
965
EXAMPLES::
966
967
sage: chebyshev_U.eval_algebraic(5,x)
968
-2*((2*x + 1)*(2*x - 1)*x - 4*(2*x^2 - 1)*x)*(2*x + 1)*(2*x - 1)
969
sage: parent(chebyshev_U(3, Mod(8,9)))
970
Ring of integers modulo 9
971
sage: parent(chebyshev_U(3, Mod(1,9)))
972
Ring of integers modulo 9
973
sage: chebyshev_U(-3,x) + chebyshev_U(1,x)
974
0
975
sage: chebyshev_U(-1,Mod(5,8))
976
0
977
sage: parent(chebyshev_U(-1,Mod(5,8)))
978
Ring of integers modulo 8
979
sage: R.<t> = ZZ[]
980
sage: chebyshev_U.eval_algebraic(-2, t)
981
-1
982
sage: chebyshev_U.eval_algebraic(-1, t)
983
0
984
sage: chebyshev_U.eval_algebraic(0, t)
985
1
986
sage: chebyshev_U.eval_algebraic(1, t)
987
2*t
988
sage: n = 97; x = RIF(pi/n)
989
sage: chebyshev_U(n-1, cos(x)).contains_zero()
990
True
991
sage: R.<t> = Zp(2, 6, 'capped-abs')[]
992
sage: chebyshev_U(10^6+1, t)
993
(2 + O(2^6))*t + (O(2^6))
994
"""
995
if n == -1:
996
return parent(x).zero()
997
if n < 0:
998
return -self._eval_recursive_(-n-2, x)[0]
999
return self._eval_recursive_(n, x)[0]
1000
1001
def _eval_recursive_(self, n, x, both=False):
1002
"""
1003
If ``both=True``, compute ``(U(n,x), U(n-1,x))`` using a
1004
recursive formula.
1005
If ``both=False``, return instead a tuple ``(U(n,x), False)``.
1006
1007
EXAMPLES::
1008
1009
sage: chebyshev_U._eval_recursive_(3, x)
1010
(4*((2*x + 1)*(2*x - 1) - 2*x^2)*x, False)
1011
sage: chebyshev_U._eval_recursive_(3, x, True)
1012
(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))
1013
"""
1014
if n == 0:
1015
return parent(x).one(), 2*x
1016
1017
assert n >= 1
1018
a, b = self._eval_recursive_((n-1)//2, x, True)
1019
if n % 2 == 0:
1020
return (b+a)*(b-a), both and 2*b*(x*b-a)
1021
else:
1022
return 2*a*(b-x*a), both and (b+a)*(b-a)
1023
1024
def _maxima_init_evaled_(self, n, x):
1025
"""
1026
Uses maxima to evaluate ``self``.
1027
1028
EXAMPLES::
1029
1030
sage: var('n, x')
1031
(n, x)
1032
sage: maxima(chebyshev_U(5,x))
1033
32*x^5-32*x^3+6*x
1034
sage: maxima(chebyshev_U(n,x))
1035
chebyshev_u(n,x)
1036
sage: maxima(chebyshev_U(2,x))
1037
4*x^2-1
1038
"""
1039
return maxima.eval('chebyshev_u({0},{1})'.format(n._maxima_init_(), x._maxima_init_()))
1040
1041
def _evalf_(self, n, x, **kwds):
1042
"""
1043
Evaluate :class:`chebyshev_U` numerically with mpmath.
1044
1045
EXAMPLES::
1046
1047
sage: chebyshev_U(5,-4+3.*I)
1048
98280.0000000000 - 11310.0000000000*I
1049
sage: chebyshev_U(10,3).n(75)
1050
4.661117900000000000000e7
1051
sage: chebyshev_U._evalf_(1.5, Mod(8,9))
1052
Traceback (most recent call last):
1053
...
1054
TypeError: cannot evaluate chebyshev_U with parent Ring of integers modulo 9
1055
"""
1056
try:
1057
real_parent = kwds['parent']
1058
except KeyError:
1059
real_parent = parent(x)
1060
1061
if not is_RealField(real_parent) and not is_ComplexField(real_parent):
1062
# parent is not a real or complex field: figure out a good parent
1063
if x in RR:
1064
x = RR(x)
1065
real_parent = RR
1066
elif x in CC:
1067
x = CC(x)
1068
real_parent = CC
1069
1070
if not is_RealField(real_parent) and not is_ComplexField(real_parent):
1071
raise TypeError("cannot evaluate chebyshev_U with parent {}".format(real_parent))
1072
1073
from sage.libs.mpmath.all import call as mpcall
1074
from sage.libs.mpmath.all import chebyu as mpchebyu
1075
1076
return mpcall(mpchebyu, n, x, parent=real_parent)
1077
1078
def _eval_special_values_(self, n, x):
1079
"""
1080
Values known for special values of x.
1081
See [ASHandbook]_ 22.4 (p.777).
1082
1083
EXAMPLES::
1084
1085
sage: var('n')
1086
n
1087
sage: chebyshev_U(n,1)
1088
n + 1
1089
sage: chebyshev_U(n,0)
1090
1/2*(-1)^(1/2*n)*((-1)^n + 1)
1091
sage: chebyshev_U(n,-1)
1092
(-1)^n*(n + 1)
1093
sage: chebyshev_U._eval_special_values_(n, 2)
1094
Traceback (most recent call last):
1095
...
1096
ValueError: no special value found
1097
"""
1098
if x == 1:
1099
return x*(n+1)
1100
1101
if x == -1:
1102
return x**n*(n+1)
1103
1104
if x == 0:
1105
return (1+(-1)**n)*(-1)**(n/2)/2
1106
1107
raise ValueError("no special value found")
1108
1109
def _eval_numpy_(self, n, x):
1110
"""
1111
Evaluate ``self`` using numpy.
1112
1113
EXAMPLES::
1114
1115
sage: import numpy
1116
sage: z = numpy.array([1,2])
1117
sage: z2 = numpy.array([[1,2],[1,2]])
1118
sage: z3 = numpy.array([1,2,3.])
1119
sage: chebyshev_U(1,z)
1120
array([ 2., 4.])
1121
sage: chebyshev_U(1,z2)
1122
array([[ 2., 4.],
1123
[ 2., 4.]])
1124
sage: chebyshev_U(1,z3)
1125
array([ 2., 4., 6.])
1126
sage: chebyshev_U(z,0.1)
1127
array([ 0.2 , -0.96])
1128
"""
1129
from scipy.special import eval_chebyu
1130
return eval_chebyu(n, x)
1131
1132
def _derivative_(self, n, x, diff_param):
1133
"""
1134
Return the derivative of :class:`chebyshev_U` in form of the Chebyshev
1135
polynomials of the first and second kind.
1136
1137
EXAMPLES::
1138
1139
sage: var('k')
1140
k
1141
sage: derivative(chebyshev_U(k,x),x)
1142
((k + 1)*chebyshev_T(k + 1, x) - x*chebyshev_U(k, x))/(x^2 - 1)
1143
sage: derivative(chebyshev_U(3,x),x)
1144
24*x^2 - 4
1145
sage: derivative(chebyshev_U(k,x),k)
1146
Traceback (most recent call last):
1147
...
1148
NotImplementedError: derivative w.r.t. to the index is not supported yet
1149
"""
1150
if diff_param == 0:
1151
raise NotImplementedError("derivative w.r.t. to the index is not supported yet")
1152
elif diff_param == 1:
1153
return ((n+1)*chebyshev_T(n+1, x) - x*chebyshev_U(n,x)) / (x*x-1)
1154
raise ValueError("illegal differentiation parameter {}".format(diff_param))
1155
1156
chebyshev_U = Func_chebyshev_U()
1157
1158
1159
def gen_laguerre(n,a,x):
1160
"""
1161
Returns the generalized Laguerre polynomial for integers `n > -1`.
1162
Typically, `a = 1/2` or `a = -1/2`.
1163
1164
REFERENCES:
1165
1166
- Table on page 789 in [ASHandbook]_.
1167
1168
EXAMPLES::
1169
1170
sage: x = PolynomialRing(QQ, 'x').gen()
1171
sage: gen_laguerre(2,1,x)
1172
1/2*x^2 - 3*x + 3
1173
sage: gen_laguerre(2,1/2,x)
1174
1/2*x^2 - 5/2*x + 15/8
1175
sage: gen_laguerre(2,-1/2,x)
1176
1/2*x^2 - 3/2*x + 3/8
1177
sage: gen_laguerre(2,0,x)
1178
1/2*x^2 - 2*x + 1
1179
sage: gen_laguerre(3,0,x)
1180
-1/6*x^3 + 3/2*x^2 - 3*x + 1
1181
"""
1182
_init()
1183
return sage_eval(maxima.eval('gen_laguerre(%s,%s,x)'%(ZZ(n),a)), locals={'x':x})
1184
1185
def gen_legendre_P(n,m,x):
1186
r"""
1187
Returns the generalized (or associated) Legendre function of the
1188
first kind for integers `n > -1, m > -1`.
1189
1190
The awkward code for when m is odd and 1 results from the fact that
1191
Maxima is happy with, for example, `(1 - t^2)^3/2`, but
1192
Sage is not. For these cases the function is computed from the
1193
(m-1)-case using one of the recursions satisfied by the Legendre
1194
functions.
1195
1196
REFERENCE:
1197
1198
- Gradshteyn and Ryzhik 8.706 page 1000.
1199
1200
EXAMPLES::
1201
1202
sage: P.<t> = QQ[]
1203
sage: gen_legendre_P(2, 0, t)
1204
3/2*t^2 - 1/2
1205
sage: gen_legendre_P(2, 0, t) == legendre_P(2, t)
1206
True
1207
sage: gen_legendre_P(3, 1, t)
1208
-3/2*(5*t^2 - 1)*sqrt(-t^2 + 1)
1209
sage: gen_legendre_P(4, 3, t)
1210
105*(t^2 - 1)*sqrt(-t^2 + 1)*t
1211
sage: gen_legendre_P(7, 3, I).expand()
1212
-16695*sqrt(2)
1213
sage: gen_legendre_P(4, 1, 2.5)
1214
-583.562373654533*I
1215
"""
1216
from sage.functions.all import sqrt
1217
_init()
1218
if m.mod(2).is_zero() or m.is_one():
1219
return sage_eval(maxima.eval('assoc_legendre_p(%s,%s,x)'%(ZZ(n),ZZ(m))), locals={'x':x})
1220
else:
1221
return 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))
1222
1223
def gen_legendre_Q(n,m,x):
1224
"""
1225
Returns the generalized (or associated) Legendre function of the
1226
second kind for integers `n>-1`, `m>-1`.
1227
1228
Maxima restricts m = n. Hence the cases m n are computed using the
1229
same recursion used for gen_legendre_P(n,m,x) when m is odd and
1230
1.
1231
1232
EXAMPLES::
1233
1234
sage: P.<t> = QQ[]
1235
sage: gen_legendre_Q(2,0,t)
1236
3/4*t^2*log(-(t + 1)/(t - 1)) - 3/2*t - 1/4*log(-(t + 1)/(t - 1))
1237
sage: gen_legendre_Q(2,0,t) - legendre_Q(2, t)
1238
0
1239
sage: gen_legendre_Q(3,1,0.5)
1240
2.49185259170895
1241
sage: gen_legendre_Q(0, 1, x)
1242
-1/sqrt(-x^2 + 1)
1243
sage: gen_legendre_Q(2, 4, x).factor()
1244
48*x/((x + 1)^2*(x - 1)^2)
1245
"""
1246
from sage.functions.all import sqrt
1247
if m <= n:
1248
_init()
1249
return sage_eval(maxima.eval('assoc_legendre_q(%s,%s,x)'%(ZZ(n),ZZ(m))), locals={'x':x})
1250
if m == n + 1 or n == 0:
1251
if m.mod(2).is_zero():
1252
denom = (1 - x**2)**(m/2)
1253
else:
1254
denom = sqrt(1 - x**2)*(1 - x**2)**((m-1)/2)
1255
if m == n + 1:
1256
return (-1)**m*(m-1).factorial()*2**n/denom
1257
else:
1258
return (-1)**m*(m-1).factorial()*((x+1)**m - (x-1)**m)/(2*denom)
1259
else:
1260
return ((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)
1261
1262
def hermite(n,x):
1263
"""
1264
Returns the Hermite polynomial for integers `n > -1`.
1265
1266
REFERENCE:
1267
1268
- [ASHandbook]_ 22.5.40 and 22.5.41, page 779.
1269
1270
EXAMPLES::
1271
1272
sage: x = PolynomialRing(QQ, 'x').gen()
1273
sage: hermite(2,x)
1274
4*x^2 - 2
1275
sage: hermite(3,x)
1276
8*x^3 - 12*x
1277
sage: hermite(3,2)
1278
40
1279
sage: S.<y> = PolynomialRing(RR)
1280
sage: hermite(3,y)
1281
8.00000000000000*y^3 - 12.0000000000000*y
1282
sage: R.<x,y> = QQ[]
1283
sage: hermite(3,y^2)
1284
8*y^6 - 12*y^2
1285
sage: w = var('w')
1286
sage: hermite(3,2*w)
1287
8*(8*w^2 - 3)*w
1288
"""
1289
_init()
1290
return sage_eval(maxima.eval('hermite(%s,x)'%ZZ(n)), locals={'x':x})
1291
1292
def jacobi_P(n,a,b,x):
1293
r"""
1294
Returns the Jacobi polynomial `P_n^{(a,b)}(x)` for
1295
integers `n > -1` and a and b symbolic or `a > -1`
1296
and `b > -1`. The Jacobi polynomials are actually defined
1297
for all a and b. However, the Jacobi polynomial weight
1298
`(1-x)^a(1+x)^b` isn't integrable for `a \leq -1`
1299
or `b \leq -1`.
1300
1301
REFERENCE:
1302
1303
- Table on page 789 in [ASHandbook]_.
1304
1305
EXAMPLES::
1306
1307
sage: x = PolynomialRing(QQ, 'x').gen()
1308
sage: jacobi_P(2,0,0,x)
1309
3/2*x^2 - 1/2
1310
sage: jacobi_P(2,1,2,1.2) # random output of low order bits
1311
5.009999999999998
1312
"""
1313
_init()
1314
return sage_eval(maxima.eval('jacobi_p(%s,%s,%s,x)'%(ZZ(n),a,b)), locals={'x':x})
1315
1316
def laguerre(n,x):
1317
"""
1318
Return the Laguerre polynomial for integers `n > -1`.
1319
1320
REFERENCE:
1321
1322
- [ASHandbook]_ 22.5.16, page 778 and page 789.
1323
1324
EXAMPLES::
1325
1326
sage: x = PolynomialRing(QQ, 'x').gen()
1327
sage: laguerre(2,x)
1328
1/2*x^2 - 2*x + 1
1329
sage: laguerre(3,x)
1330
-1/6*x^3 + 3/2*x^2 - 3*x + 1
1331
sage: laguerre(2,2)
1332
-1
1333
"""
1334
_init()
1335
return sage_eval(maxima.eval('laguerre(%s,x)'%ZZ(n)), locals={'x':x})
1336
1337
def legendre_P(n,x):
1338
"""
1339
Returns the Legendre polynomial of the first kind for integers
1340
`n > -1`.
1341
1342
REFERENCE:
1343
1344
- [ASHandbook]_ 22.5.35 page 779.
1345
1346
EXAMPLES::
1347
1348
sage: P.<t> = QQ[]
1349
sage: legendre_P(2,t)
1350
3/2*t^2 - 1/2
1351
sage: legendre_P(3, 1.1)
1352
1.67750000000000
1353
sage: legendre_P(3, 1 + I)
1354
7/2*I - 13/2
1355
sage: legendre_P(3, MatrixSpace(ZZ, 2)([1, 2, -4, 7]))
1356
[-179 242]
1357
[-484 547]
1358
sage: legendre_P(3, GF(11)(5))
1359
8
1360
"""
1361
_init()
1362
return sage_eval(maxima.eval('legendre_p(%s,x)'%ZZ(n)), locals={'x':x})
1363
1364
def legendre_Q(n,x):
1365
"""
1366
Returns the Legendre function of the second kind for integers
1367
`n > -1`.
1368
1369
Computed using Maxima.
1370
1371
EXAMPLES::
1372
1373
sage: P.<t> = QQ[]
1374
sage: legendre_Q(2, t)
1375
3/4*t^2*log(-(t + 1)/(t - 1)) - 3/2*t - 1/4*log(-(t + 1)/(t - 1))
1376
sage: legendre_Q(3, 0.5)
1377
-0.198654771479482
1378
sage: legendre_Q(4, 2)
1379
443/16*I*pi + 443/16*log(3) - 365/12
1380
sage: legendre_Q(4, 2.0)
1381
0.00116107583162324 + 86.9828465962674*I
1382
"""
1383
_init()
1384
return sage_eval(maxima.eval('legendre_q(%s,x)'%ZZ(n)), locals={'x':x})
1385
1386
def ultraspherical(n,a,x):
1387
"""
1388
Returns the ultraspherical (or Gegenbauer) polynomial for integers
1389
`n > -1`.
1390
1391
Computed using Maxima.
1392
1393
REFERENCE:
1394
1395
- [ASHandbook]_ 22.5.27
1396
1397
EXAMPLES::
1398
1399
sage: x = PolynomialRing(QQ, 'x').gen()
1400
sage: ultraspherical(2,3/2,x)
1401
15/2*x^2 - 3/2
1402
sage: ultraspherical(2,1/2,x)
1403
3/2*x^2 - 1/2
1404
sage: ultraspherical(1,1,x)
1405
2*x
1406
sage: t = PolynomialRing(RationalField(),"t").gen()
1407
sage: gegenbauer(3,2,t)
1408
32*t^3 - 12*t
1409
"""
1410
_init()
1411
return sage_eval(maxima.eval('ultraspherical(%s,%s,x)'%(ZZ(n),a)), locals={'x':x})
1412
1413
gegenbauer = ultraspherical
1414
1415