Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/numpy/polynomial/laguerre.py: 16%
252 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1"""
2==================================================
3Laguerre Series (:mod:`numpy.polynomial.laguerre`)
4==================================================
6This module provides a number of objects (mostly functions) useful for
7dealing with Laguerre series, including a `Laguerre` class that
8encapsulates the usual arithmetic operations. (General information
9on how this module represents and works with such polynomials is in the
10docstring for its "parent" sub-package, `numpy.polynomial`).
12Classes
13-------
14.. autosummary::
15 :toctree: generated/
17 Laguerre
19Constants
20---------
21.. autosummary::
22 :toctree: generated/
24 lagdomain
25 lagzero
26 lagone
27 lagx
29Arithmetic
30----------
31.. autosummary::
32 :toctree: generated/
34 lagadd
35 lagsub
36 lagmulx
37 lagmul
38 lagdiv
39 lagpow
40 lagval
41 lagval2d
42 lagval3d
43 laggrid2d
44 laggrid3d
46Calculus
47--------
48.. autosummary::
49 :toctree: generated/
51 lagder
52 lagint
54Misc Functions
55--------------
56.. autosummary::
57 :toctree: generated/
59 lagfromroots
60 lagroots
61 lagvander
62 lagvander2d
63 lagvander3d
64 laggauss
65 lagweight
66 lagcompanion
67 lagfit
68 lagtrim
69 lagline
70 lag2poly
71 poly2lag
73See also
74--------
75`numpy.polynomial`
77"""
78import numpy as np
79import numpy.linalg as la
80from numpy.core.multiarray import normalize_axis_index
82from . import polyutils as pu
83from ._polybase import ABCPolyBase
85__all__ = [
86 'lagzero', 'lagone', 'lagx', 'lagdomain', 'lagline', 'lagadd',
87 'lagsub', 'lagmulx', 'lagmul', 'lagdiv', 'lagpow', 'lagval', 'lagder',
88 'lagint', 'lag2poly', 'poly2lag', 'lagfromroots', 'lagvander',
89 'lagfit', 'lagtrim', 'lagroots', 'Laguerre', 'lagval2d', 'lagval3d',
90 'laggrid2d', 'laggrid3d', 'lagvander2d', 'lagvander3d', 'lagcompanion',
91 'laggauss', 'lagweight']
93lagtrim = pu.trimcoef
96def poly2lag(pol):
97 """
98 poly2lag(pol)
100 Convert a polynomial to a Laguerre series.
102 Convert an array representing the coefficients of a polynomial (relative
103 to the "standard" basis) ordered from lowest degree to highest, to an
104 array of the coefficients of the equivalent Laguerre series, ordered
105 from lowest to highest degree.
107 Parameters
108 ----------
109 pol : array_like
110 1-D array containing the polynomial coefficients
112 Returns
113 -------
114 c : ndarray
115 1-D array containing the coefficients of the equivalent Laguerre
116 series.
118 See Also
119 --------
120 lag2poly
122 Notes
123 -----
124 The easy way to do conversions between polynomial basis sets
125 is to use the convert method of a class instance.
127 Examples
128 --------
129 >>> from numpy.polynomial.laguerre import poly2lag
130 >>> poly2lag(np.arange(4))
131 array([ 23., -63., 58., -18.])
133 """
134 [pol] = pu.as_series([pol])
135 res = 0
136 for p in pol[::-1]:
137 res = lagadd(lagmulx(res), p)
138 return res
141def lag2poly(c):
142 """
143 Convert a Laguerre series to a polynomial.
145 Convert an array representing the coefficients of a Laguerre series,
146 ordered from lowest degree to highest, to an array of the coefficients
147 of the equivalent polynomial (relative to the "standard" basis) ordered
148 from lowest to highest degree.
150 Parameters
151 ----------
152 c : array_like
153 1-D array containing the Laguerre series coefficients, ordered
154 from lowest order term to highest.
156 Returns
157 -------
158 pol : ndarray
159 1-D array containing the coefficients of the equivalent polynomial
160 (relative to the "standard" basis) ordered from lowest order term
161 to highest.
163 See Also
164 --------
165 poly2lag
167 Notes
168 -----
169 The easy way to do conversions between polynomial basis sets
170 is to use the convert method of a class instance.
172 Examples
173 --------
174 >>> from numpy.polynomial.laguerre import lag2poly
175 >>> lag2poly([ 23., -63., 58., -18.])
176 array([0., 1., 2., 3.])
178 """
179 from .polynomial import polyadd, polysub, polymulx
181 [c] = pu.as_series([c])
182 n = len(c)
183 if n == 1:
184 return c
185 else:
186 c0 = c[-2]
187 c1 = c[-1]
188 # i is the current degree of c1
189 for i in range(n - 1, 1, -1):
190 tmp = c0
191 c0 = polysub(c[i - 2], (c1*(i - 1))/i)
192 c1 = polyadd(tmp, polysub((2*i - 1)*c1, polymulx(c1))/i)
193 return polyadd(c0, polysub(c1, polymulx(c1)))
195#
196# These are constant arrays are of integer type so as to be compatible
197# with the widest range of other types, such as Decimal.
198#
200# Laguerre
201lagdomain = np.array([0, 1])
203# Laguerre coefficients representing zero.
204lagzero = np.array([0])
206# Laguerre coefficients representing one.
207lagone = np.array([1])
209# Laguerre coefficients representing the identity x.
210lagx = np.array([1, -1])
213def lagline(off, scl):
214 """
215 Laguerre series whose graph is a straight line.
217 Parameters
218 ----------
219 off, scl : scalars
220 The specified line is given by ``off + scl*x``.
222 Returns
223 -------
224 y : ndarray
225 This module's representation of the Laguerre series for
226 ``off + scl*x``.
228 See Also
229 --------
230 numpy.polynomial.polynomial.polyline
231 numpy.polynomial.chebyshev.chebline
232 numpy.polynomial.legendre.legline
233 numpy.polynomial.hermite.hermline
234 numpy.polynomial.hermite_e.hermeline
236 Examples
237 --------
238 >>> from numpy.polynomial.laguerre import lagline, lagval
239 >>> lagval(0,lagline(3, 2))
240 3.0
241 >>> lagval(1,lagline(3, 2))
242 5.0
244 """
245 if scl != 0:
246 return np.array([off + scl, -scl])
247 else:
248 return np.array([off])
251def lagfromroots(roots):
252 """
253 Generate a Laguerre series with given roots.
255 The function returns the coefficients of the polynomial
257 .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
259 in Laguerre form, where the `r_n` are the roots specified in `roots`.
260 If a zero has multiplicity n, then it must appear in `roots` n times.
261 For instance, if 2 is a root of multiplicity three and 3 is a root of
262 multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
263 roots can appear in any order.
265 If the returned coefficients are `c`, then
267 .. math:: p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x)
269 The coefficient of the last term is not generally 1 for monic
270 polynomials in Laguerre form.
272 Parameters
273 ----------
274 roots : array_like
275 Sequence containing the roots.
277 Returns
278 -------
279 out : ndarray
280 1-D array of coefficients. If all roots are real then `out` is a
281 real array, if some of the roots are complex, then `out` is complex
282 even if all the coefficients in the result are real (see Examples
283 below).
285 See Also
286 --------
287 numpy.polynomial.polynomial.polyfromroots
288 numpy.polynomial.legendre.legfromroots
289 numpy.polynomial.chebyshev.chebfromroots
290 numpy.polynomial.hermite.hermfromroots
291 numpy.polynomial.hermite_e.hermefromroots
293 Examples
294 --------
295 >>> from numpy.polynomial.laguerre import lagfromroots, lagval
296 >>> coef = lagfromroots((-1, 0, 1))
297 >>> lagval((-1, 0, 1), coef)
298 array([0., 0., 0.])
299 >>> coef = lagfromroots((-1j, 1j))
300 >>> lagval((-1j, 1j), coef)
301 array([0.+0.j, 0.+0.j])
303 """
304 return pu._fromroots(lagline, lagmul, roots)
307def lagadd(c1, c2):
308 """
309 Add one Laguerre series to another.
311 Returns the sum of two Laguerre series `c1` + `c2`. The arguments
312 are sequences of coefficients ordered from lowest order term to
313 highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
315 Parameters
316 ----------
317 c1, c2 : array_like
318 1-D arrays of Laguerre series coefficients ordered from low to
319 high.
321 Returns
322 -------
323 out : ndarray
324 Array representing the Laguerre series of their sum.
326 See Also
327 --------
328 lagsub, lagmulx, lagmul, lagdiv, lagpow
330 Notes
331 -----
332 Unlike multiplication, division, etc., the sum of two Laguerre series
333 is a Laguerre series (without having to "reproject" the result onto
334 the basis set) so addition, just like that of "standard" polynomials,
335 is simply "component-wise."
337 Examples
338 --------
339 >>> from numpy.polynomial.laguerre import lagadd
340 >>> lagadd([1, 2, 3], [1, 2, 3, 4])
341 array([2., 4., 6., 4.])
344 """
345 return pu._add(c1, c2)
348def lagsub(c1, c2):
349 """
350 Subtract one Laguerre series from another.
352 Returns the difference of two Laguerre series `c1` - `c2`. The
353 sequences of coefficients are from lowest order term to highest, i.e.,
354 [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
356 Parameters
357 ----------
358 c1, c2 : array_like
359 1-D arrays of Laguerre series coefficients ordered from low to
360 high.
362 Returns
363 -------
364 out : ndarray
365 Of Laguerre series coefficients representing their difference.
367 See Also
368 --------
369 lagadd, lagmulx, lagmul, lagdiv, lagpow
371 Notes
372 -----
373 Unlike multiplication, division, etc., the difference of two Laguerre
374 series is a Laguerre series (without having to "reproject" the result
375 onto the basis set) so subtraction, just like that of "standard"
376 polynomials, is simply "component-wise."
378 Examples
379 --------
380 >>> from numpy.polynomial.laguerre import lagsub
381 >>> lagsub([1, 2, 3, 4], [1, 2, 3])
382 array([0., 0., 0., 4.])
384 """
385 return pu._sub(c1, c2)
388def lagmulx(c):
389 """Multiply a Laguerre series by x.
391 Multiply the Laguerre series `c` by x, where x is the independent
392 variable.
395 Parameters
396 ----------
397 c : array_like
398 1-D array of Laguerre series coefficients ordered from low to
399 high.
401 Returns
402 -------
403 out : ndarray
404 Array representing the result of the multiplication.
406 See Also
407 --------
408 lagadd, lagsub, lagmul, lagdiv, lagpow
410 Notes
411 -----
412 The multiplication uses the recursion relationship for Laguerre
413 polynomials in the form
415 .. math::
417 xP_i(x) = (-(i + 1)*P_{i + 1}(x) + (2i + 1)P_{i}(x) - iP_{i - 1}(x))
419 Examples
420 --------
421 >>> from numpy.polynomial.laguerre import lagmulx
422 >>> lagmulx([1, 2, 3])
423 array([-1., -1., 11., -9.])
425 """
426 # c is a trimmed copy
427 [c] = pu.as_series([c])
428 # The zero series needs special treatment
429 if len(c) == 1 and c[0] == 0:
430 return c
432 prd = np.empty(len(c) + 1, dtype=c.dtype)
433 prd[0] = c[0]
434 prd[1] = -c[0]
435 for i in range(1, len(c)):
436 prd[i + 1] = -c[i]*(i + 1)
437 prd[i] += c[i]*(2*i + 1)
438 prd[i - 1] -= c[i]*i
439 return prd
442def lagmul(c1, c2):
443 """
444 Multiply one Laguerre series by another.
446 Returns the product of two Laguerre series `c1` * `c2`. The arguments
447 are sequences of coefficients, from lowest order "term" to highest,
448 e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
450 Parameters
451 ----------
452 c1, c2 : array_like
453 1-D arrays of Laguerre series coefficients ordered from low to
454 high.
456 Returns
457 -------
458 out : ndarray
459 Of Laguerre series coefficients representing their product.
461 See Also
462 --------
463 lagadd, lagsub, lagmulx, lagdiv, lagpow
465 Notes
466 -----
467 In general, the (polynomial) product of two C-series results in terms
468 that are not in the Laguerre polynomial basis set. Thus, to express
469 the product as a Laguerre series, it is necessary to "reproject" the
470 product onto said basis set, which may produce "unintuitive" (but
471 correct) results; see Examples section below.
473 Examples
474 --------
475 >>> from numpy.polynomial.laguerre import lagmul
476 >>> lagmul([1, 2, 3], [0, 1, 2])
477 array([ 8., -13., 38., -51., 36.])
479 """
480 # s1, s2 are trimmed copies
481 [c1, c2] = pu.as_series([c1, c2])
483 if len(c1) > len(c2):
484 c = c2
485 xs = c1
486 else:
487 c = c1
488 xs = c2
490 if len(c) == 1:
491 c0 = c[0]*xs
492 c1 = 0
493 elif len(c) == 2:
494 c0 = c[0]*xs
495 c1 = c[1]*xs
496 else:
497 nd = len(c)
498 c0 = c[-2]*xs
499 c1 = c[-1]*xs
500 for i in range(3, len(c) + 1):
501 tmp = c0
502 nd = nd - 1
503 c0 = lagsub(c[-i]*xs, (c1*(nd - 1))/nd)
504 c1 = lagadd(tmp, lagsub((2*nd - 1)*c1, lagmulx(c1))/nd)
505 return lagadd(c0, lagsub(c1, lagmulx(c1)))
508def lagdiv(c1, c2):
509 """
510 Divide one Laguerre series by another.
512 Returns the quotient-with-remainder of two Laguerre series
513 `c1` / `c2`. The arguments are sequences of coefficients from lowest
514 order "term" to highest, e.g., [1,2,3] represents the series
515 ``P_0 + 2*P_1 + 3*P_2``.
517 Parameters
518 ----------
519 c1, c2 : array_like
520 1-D arrays of Laguerre series coefficients ordered from low to
521 high.
523 Returns
524 -------
525 [quo, rem] : ndarrays
526 Of Laguerre series coefficients representing the quotient and
527 remainder.
529 See Also
530 --------
531 lagadd, lagsub, lagmulx, lagmul, lagpow
533 Notes
534 -----
535 In general, the (polynomial) division of one Laguerre series by another
536 results in quotient and remainder terms that are not in the Laguerre
537 polynomial basis set. Thus, to express these results as a Laguerre
538 series, it is necessary to "reproject" the results onto the Laguerre
539 basis set, which may produce "unintuitive" (but correct) results; see
540 Examples section below.
542 Examples
543 --------
544 >>> from numpy.polynomial.laguerre import lagdiv
545 >>> lagdiv([ 8., -13., 38., -51., 36.], [0, 1, 2])
546 (array([1., 2., 3.]), array([0.]))
547 >>> lagdiv([ 9., -12., 38., -51., 36.], [0, 1, 2])
548 (array([1., 2., 3.]), array([1., 1.]))
550 """
551 return pu._div(lagmul, c1, c2)
554def lagpow(c, pow, maxpower=16):
555 """Raise a Laguerre series to a power.
557 Returns the Laguerre series `c` raised to the power `pow`. The
558 argument `c` is a sequence of coefficients ordered from low to high.
559 i.e., [1,2,3] is the series ``P_0 + 2*P_1 + 3*P_2.``
561 Parameters
562 ----------
563 c : array_like
564 1-D array of Laguerre series coefficients ordered from low to
565 high.
566 pow : integer
567 Power to which the series will be raised
568 maxpower : integer, optional
569 Maximum power allowed. This is mainly to limit growth of the series
570 to unmanageable size. Default is 16
572 Returns
573 -------
574 coef : ndarray
575 Laguerre series of power.
577 See Also
578 --------
579 lagadd, lagsub, lagmulx, lagmul, lagdiv
581 Examples
582 --------
583 >>> from numpy.polynomial.laguerre import lagpow
584 >>> lagpow([1, 2, 3], 2)
585 array([ 14., -16., 56., -72., 54.])
587 """
588 return pu._pow(lagmul, c, pow, maxpower)
591def lagder(c, m=1, scl=1, axis=0):
592 """
593 Differentiate a Laguerre series.
595 Returns the Laguerre series coefficients `c` differentiated `m` times
596 along `axis`. At each iteration the result is multiplied by `scl` (the
597 scaling factor is for use in a linear change of variable). The argument
598 `c` is an array of coefficients from low to high degree along each
599 axis, e.g., [1,2,3] represents the series ``1*L_0 + 2*L_1 + 3*L_2``
600 while [[1,2],[1,2]] represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) +
601 2*L_0(x)*L_1(y) + 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is
602 ``y``.
604 Parameters
605 ----------
606 c : array_like
607 Array of Laguerre series coefficients. If `c` is multidimensional
608 the different axis correspond to different variables with the
609 degree in each axis given by the corresponding index.
610 m : int, optional
611 Number of derivatives taken, must be non-negative. (Default: 1)
612 scl : scalar, optional
613 Each differentiation is multiplied by `scl`. The end result is
614 multiplication by ``scl**m``. This is for use in a linear change of
615 variable. (Default: 1)
616 axis : int, optional
617 Axis over which the derivative is taken. (Default: 0).
619 .. versionadded:: 1.7.0
621 Returns
622 -------
623 der : ndarray
624 Laguerre series of the derivative.
626 See Also
627 --------
628 lagint
630 Notes
631 -----
632 In general, the result of differentiating a Laguerre series does not
633 resemble the same operation on a power series. Thus the result of this
634 function may be "unintuitive," albeit correct; see Examples section
635 below.
637 Examples
638 --------
639 >>> from numpy.polynomial.laguerre import lagder
640 >>> lagder([ 1., 1., 1., -3.])
641 array([1., 2., 3.])
642 >>> lagder([ 1., 0., 0., -4., 3.], m=2)
643 array([1., 2., 3.])
645 """
646 c = np.array(c, ndmin=1, copy=True)
647 if c.dtype.char in '?bBhHiIlLqQpP':
648 c = c.astype(np.double)
650 cnt = pu._deprecate_as_int(m, "the order of derivation")
651 iaxis = pu._deprecate_as_int(axis, "the axis")
652 if cnt < 0:
653 raise ValueError("The order of derivation must be non-negative")
654 iaxis = normalize_axis_index(iaxis, c.ndim)
656 if cnt == 0:
657 return c
659 c = np.moveaxis(c, iaxis, 0)
660 n = len(c)
661 if cnt >= n:
662 c = c[:1]*0
663 else:
664 for i in range(cnt):
665 n = n - 1
666 c *= scl
667 der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
668 for j in range(n, 1, -1):
669 der[j - 1] = -c[j]
670 c[j - 1] += c[j]
671 der[0] = -c[1]
672 c = der
673 c = np.moveaxis(c, 0, iaxis)
674 return c
677def lagint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
678 """
679 Integrate a Laguerre series.
681 Returns the Laguerre series coefficients `c` integrated `m` times from
682 `lbnd` along `axis`. At each iteration the resulting series is
683 **multiplied** by `scl` and an integration constant, `k`, is added.
684 The scaling factor is for use in a linear change of variable. ("Buyer
685 beware": note that, depending on what one is doing, one may want `scl`
686 to be the reciprocal of what one might expect; for more information,
687 see the Notes section below.) The argument `c` is an array of
688 coefficients from low to high degree along each axis, e.g., [1,2,3]
689 represents the series ``L_0 + 2*L_1 + 3*L_2`` while [[1,2],[1,2]]
690 represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) + 2*L_0(x)*L_1(y) +
691 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
694 Parameters
695 ----------
696 c : array_like
697 Array of Laguerre series coefficients. If `c` is multidimensional
698 the different axis correspond to different variables with the
699 degree in each axis given by the corresponding index.
700 m : int, optional
701 Order of integration, must be positive. (Default: 1)
702 k : {[], list, scalar}, optional
703 Integration constant(s). The value of the first integral at
704 ``lbnd`` is the first value in the list, the value of the second
705 integral at ``lbnd`` is the second value, etc. If ``k == []`` (the
706 default), all constants are set to zero. If ``m == 1``, a single
707 scalar can be given instead of a list.
708 lbnd : scalar, optional
709 The lower bound of the integral. (Default: 0)
710 scl : scalar, optional
711 Following each integration the result is *multiplied* by `scl`
712 before the integration constant is added. (Default: 1)
713 axis : int, optional
714 Axis over which the integral is taken. (Default: 0).
716 .. versionadded:: 1.7.0
718 Returns
719 -------
720 S : ndarray
721 Laguerre series coefficients of the integral.
723 Raises
724 ------
725 ValueError
726 If ``m < 0``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or
727 ``np.ndim(scl) != 0``.
729 See Also
730 --------
731 lagder
733 Notes
734 -----
735 Note that the result of each integration is *multiplied* by `scl`.
736 Why is this important to note? Say one is making a linear change of
737 variable :math:`u = ax + b` in an integral relative to `x`. Then
738 :math:`dx = du/a`, so one will need to set `scl` equal to
739 :math:`1/a` - perhaps not what one would have first thought.
741 Also note that, in general, the result of integrating a C-series needs
742 to be "reprojected" onto the C-series basis set. Thus, typically,
743 the result of this function is "unintuitive," albeit correct; see
744 Examples section below.
746 Examples
747 --------
748 >>> from numpy.polynomial.laguerre import lagint
749 >>> lagint([1,2,3])
750 array([ 1., 1., 1., -3.])
751 >>> lagint([1,2,3], m=2)
752 array([ 1., 0., 0., -4., 3.])
753 >>> lagint([1,2,3], k=1)
754 array([ 2., 1., 1., -3.])
755 >>> lagint([1,2,3], lbnd=-1)
756 array([11.5, 1. , 1. , -3. ])
757 >>> lagint([1,2], m=2, k=[1,2], lbnd=-1)
758 array([ 11.16666667, -5. , -3. , 2. ]) # may vary
760 """
761 c = np.array(c, ndmin=1, copy=True)
762 if c.dtype.char in '?bBhHiIlLqQpP':
763 c = c.astype(np.double)
764 if not np.iterable(k):
765 k = [k]
766 cnt = pu._deprecate_as_int(m, "the order of integration")
767 iaxis = pu._deprecate_as_int(axis, "the axis")
768 if cnt < 0:
769 raise ValueError("The order of integration must be non-negative")
770 if len(k) > cnt:
771 raise ValueError("Too many integration constants")
772 if np.ndim(lbnd) != 0:
773 raise ValueError("lbnd must be a scalar.")
774 if np.ndim(scl) != 0:
775 raise ValueError("scl must be a scalar.")
776 iaxis = normalize_axis_index(iaxis, c.ndim)
778 if cnt == 0:
779 return c
781 c = np.moveaxis(c, iaxis, 0)
782 k = list(k) + [0]*(cnt - len(k))
783 for i in range(cnt):
784 n = len(c)
785 c *= scl
786 if n == 1 and np.all(c[0] == 0):
787 c[0] += k[i]
788 else:
789 tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
790 tmp[0] = c[0]
791 tmp[1] = -c[0]
792 for j in range(1, n):
793 tmp[j] += c[j]
794 tmp[j + 1] = -c[j]
795 tmp[0] += k[i] - lagval(lbnd, tmp)
796 c = tmp
797 c = np.moveaxis(c, 0, iaxis)
798 return c
801def lagval(x, c, tensor=True):
802 """
803 Evaluate a Laguerre series at points x.
805 If `c` is of length `n + 1`, this function returns the value:
807 .. math:: p(x) = c_0 * L_0(x) + c_1 * L_1(x) + ... + c_n * L_n(x)
809 The parameter `x` is converted to an array only if it is a tuple or a
810 list, otherwise it is treated as a scalar. In either case, either `x`
811 or its elements must support multiplication and addition both with
812 themselves and with the elements of `c`.
814 If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If
815 `c` is multidimensional, then the shape of the result depends on the
816 value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
817 x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
818 scalars have shape (,).
820 Trailing zeros in the coefficients will be used in the evaluation, so
821 they should be avoided if efficiency is a concern.
823 Parameters
824 ----------
825 x : array_like, compatible object
826 If `x` is a list or tuple, it is converted to an ndarray, otherwise
827 it is left unchanged and treated as a scalar. In either case, `x`
828 or its elements must support addition and multiplication with
829 themselves and with the elements of `c`.
830 c : array_like
831 Array of coefficients ordered so that the coefficients for terms of
832 degree n are contained in c[n]. If `c` is multidimensional the
833 remaining indices enumerate multiple polynomials. In the two
834 dimensional case the coefficients may be thought of as stored in
835 the columns of `c`.
836 tensor : boolean, optional
837 If True, the shape of the coefficient array is extended with ones
838 on the right, one for each dimension of `x`. Scalars have dimension 0
839 for this action. The result is that every column of coefficients in
840 `c` is evaluated for every element of `x`. If False, `x` is broadcast
841 over the columns of `c` for the evaluation. This keyword is useful
842 when `c` is multidimensional. The default value is True.
844 .. versionadded:: 1.7.0
846 Returns
847 -------
848 values : ndarray, algebra_like
849 The shape of the return value is described above.
851 See Also
852 --------
853 lagval2d, laggrid2d, lagval3d, laggrid3d
855 Notes
856 -----
857 The evaluation uses Clenshaw recursion, aka synthetic division.
859 Examples
860 --------
861 >>> from numpy.polynomial.laguerre import lagval
862 >>> coef = [1,2,3]
863 >>> lagval(1, coef)
864 -0.5
865 >>> lagval([[1,2],[3,4]], coef)
866 array([[-0.5, -4. ],
867 [-4.5, -2. ]])
869 """
870 c = np.array(c, ndmin=1, copy=False)
871 if c.dtype.char in '?bBhHiIlLqQpP':
872 c = c.astype(np.double)
873 if isinstance(x, (tuple, list)):
874 x = np.asarray(x)
875 if isinstance(x, np.ndarray) and tensor:
876 c = c.reshape(c.shape + (1,)*x.ndim)
878 if len(c) == 1:
879 c0 = c[0]
880 c1 = 0
881 elif len(c) == 2:
882 c0 = c[0]
883 c1 = c[1]
884 else:
885 nd = len(c)
886 c0 = c[-2]
887 c1 = c[-1]
888 for i in range(3, len(c) + 1):
889 tmp = c0
890 nd = nd - 1
891 c0 = c[-i] - (c1*(nd - 1))/nd
892 c1 = tmp + (c1*((2*nd - 1) - x))/nd
893 return c0 + c1*(1 - x)
896def lagval2d(x, y, c):
897 """
898 Evaluate a 2-D Laguerre series at points (x, y).
900 This function returns the values:
902 .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * L_i(x) * L_j(y)
904 The parameters `x` and `y` are converted to arrays only if they are
905 tuples or a lists, otherwise they are treated as a scalars and they
906 must have the same shape after conversion. In either case, either `x`
907 and `y` or their elements must support multiplication and addition both
908 with themselves and with the elements of `c`.
910 If `c` is a 1-D array a one is implicitly appended to its shape to make
911 it 2-D. The shape of the result will be c.shape[2:] + x.shape.
913 Parameters
914 ----------
915 x, y : array_like, compatible objects
916 The two dimensional series is evaluated at the points `(x, y)`,
917 where `x` and `y` must have the same shape. If `x` or `y` is a list
918 or tuple, it is first converted to an ndarray, otherwise it is left
919 unchanged and if it isn't an ndarray it is treated as a scalar.
920 c : array_like
921 Array of coefficients ordered so that the coefficient of the term
922 of multi-degree i,j is contained in ``c[i,j]``. If `c` has
923 dimension greater than two the remaining indices enumerate multiple
924 sets of coefficients.
926 Returns
927 -------
928 values : ndarray, compatible object
929 The values of the two dimensional polynomial at points formed with
930 pairs of corresponding values from `x` and `y`.
932 See Also
933 --------
934 lagval, laggrid2d, lagval3d, laggrid3d
936 Notes
937 -----
939 .. versionadded:: 1.7.0
941 """
942 return pu._valnd(lagval, c, x, y)
945def laggrid2d(x, y, c):
946 """
947 Evaluate a 2-D Laguerre series on the Cartesian product of x and y.
949 This function returns the values:
951 .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * L_i(a) * L_j(b)
953 where the points `(a, b)` consist of all pairs formed by taking
954 `a` from `x` and `b` from `y`. The resulting points form a grid with
955 `x` in the first dimension and `y` in the second.
957 The parameters `x` and `y` are converted to arrays only if they are
958 tuples or a lists, otherwise they are treated as a scalars. In either
959 case, either `x` and `y` or their elements must support multiplication
960 and addition both with themselves and with the elements of `c`.
962 If `c` has fewer than two dimensions, ones are implicitly appended to
963 its shape to make it 2-D. The shape of the result will be c.shape[2:] +
964 x.shape + y.shape.
966 Parameters
967 ----------
968 x, y : array_like, compatible objects
969 The two dimensional series is evaluated at the points in the
970 Cartesian product of `x` and `y`. If `x` or `y` is a list or
971 tuple, it is first converted to an ndarray, otherwise it is left
972 unchanged and, if it isn't an ndarray, it is treated as a scalar.
973 c : array_like
974 Array of coefficients ordered so that the coefficient of the term of
975 multi-degree i,j is contained in `c[i,j]`. If `c` has dimension
976 greater than two the remaining indices enumerate multiple sets of
977 coefficients.
979 Returns
980 -------
981 values : ndarray, compatible object
982 The values of the two dimensional Chebyshev series at points in the
983 Cartesian product of `x` and `y`.
985 See Also
986 --------
987 lagval, lagval2d, lagval3d, laggrid3d
989 Notes
990 -----
992 .. versionadded:: 1.7.0
994 """
995 return pu._gridnd(lagval, c, x, y)
998def lagval3d(x, y, z, c):
999 """
1000 Evaluate a 3-D Laguerre series at points (x, y, z).
1002 This function returns the values:
1004 .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * L_i(x) * L_j(y) * L_k(z)
1006 The parameters `x`, `y`, and `z` are converted to arrays only if
1007 they are tuples or a lists, otherwise they are treated as a scalars and
1008 they must have the same shape after conversion. In either case, either
1009 `x`, `y`, and `z` or their elements must support multiplication and
1010 addition both with themselves and with the elements of `c`.
1012 If `c` has fewer than 3 dimensions, ones are implicitly appended to its
1013 shape to make it 3-D. The shape of the result will be c.shape[3:] +
1014 x.shape.
1016 Parameters
1017 ----------
1018 x, y, z : array_like, compatible object
1019 The three dimensional series is evaluated at the points
1020 `(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If
1021 any of `x`, `y`, or `z` is a list or tuple, it is first converted
1022 to an ndarray, otherwise it is left unchanged and if it isn't an
1023 ndarray it is treated as a scalar.
1024 c : array_like
1025 Array of coefficients ordered so that the coefficient of the term of
1026 multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
1027 greater than 3 the remaining indices enumerate multiple sets of
1028 coefficients.
1030 Returns
1031 -------
1032 values : ndarray, compatible object
1033 The values of the multidimensional polynomial on points formed with
1034 triples of corresponding values from `x`, `y`, and `z`.
1036 See Also
1037 --------
1038 lagval, lagval2d, laggrid2d, laggrid3d
1040 Notes
1041 -----
1043 .. versionadded:: 1.7.0
1045 """
1046 return pu._valnd(lagval, c, x, y, z)
1049def laggrid3d(x, y, z, c):
1050 """
1051 Evaluate a 3-D Laguerre series on the Cartesian product of x, y, and z.
1053 This function returns the values:
1055 .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * L_i(a) * L_j(b) * L_k(c)
1057 where the points `(a, b, c)` consist of all triples formed by taking
1058 `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
1059 a grid with `x` in the first dimension, `y` in the second, and `z` in
1060 the third.
1062 The parameters `x`, `y`, and `z` are converted to arrays only if they
1063 are tuples or a lists, otherwise they are treated as a scalars. In
1064 either case, either `x`, `y`, and `z` or their elements must support
1065 multiplication and addition both with themselves and with the elements
1066 of `c`.
1068 If `c` has fewer than three dimensions, ones are implicitly appended to
1069 its shape to make it 3-D. The shape of the result will be c.shape[3:] +
1070 x.shape + y.shape + z.shape.
1072 Parameters
1073 ----------
1074 x, y, z : array_like, compatible objects
1075 The three dimensional series is evaluated at the points in the
1076 Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a
1077 list or tuple, it is first converted to an ndarray, otherwise it is
1078 left unchanged and, if it isn't an ndarray, it is treated as a
1079 scalar.
1080 c : array_like
1081 Array of coefficients ordered so that the coefficients for terms of
1082 degree i,j are contained in ``c[i,j]``. If `c` has dimension
1083 greater than two the remaining indices enumerate multiple sets of
1084 coefficients.
1086 Returns
1087 -------
1088 values : ndarray, compatible object
1089 The values of the two dimensional polynomial at points in the Cartesian
1090 product of `x` and `y`.
1092 See Also
1093 --------
1094 lagval, lagval2d, laggrid2d, lagval3d
1096 Notes
1097 -----
1099 .. versionadded:: 1.7.0
1101 """
1102 return pu._gridnd(lagval, c, x, y, z)
1105def lagvander(x, deg):
1106 """Pseudo-Vandermonde matrix of given degree.
1108 Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
1109 `x`. The pseudo-Vandermonde matrix is defined by
1111 .. math:: V[..., i] = L_i(x)
1113 where `0 <= i <= deg`. The leading indices of `V` index the elements of
1114 `x` and the last index is the degree of the Laguerre polynomial.
1116 If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
1117 array ``V = lagvander(x, n)``, then ``np.dot(V, c)`` and
1118 ``lagval(x, c)`` are the same up to roundoff. This equivalence is
1119 useful both for least squares fitting and for the evaluation of a large
1120 number of Laguerre series of the same degree and sample points.
1122 Parameters
1123 ----------
1124 x : array_like
1125 Array of points. The dtype is converted to float64 or complex128
1126 depending on whether any of the elements are complex. If `x` is
1127 scalar it is converted to a 1-D array.
1128 deg : int
1129 Degree of the resulting matrix.
1131 Returns
1132 -------
1133 vander : ndarray
1134 The pseudo-Vandermonde matrix. The shape of the returned matrix is
1135 ``x.shape + (deg + 1,)``, where The last index is the degree of the
1136 corresponding Laguerre polynomial. The dtype will be the same as
1137 the converted `x`.
1139 Examples
1140 --------
1141 >>> from numpy.polynomial.laguerre import lagvander
1142 >>> x = np.array([0, 1, 2])
1143 >>> lagvander(x, 3)
1144 array([[ 1. , 1. , 1. , 1. ],
1145 [ 1. , 0. , -0.5 , -0.66666667],
1146 [ 1. , -1. , -1. , -0.33333333]])
1148 """
1149 ideg = pu._deprecate_as_int(deg, "deg")
1150 if ideg < 0:
1151 raise ValueError("deg must be non-negative")
1153 x = np.array(x, copy=False, ndmin=1) + 0.0
1154 dims = (ideg + 1,) + x.shape
1155 dtyp = x.dtype
1156 v = np.empty(dims, dtype=dtyp)
1157 v[0] = x*0 + 1
1158 if ideg > 0:
1159 v[1] = 1 - x
1160 for i in range(2, ideg + 1):
1161 v[i] = (v[i-1]*(2*i - 1 - x) - v[i-2]*(i - 1))/i
1162 return np.moveaxis(v, 0, -1)
1165def lagvander2d(x, y, deg):
1166 """Pseudo-Vandermonde matrix of given degrees.
1168 Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
1169 points `(x, y)`. The pseudo-Vandermonde matrix is defined by
1171 .. math:: V[..., (deg[1] + 1)*i + j] = L_i(x) * L_j(y),
1173 where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
1174 `V` index the points `(x, y)` and the last index encodes the degrees of
1175 the Laguerre polynomials.
1177 If ``V = lagvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
1178 correspond to the elements of a 2-D coefficient array `c` of shape
1179 (xdeg + 1, ydeg + 1) in the order
1181 .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
1183 and ``np.dot(V, c.flat)`` and ``lagval2d(x, y, c)`` will be the same
1184 up to roundoff. This equivalence is useful both for least squares
1185 fitting and for the evaluation of a large number of 2-D Laguerre
1186 series of the same degrees and sample points.
1188 Parameters
1189 ----------
1190 x, y : array_like
1191 Arrays of point coordinates, all of the same shape. The dtypes
1192 will be converted to either float64 or complex128 depending on
1193 whether any of the elements are complex. Scalars are converted to
1194 1-D arrays.
1195 deg : list of ints
1196 List of maximum degrees of the form [x_deg, y_deg].
1198 Returns
1199 -------
1200 vander2d : ndarray
1201 The shape of the returned matrix is ``x.shape + (order,)``, where
1202 :math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same
1203 as the converted `x` and `y`.
1205 See Also
1206 --------
1207 lagvander, lagvander3d, lagval2d, lagval3d
1209 Notes
1210 -----
1212 .. versionadded:: 1.7.0
1214 """
1215 return pu._vander_nd_flat((lagvander, lagvander), (x, y), deg)
1218def lagvander3d(x, y, z, deg):
1219 """Pseudo-Vandermonde matrix of given degrees.
1221 Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
1222 points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
1223 then The pseudo-Vandermonde matrix is defined by
1225 .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = L_i(x)*L_j(y)*L_k(z),
1227 where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading
1228 indices of `V` index the points `(x, y, z)` and the last index encodes
1229 the degrees of the Laguerre polynomials.
1231 If ``V = lagvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
1232 of `V` correspond to the elements of a 3-D coefficient array `c` of
1233 shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
1235 .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
1237 and ``np.dot(V, c.flat)`` and ``lagval3d(x, y, z, c)`` will be the
1238 same up to roundoff. This equivalence is useful both for least squares
1239 fitting and for the evaluation of a large number of 3-D Laguerre
1240 series of the same degrees and sample points.
1242 Parameters
1243 ----------
1244 x, y, z : array_like
1245 Arrays of point coordinates, all of the same shape. The dtypes will
1246 be converted to either float64 or complex128 depending on whether
1247 any of the elements are complex. Scalars are converted to 1-D
1248 arrays.
1249 deg : list of ints
1250 List of maximum degrees of the form [x_deg, y_deg, z_deg].
1252 Returns
1253 -------
1254 vander3d : ndarray
1255 The shape of the returned matrix is ``x.shape + (order,)``, where
1256 :math:`order = (deg[0]+1)*(deg[1]+1)*(deg[2]+1)`. The dtype will
1257 be the same as the converted `x`, `y`, and `z`.
1259 See Also
1260 --------
1261 lagvander, lagvander3d, lagval2d, lagval3d
1263 Notes
1264 -----
1266 .. versionadded:: 1.7.0
1268 """
1269 return pu._vander_nd_flat((lagvander, lagvander, lagvander), (x, y, z), deg)
1272def lagfit(x, y, deg, rcond=None, full=False, w=None):
1273 """
1274 Least squares fit of Laguerre series to data.
1276 Return the coefficients of a Laguerre series of degree `deg` that is the
1277 least squares fit to the data values `y` given at points `x`. If `y` is
1278 1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
1279 fits are done, one for each column of `y`, and the resulting
1280 coefficients are stored in the corresponding columns of a 2-D return.
1281 The fitted polynomial(s) are in the form
1283 .. math:: p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x),
1285 where `n` is `deg`.
1287 Parameters
1288 ----------
1289 x : array_like, shape (M,)
1290 x-coordinates of the M sample points ``(x[i], y[i])``.
1291 y : array_like, shape (M,) or (M, K)
1292 y-coordinates of the sample points. Several data sets of sample
1293 points sharing the same x-coordinates can be fitted at once by
1294 passing in a 2D-array that contains one dataset per column.
1295 deg : int or 1-D array_like
1296 Degree(s) of the fitting polynomials. If `deg` is a single integer
1297 all terms up to and including the `deg`'th term are included in the
1298 fit. For NumPy versions >= 1.11.0 a list of integers specifying the
1299 degrees of the terms to include may be used instead.
1300 rcond : float, optional
1301 Relative condition number of the fit. Singular values smaller than
1302 this relative to the largest singular value will be ignored. The
1303 default value is len(x)*eps, where eps is the relative precision of
1304 the float type, about 2e-16 in most cases.
1305 full : bool, optional
1306 Switch determining nature of return value. When it is False (the
1307 default) just the coefficients are returned, when True diagnostic
1308 information from the singular value decomposition is also returned.
1309 w : array_like, shape (`M`,), optional
1310 Weights. If not None, the weight ``w[i]`` applies to the unsquared
1311 residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
1312 chosen so that the errors of the products ``w[i]*y[i]`` all have the
1313 same variance. When using inverse-variance weighting, use
1314 ``w[i] = 1/sigma(y[i])``. The default value is None.
1316 Returns
1317 -------
1318 coef : ndarray, shape (M,) or (M, K)
1319 Laguerre coefficients ordered from low to high. If `y` was 2-D,
1320 the coefficients for the data in column k of `y` are in column
1321 `k`.
1323 [residuals, rank, singular_values, rcond] : list
1324 These values are only returned if ``full == True``
1326 - residuals -- sum of squared residuals of the least squares fit
1327 - rank -- the numerical rank of the scaled Vandermonde matrix
1328 - singular_values -- singular values of the scaled Vandermonde matrix
1329 - rcond -- value of `rcond`.
1331 For more details, see `numpy.linalg.lstsq`.
1333 Warns
1334 -----
1335 RankWarning
1336 The rank of the coefficient matrix in the least-squares fit is
1337 deficient. The warning is only raised if ``full == False``. The
1338 warnings can be turned off by
1340 >>> import warnings
1341 >>> warnings.simplefilter('ignore', np.RankWarning)
1343 See Also
1344 --------
1345 numpy.polynomial.polynomial.polyfit
1346 numpy.polynomial.legendre.legfit
1347 numpy.polynomial.chebyshev.chebfit
1348 numpy.polynomial.hermite.hermfit
1349 numpy.polynomial.hermite_e.hermefit
1350 lagval : Evaluates a Laguerre series.
1351 lagvander : pseudo Vandermonde matrix of Laguerre series.
1352 lagweight : Laguerre weight function.
1353 numpy.linalg.lstsq : Computes a least-squares fit from the matrix.
1354 scipy.interpolate.UnivariateSpline : Computes spline fits.
1356 Notes
1357 -----
1358 The solution is the coefficients of the Laguerre series `p` that
1359 minimizes the sum of the weighted squared errors
1361 .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
1363 where the :math:`w_j` are the weights. This problem is solved by
1364 setting up as the (typically) overdetermined matrix equation
1366 .. math:: V(x) * c = w * y,
1368 where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
1369 coefficients to be solved for, `w` are the weights, and `y` are the
1370 observed values. This equation is then solved using the singular value
1371 decomposition of `V`.
1373 If some of the singular values of `V` are so small that they are
1374 neglected, then a `RankWarning` will be issued. This means that the
1375 coefficient values may be poorly determined. Using a lower order fit
1376 will usually get rid of the warning. The `rcond` parameter can also be
1377 set to a value smaller than its default, but the resulting fit may be
1378 spurious and have large contributions from roundoff error.
1380 Fits using Laguerre series are probably most useful when the data can
1381 be approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the Laguerre
1382 weight. In that case the weight ``sqrt(w(x[i]))`` should be used
1383 together with data values ``y[i]/sqrt(w(x[i]))``. The weight function is
1384 available as `lagweight`.
1386 References
1387 ----------
1388 .. [1] Wikipedia, "Curve fitting",
1389 https://en.wikipedia.org/wiki/Curve_fitting
1391 Examples
1392 --------
1393 >>> from numpy.polynomial.laguerre import lagfit, lagval
1394 >>> x = np.linspace(0, 10)
1395 >>> err = np.random.randn(len(x))/10
1396 >>> y = lagval(x, [1, 2, 3]) + err
1397 >>> lagfit(x, y, 2)
1398 array([ 0.96971004, 2.00193749, 3.00288744]) # may vary
1400 """
1401 return pu._fit(lagvander, x, y, deg, rcond, full, w)
1404def lagcompanion(c):
1405 """
1406 Return the companion matrix of c.
1408 The usual companion matrix of the Laguerre polynomials is already
1409 symmetric when `c` is a basis Laguerre polynomial, so no scaling is
1410 applied.
1412 Parameters
1413 ----------
1414 c : array_like
1415 1-D array of Laguerre series coefficients ordered from low to high
1416 degree.
1418 Returns
1419 -------
1420 mat : ndarray
1421 Companion matrix of dimensions (deg, deg).
1423 Notes
1424 -----
1426 .. versionadded:: 1.7.0
1428 """
1429 # c is a trimmed copy
1430 [c] = pu.as_series([c])
1431 if len(c) < 2:
1432 raise ValueError('Series must have maximum degree of at least 1.')
1433 if len(c) == 2:
1434 return np.array([[1 + c[0]/c[1]]])
1436 n = len(c) - 1
1437 mat = np.zeros((n, n), dtype=c.dtype)
1438 top = mat.reshape(-1)[1::n+1]
1439 mid = mat.reshape(-1)[0::n+1]
1440 bot = mat.reshape(-1)[n::n+1]
1441 top[...] = -np.arange(1, n)
1442 mid[...] = 2.*np.arange(n) + 1.
1443 bot[...] = top
1444 mat[:, -1] += (c[:-1]/c[-1])*n
1445 return mat
1448def lagroots(c):
1449 """
1450 Compute the roots of a Laguerre series.
1452 Return the roots (a.k.a. "zeros") of the polynomial
1454 .. math:: p(x) = \\sum_i c[i] * L_i(x).
1456 Parameters
1457 ----------
1458 c : 1-D array_like
1459 1-D array of coefficients.
1461 Returns
1462 -------
1463 out : ndarray
1464 Array of the roots of the series. If all the roots are real,
1465 then `out` is also real, otherwise it is complex.
1467 See Also
1468 --------
1469 numpy.polynomial.polynomial.polyroots
1470 numpy.polynomial.legendre.legroots
1471 numpy.polynomial.chebyshev.chebroots
1472 numpy.polynomial.hermite.hermroots
1473 numpy.polynomial.hermite_e.hermeroots
1475 Notes
1476 -----
1477 The root estimates are obtained as the eigenvalues of the companion
1478 matrix, Roots far from the origin of the complex plane may have large
1479 errors due to the numerical instability of the series for such
1480 values. Roots with multiplicity greater than 1 will also show larger
1481 errors as the value of the series near such points is relatively
1482 insensitive to errors in the roots. Isolated roots near the origin can
1483 be improved by a few iterations of Newton's method.
1485 The Laguerre series basis polynomials aren't powers of `x` so the
1486 results of this function may seem unintuitive.
1488 Examples
1489 --------
1490 >>> from numpy.polynomial.laguerre import lagroots, lagfromroots
1491 >>> coef = lagfromroots([0, 1, 2])
1492 >>> coef
1493 array([ 2., -8., 12., -6.])
1494 >>> lagroots(coef)
1495 array([-4.4408921e-16, 1.0000000e+00, 2.0000000e+00])
1497 """
1498 # c is a trimmed copy
1499 [c] = pu.as_series([c])
1500 if len(c) <= 1:
1501 return np.array([], dtype=c.dtype)
1502 if len(c) == 2:
1503 return np.array([1 + c[0]/c[1]])
1505 # rotated companion matrix reduces error
1506 m = lagcompanion(c)[::-1,::-1]
1507 r = la.eigvals(m)
1508 r.sort()
1509 return r
1512def laggauss(deg):
1513 """
1514 Gauss-Laguerre quadrature.
1516 Computes the sample points and weights for Gauss-Laguerre quadrature.
1517 These sample points and weights will correctly integrate polynomials of
1518 degree :math:`2*deg - 1` or less over the interval :math:`[0, \\inf]`
1519 with the weight function :math:`f(x) = \\exp(-x)`.
1521 Parameters
1522 ----------
1523 deg : int
1524 Number of sample points and weights. It must be >= 1.
1526 Returns
1527 -------
1528 x : ndarray
1529 1-D ndarray containing the sample points.
1530 y : ndarray
1531 1-D ndarray containing the weights.
1533 Notes
1534 -----
1536 .. versionadded:: 1.7.0
1538 The results have only been tested up to degree 100 higher degrees may
1539 be problematic. The weights are determined by using the fact that
1541 .. math:: w_k = c / (L'_n(x_k) * L_{n-1}(x_k))
1543 where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
1544 is the k'th root of :math:`L_n`, and then scaling the results to get
1545 the right value when integrating 1.
1547 """
1548 ideg = pu._deprecate_as_int(deg, "deg")
1549 if ideg <= 0:
1550 raise ValueError("deg must be a positive integer")
1552 # first approximation of roots. We use the fact that the companion
1553 # matrix is symmetric in this case in order to obtain better zeros.
1554 c = np.array([0]*deg + [1])
1555 m = lagcompanion(c)
1556 x = la.eigvalsh(m)
1558 # improve roots by one application of Newton
1559 dy = lagval(x, c)
1560 df = lagval(x, lagder(c))
1561 x -= dy/df
1563 # compute the weights. We scale the factor to avoid possible numerical
1564 # overflow.
1565 fm = lagval(x, c[1:])
1566 fm /= np.abs(fm).max()
1567 df /= np.abs(df).max()
1568 w = 1/(fm * df)
1570 # scale w to get the right value, 1 in this case
1571 w /= w.sum()
1573 return x, w
1576def lagweight(x):
1577 """Weight function of the Laguerre polynomials.
1579 The weight function is :math:`exp(-x)` and the interval of integration
1580 is :math:`[0, \\inf]`. The Laguerre polynomials are orthogonal, but not
1581 normalized, with respect to this weight function.
1583 Parameters
1584 ----------
1585 x : array_like
1586 Values at which the weight function will be computed.
1588 Returns
1589 -------
1590 w : ndarray
1591 The weight function at `x`.
1593 Notes
1594 -----
1596 .. versionadded:: 1.7.0
1598 """
1599 w = np.exp(-x)
1600 return w
1602#
1603# Laguerre series class
1604#
1606class Laguerre(ABCPolyBase):
1607 """A Laguerre series class.
1609 The Laguerre class provides the standard Python numerical methods
1610 '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
1611 attributes and methods listed in the `ABCPolyBase` documentation.
1613 Parameters
1614 ----------
1615 coef : array_like
1616 Laguerre coefficients in order of increasing degree, i.e,
1617 ``(1, 2, 3)`` gives ``1*L_0(x) + 2*L_1(X) + 3*L_2(x)``.
1618 domain : (2,) array_like, optional
1619 Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
1620 to the interval ``[window[0], window[1]]`` by shifting and scaling.
1621 The default value is [0, 1].
1622 window : (2,) array_like, optional
1623 Window, see `domain` for its use. The default value is [0, 1].
1625 .. versionadded:: 1.6.0
1627 """
1628 # Virtual Functions
1629 _add = staticmethod(lagadd)
1630 _sub = staticmethod(lagsub)
1631 _mul = staticmethod(lagmul)
1632 _div = staticmethod(lagdiv)
1633 _pow = staticmethod(lagpow)
1634 _val = staticmethod(lagval)
1635 _int = staticmethod(lagint)
1636 _der = staticmethod(lagder)
1637 _fit = staticmethod(lagfit)
1638 _line = staticmethod(lagline)
1639 _roots = staticmethod(lagroots)
1640 _fromroots = staticmethod(lagfromroots)
1642 # Virtual properties
1643 domain = np.array(lagdomain)
1644 window = np.array(lagdomain)
1645 basis_name = 'L'