codekingpro/portable-devtools
114k
1"""
2===================================================================
3HermiteE Series, "Probabilists" (:mod:`numpy.polynomial.hermite_e`)
4===================================================================
5
6This module provides a number of objects (mostly functions) useful for
7dealing with Hermite_e series, including a `HermiteE` 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`).
11
12Classes
13-------
14.. autosummary::
15 :toctree: generated/
16
17 HermiteE
18
19Constants
20---------
21.. autosummary::
22 :toctree: generated/
23
24 hermedomain
25 hermezero
26 hermeone
27 hermex
28
29Arithmetic
30----------
31.. autosummary::
32 :toctree: generated/
33
34 hermeadd
35 hermesub
36 hermemulx
37 hermemul
38 hermediv
39 hermepow
40 hermeval
41 hermeval2d
42 hermeval3d
43 hermegrid2d
44 hermegrid3d
45
46Calculus
47--------
48.. autosummary::
49 :toctree: generated/
50
51 hermeder
52 hermeint
53
54Misc Functions
55--------------
56.. autosummary::
57 :toctree: generated/
58
59 hermefromroots
60 hermeroots
61 hermevander
62 hermevander2d
63 hermevander3d
64 hermegauss
65 hermeweight
66 hermecompanion
67 hermefit
68 hermetrim
69 hermeline
70 herme2poly
71 poly2herme
72
73See also
74--------
75`numpy.polynomial`
76
77"""
78import numpy as np
79
80from . import polyutils as pu
81from ._polybase import ABCPolyBase
82
83__all__ = [
84 'hermezero', 'hermeone', 'hermex', 'hermedomain', 'hermeline',
85 'hermeadd', 'hermesub', 'hermemulx', 'hermemul', 'hermediv',
86 'hermepow', 'hermeval', 'hermeder', 'hermeint', 'herme2poly',
87 'poly2herme', 'hermefromroots', 'hermevander', 'hermefit', 'hermetrim',
88 'hermeroots', 'HermiteE', 'hermeval2d', 'hermeval3d', 'hermegrid2d',
89 'hermegrid3d', 'hermevander2d', 'hermevander3d', 'hermecompanion',
90 'hermegauss', 'hermeweight']
91
92hermetrim = pu.trimcoef
93
94
95def poly2herme(pol):
96 """
97 poly2herme(pol)
98
99 Convert a polynomial to a Hermite series.
100
101 Convert an array representing the coefficients of a polynomial (relative
102 to the "standard" basis) ordered from lowest degree to highest, to an
103 array of the coefficients of the equivalent Hermite series, ordered
104 from lowest to highest degree.
105
106 Parameters
107 ----------
108 pol : array_like
109 1-D array containing the polynomial coefficients
110
111 Returns
112 -------
113 c : ndarray
114 1-D array containing the coefficients of the equivalent Hermite
115 series.
116
117 See Also
118 --------
119 herme2poly
120
121 Notes
122 -----
123 The easy way to do conversions between polynomial basis sets
124 is to use the convert method of a class instance.
125
126 Examples
127 --------
128 >>> import numpy as np
129 >>> from numpy.polynomial.hermite_e import poly2herme
130 >>> poly2herme(np.arange(4))
131 array([ 2., 10., 2., 3.])
132
133 """
134 [pol] = pu.as_series([pol])
135 deg = len(pol) - 1
136 res = 0
137 for i in range(deg, -1, -1):
138 res = hermeadd(hermemulx(res), pol[i])
139 return res
140
141
142def herme2poly(c):
143 """
144 Convert a Hermite series to a polynomial.
145
146 Convert an array representing the coefficients of a Hermite series,
147 ordered from lowest degree to highest, to an array of the coefficients
148 of the equivalent polynomial (relative to the "standard" basis) ordered
149 from lowest to highest degree.
150
151 Parameters
152 ----------
153 c : array_like
154 1-D array containing the Hermite series coefficients, ordered
155 from lowest order term to highest.
156
157 Returns
158 -------
159 pol : ndarray
160 1-D array containing the coefficients of the equivalent polynomial
161 (relative to the "standard" basis) ordered from lowest order term
162 to highest.
163
164 See Also
165 --------
166 poly2herme
167
168 Notes
169 -----
170 The easy way to do conversions between polynomial basis sets
171 is to use the convert method of a class instance.
172
173 Examples
174 --------
175 >>> from numpy.polynomial.hermite_e import herme2poly
176 >>> herme2poly([ 2., 10., 2., 3.])
177 array([0., 1., 2., 3.])
178
179 """
180 from .polynomial import polyadd, polymulx, polysub
181
182 [c] = pu.as_series([c])
183 n = len(c)
184 if n == 1:
185 return c
186 if n == 2:
187 return c
188 else:
189 c0 = c[-2]
190 c1 = c[-1]
191 # i is the current degree of c1
192 for i in range(n - 1, 1, -1):
193 tmp = c0
194 c0 = polysub(c[i - 2], c1 * (i - 1))
195 c1 = polyadd(tmp, polymulx(c1))
196 return polyadd(c0, polymulx(c1))
197
198
199#
200# These are constant arrays are of integer type so as to be compatible
201# with the widest range of other types, such as Decimal.
202#
203
204# Hermite
205hermedomain = np.array([-1., 1.])
206
207# Hermite coefficients representing zero.
208hermezero = np.array([0])
209
210# Hermite coefficients representing one.
211hermeone = np.array([1])
212
213# Hermite coefficients representing the identity x.
214hermex = np.array([0, 1])
215
216
217def hermeline(off, scl):
218 """
219 Hermite series whose graph is a straight line.
220
221 Parameters
222 ----------
223 off, scl : scalars
224 The specified line is given by ``off + scl*x``.
225
226 Returns
227 -------
228 y : ndarray
229 This module's representation of the Hermite series for
230 ``off + scl*x``.
231
232 See Also
233 --------
234 numpy.polynomial.polynomial.polyline
235 numpy.polynomial.chebyshev.chebline
236 numpy.polynomial.legendre.legline
237 numpy.polynomial.laguerre.lagline
238 numpy.polynomial.hermite.hermline
239
240 Examples
241 --------
242 >>> from numpy.polynomial.hermite_e import hermeline
243 >>> from numpy.polynomial.hermite_e import hermeline, hermeval
244 >>> hermeval(0,hermeline(3, 2))
245 3.0
246 >>> hermeval(1,hermeline(3, 2))
247 5.0
248
249 """
250 if scl != 0:
251 return np.array([off, scl])
252 else:
253 return np.array([off])
254
255
256def hermefromroots(roots):
257 """
258 Generate a HermiteE series with given roots.
259
260 The function returns the coefficients of the polynomial
261
262 .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
263
264 in HermiteE form, where the :math:`r_n` are the roots specified in `roots`.
265 If a zero has multiplicity n, then it must appear in `roots` n times.
266 For instance, if 2 is a root of multiplicity three and 3 is a root of
267 multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
268 roots can appear in any order.
269
270 If the returned coefficients are `c`, then
271
272 .. math:: p(x) = c_0 + c_1 * He_1(x) + ... + c_n * He_n(x)
273
274 The coefficient of the last term is not generally 1 for monic
275 polynomials in HermiteE form.
276
277 Parameters
278 ----------
279 roots : array_like
280 Sequence containing the roots.
281
282 Returns
283 -------
284 out : ndarray
285 1-D array of coefficients. If all roots are real then `out` is a
286 real array, if some of the roots are complex, then `out` is complex
287 even if all the coefficients in the result are real (see Examples
288 below).
289
290 See Also
291 --------
292 numpy.polynomial.polynomial.polyfromroots
293 numpy.polynomial.legendre.legfromroots
294 numpy.polynomial.laguerre.lagfromroots
295 numpy.polynomial.hermite.hermfromroots
296 numpy.polynomial.chebyshev.chebfromroots
297
298 Examples
299 --------
300 >>> from numpy.polynomial.hermite_e import hermefromroots, hermeval
301 >>> coef = hermefromroots((-1, 0, 1))
302 >>> hermeval((-1, 0, 1), coef)
303 array([0., 0., 0.])
304 >>> coef = hermefromroots((-1j, 1j))
305 >>> hermeval((-1j, 1j), coef)
306 array([0.+0.j, 0.+0.j])
307
308 """
309 return pu._fromroots(hermeline, hermemul, roots)
310
311
312def hermeadd(c1, c2):
313 """
314 Add one Hermite series to another.
315
316 Returns the sum of two Hermite series `c1` + `c2`. The arguments
317 are sequences of coefficients ordered from lowest order term to
318 highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
319
320 Parameters
321 ----------
322 c1, c2 : array_like
323 1-D arrays of Hermite series coefficients ordered from low to
324 high.
325
326 Returns
327 -------
328 out : ndarray
329 Array representing the Hermite series of their sum.
330
331 See Also
332 --------
333 hermesub, hermemulx, hermemul, hermediv, hermepow
334
335 Notes
336 -----
337 Unlike multiplication, division, etc., the sum of two Hermite series
338 is a Hermite series (without having to "reproject" the result onto
339 the basis set) so addition, just like that of "standard" polynomials,
340 is simply "component-wise."
341
342 Examples
343 --------
344 >>> from numpy.polynomial.hermite_e import hermeadd
345 >>> hermeadd([1, 2, 3], [1, 2, 3, 4])
346 array([2., 4., 6., 4.])
347
348 """
349 return pu._add(c1, c2)
350
351
352def hermesub(c1, c2):
353 """
354 Subtract one Hermite series from another.
355
356 Returns the difference of two Hermite series `c1` - `c2`. The
357 sequences of coefficients are from lowest order term to highest, i.e.,
358 [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
359
360 Parameters
361 ----------
362 c1, c2 : array_like
363 1-D arrays of Hermite series coefficients ordered from low to
364 high.
365
366 Returns
367 -------
368 out : ndarray
369 Of Hermite series coefficients representing their difference.
370
371 See Also
372 --------
373 hermeadd, hermemulx, hermemul, hermediv, hermepow
374
375 Notes
376 -----
377 Unlike multiplication, division, etc., the difference of two Hermite
378 series is a Hermite series (without having to "reproject" the result
379 onto the basis set) so subtraction, just like that of "standard"
380 polynomials, is simply "component-wise."
381
382 Examples
383 --------
384 >>> from numpy.polynomial.hermite_e import hermesub
385 >>> hermesub([1, 2, 3, 4], [1, 2, 3])
386 array([0., 0., 0., 4.])
387
388 """
389 return pu._sub(c1, c2)
390
391
392def hermemulx(c):
393 """Multiply a Hermite series by x.
394
395 Multiply the Hermite series `c` by x, where x is the independent
396 variable.
397
398
399 Parameters
400 ----------
401 c : array_like
402 1-D array of Hermite series coefficients ordered from low to
403 high.
404
405 Returns
406 -------
407 out : ndarray
408 Array representing the result of the multiplication.
409
410 See Also
411 --------
412 hermeadd, hermesub, hermemul, hermediv, hermepow
413
414 Notes
415 -----
416 The multiplication uses the recursion relationship for Hermite
417 polynomials in the form
418
419 .. math::
420
421 xP_i(x) = (P_{i + 1}(x) + iP_{i - 1}(x)))
422
423 Examples
424 --------
425 >>> from numpy.polynomial.hermite_e import hermemulx
426 >>> hermemulx([1, 2, 3])
427 array([2., 7., 2., 3.])
428
429 """
430 # c is a trimmed copy
431 [c] = pu.as_series([c])
432 # The zero series needs special treatment
433 if len(c) == 1 and c[0] == 0:
434 return c
435
436 prd = np.empty(len(c) + 1, dtype=c.dtype)
437 prd[0] = c[0] * 0
438 prd[1] = c[0]
439 for i in range(1, len(c)):
440 prd[i + 1] = c[i]
441 prd[i - 1] += c[i] * i
442 return prd
443
444
445def hermemul(c1, c2):
446 """
447 Multiply one Hermite series by another.
448
449 Returns the product of two Hermite series `c1` * `c2`. The arguments
450 are sequences of coefficients, from lowest order "term" to highest,
451 e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
452
453 Parameters
454 ----------
455 c1, c2 : array_like
456 1-D arrays of Hermite series coefficients ordered from low to
457 high.
458
459 Returns
460 -------
461 out : ndarray
462 Of Hermite series coefficients representing their product.
463
464 See Also
465 --------
466 hermeadd, hermesub, hermemulx, hermediv, hermepow
467
468 Notes
469 -----
470 In general, the (polynomial) product of two C-series results in terms
471 that are not in the Hermite polynomial basis set. Thus, to express
472 the product as a Hermite series, it is necessary to "reproject" the
473 product onto said basis set, which may produce "unintuitive" (but
474 correct) results; see Examples section below.
475
476 Examples
477 --------
478 >>> from numpy.polynomial.hermite_e import hermemul
479 >>> hermemul([1, 2, 3], [0, 1, 2])
480 array([14., 15., 28., 7., 6.])
481
482 """
483 # s1, s2 are trimmed copies
484 [c1, c2] = pu.as_series([c1, c2])
485
486 if len(c1) > len(c2):
487 c = c2
488 xs = c1
489 else:
490 c = c1
491 xs = c2
492
493 if len(c) == 1:
494 c0 = c[0] * xs
495 c1 = 0
496 elif len(c) == 2:
497 c0 = c[0] * xs
498 c1 = c[1] * xs
499 else:
500 nd = len(c)
501 c0 = c[-2] * xs
502 c1 = c[-1] * xs
503 for i in range(3, len(c) + 1):
504 tmp = c0
505 nd = nd - 1
506 c0 = hermesub(c[-i] * xs, c1 * (nd - 1))
507 c1 = hermeadd(tmp, hermemulx(c1))
508 return hermeadd(c0, hermemulx(c1))
509
510
511def hermediv(c1, c2):
512 """
513 Divide one Hermite series by another.
514
515 Returns the quotient-with-remainder of two Hermite series
516 `c1` / `c2`. The arguments are sequences of coefficients from lowest
517 order "term" to highest, e.g., [1,2,3] represents the series
518 ``P_0 + 2*P_1 + 3*P_2``.
519
520 Parameters
521 ----------
522 c1, c2 : array_like
523 1-D arrays of Hermite series coefficients ordered from low to
524 high.
525
526 Returns
527 -------
528 [quo, rem] : ndarrays
529 Of Hermite series coefficients representing the quotient and
530 remainder.
531
532 See Also
533 --------
534 hermeadd, hermesub, hermemulx, hermemul, hermepow
535
536 Notes
537 -----
538 In general, the (polynomial) division of one Hermite series by another
539 results in quotient and remainder terms that are not in the Hermite
540 polynomial basis set. Thus, to express these results as a Hermite
541 series, it is necessary to "reproject" the results onto the Hermite
542 basis set, which may produce "unintuitive" (but correct) results; see
543 Examples section below.
544
545 Examples
546 --------
547 >>> from numpy.polynomial.hermite_e import hermediv
548 >>> hermediv([ 14., 15., 28., 7., 6.], [0, 1, 2])
549 (array([1., 2., 3.]), array([0.]))
550 >>> hermediv([ 15., 17., 28., 7., 6.], [0, 1, 2])
551 (array([1., 2., 3.]), array([1., 2.]))
552
553 """
554 return pu._div(hermemul, c1, c2)
555
556
557def hermepow(c, pow, maxpower=16):
558 """Raise a Hermite series to a power.
559
560 Returns the Hermite series `c` raised to the power `pow`. The
561 argument `c` is a sequence of coefficients ordered from low to high.
562 i.e., [1,2,3] is the series ``P_0 + 2*P_1 + 3*P_2.``
563
564 Parameters
565 ----------
566 c : array_like
567 1-D array of Hermite series coefficients ordered from low to
568 high.
569 pow : integer
570 Power to which the series will be raised
571 maxpower : integer, optional
572 Maximum power allowed. This is mainly to limit growth of the series
573 to unmanageable size. Default is 16
574
575 Returns
576 -------
577 coef : ndarray
578 Hermite series of power.
579
580 See Also
581 --------
582 hermeadd, hermesub, hermemulx, hermemul, hermediv
583
584 Examples
585 --------
586 >>> from numpy.polynomial.hermite_e import hermepow
587 >>> hermepow([1, 2, 3], 2)
588 array([23., 28., 46., 12., 9.])
589
590 """
591 return pu._pow(hermemul, c, pow, maxpower)
592
593
594def hermeder(c, m=1, scl=1, axis=0):
595 """
596 Differentiate a Hermite_e series.
597
598 Returns the series coefficients `c` differentiated `m` times along
599 `axis`. At each iteration the result is multiplied by `scl` (the
600 scaling factor is for use in a linear change of variable). The argument
601 `c` is an array of coefficients from low to high degree along each
602 axis, e.g., [1,2,3] represents the series ``1*He_0 + 2*He_1 + 3*He_2``
603 while [[1,2],[1,2]] represents ``1*He_0(x)*He_0(y) + 1*He_1(x)*He_0(y)
604 + 2*He_0(x)*He_1(y) + 2*He_1(x)*He_1(y)`` if axis=0 is ``x`` and axis=1
605 is ``y``.
606
607 Parameters
608 ----------
609 c : array_like
610 Array of Hermite_e series coefficients. If `c` is multidimensional
611 the different axis correspond to different variables with the
612 degree in each axis given by the corresponding index.
613 m : int, optional
614 Number of derivatives taken, must be non-negative. (Default: 1)
615 scl : scalar, optional
616 Each differentiation is multiplied by `scl`. The end result is
617 multiplication by ``scl**m``. This is for use in a linear change of
618 variable. (Default: 1)
619 axis : int, optional
620 Axis over which the derivative is taken. (Default: 0).
621
622 Returns
623 -------
624 der : ndarray
625 Hermite series of the derivative.
626
627 See Also
628 --------
629 hermeint
630
631 Notes
632 -----
633 In general, the result of differentiating a Hermite series does not
634 resemble the same operation on a power series. Thus the result of this
635 function may be "unintuitive," albeit correct; see Examples section
636 below.
637
638 Examples
639 --------
640 >>> from numpy.polynomial.hermite_e import hermeder
641 >>> hermeder([ 1., 1., 1., 1.])
642 array([1., 2., 3.])
643 >>> hermeder([-0.25, 1., 1./2., 1./3., 1./4 ], m=2)
644 array([1., 2., 3.])
645
646 """
647 c = np.array(c, ndmin=1, copy=True)
648 if c.dtype.char in '?bBhHiIlLqQpP':
649 c = c.astype(np.double)
650 cnt = pu._as_int(m, "the order of derivation")
651 iaxis = pu._as_int(axis, "the axis")
652 if cnt < 0:
653 raise ValueError("The order of derivation must be non-negative")
654 iaxis = np.lib.array_utils.normalize_axis_index(iaxis, c.ndim)
655
656 if cnt == 0:
657 return c
658
659 c = np.moveaxis(c, iaxis, 0)
660 n = len(c)
661 if cnt >= n:
662 return 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, 0, -1):
669 der[j - 1] = j * c[j]
670 c = der
671 c = np.moveaxis(c, 0, iaxis)
672 return c
673
674
675def hermeint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
676 """
677 Integrate a Hermite_e series.
678
679 Returns the Hermite_e series coefficients `c` integrated `m` times from
680 `lbnd` along `axis`. At each iteration the resulting series is
681 **multiplied** by `scl` and an integration constant, `k`, is added.
682 The scaling factor is for use in a linear change of variable. ("Buyer
683 beware": note that, depending on what one is doing, one may want `scl`
684 to be the reciprocal of what one might expect; for more information,
685 see the Notes section below.) The argument `c` is an array of
686 coefficients from low to high degree along each axis, e.g., [1,2,3]
687 represents the series ``H_0 + 2*H_1 + 3*H_2`` while [[1,2],[1,2]]
688 represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) + 2*H_0(x)*H_1(y) +
689 2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
690
691 Parameters
692 ----------
693 c : array_like
694 Array of Hermite_e series coefficients. If c is multidimensional
695 the different axis correspond to different variables with the
696 degree in each axis given by the corresponding index.
697 m : int, optional
698 Order of integration, must be positive. (Default: 1)
699 k : {[], list, scalar}, optional
700 Integration constant(s). The value of the first integral at
701 ``lbnd`` is the first value in the list, the value of the second
702 integral at ``lbnd`` is the second value, etc. If ``k == []`` (the
703 default), all constants are set to zero. If ``m == 1``, a single
704 scalar can be given instead of a list.
705 lbnd : scalar, optional
706 The lower bound of the integral. (Default: 0)
707 scl : scalar, optional
708 Following each integration the result is *multiplied* by `scl`
709 before the integration constant is added. (Default: 1)
710 axis : int, optional
711 Axis over which the integral is taken. (Default: 0).
712
713 Returns
714 -------
715 S : ndarray
716 Hermite_e series coefficients of the integral.
717
718 Raises
719 ------
720 ValueError
721 If ``m < 0``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or
722 ``np.ndim(scl) != 0``.
723
724 See Also
725 --------
726 hermeder
727
728 Notes
729 -----
730 Note that the result of each integration is *multiplied* by `scl`.
731 Why is this important to note? Say one is making a linear change of
732 variable :math:`u = ax + b` in an integral relative to `x`. Then
733 :math:`dx = du/a`, so one will need to set `scl` equal to
734 :math:`1/a` - perhaps not what one would have first thought.
735
736 Also note that, in general, the result of integrating a C-series needs
737 to be "reprojected" onto the C-series basis set. Thus, typically,
738 the result of this function is "unintuitive," albeit correct; see
739 Examples section below.
740
741 Examples
742 --------
743 >>> from numpy.polynomial.hermite_e import hermeint
744 >>> hermeint([1, 2, 3]) # integrate once, value 0 at 0.
745 array([1., 1., 1., 1.])
746 >>> hermeint([1, 2, 3], m=2) # integrate twice, value & deriv 0 at 0
747 array([-0.25 , 1. , 0.5 , 0.33333333, 0.25 ]) # may vary
748 >>> hermeint([1, 2, 3], k=1) # integrate once, value 1 at 0.
749 array([2., 1., 1., 1.])
750 >>> hermeint([1, 2, 3], lbnd=-1) # integrate once, value 0 at -1
751 array([-1., 1., 1., 1.])
752 >>> hermeint([1, 2, 3], m=2, k=[1, 2], lbnd=-1)
753 array([ 1.83333333, 0. , 0.5 , 0.33333333, 0.25 ]) # may vary
754
755 """
756 c = np.array(c, ndmin=1, copy=True)
757 if c.dtype.char in '?bBhHiIlLqQpP':
758 c = c.astype(np.double)
759 if not np.iterable(k):
760 k = [k]
761 cnt = pu._as_int(m, "the order of integration")
762 iaxis = pu._as_int(axis, "the axis")
763 if cnt < 0:
764 raise ValueError("The order of integration must be non-negative")
765 if len(k) > cnt:
766 raise ValueError("Too many integration constants")
767 if np.ndim(lbnd) != 0:
768 raise ValueError("lbnd must be a scalar.")
769 if np.ndim(scl) != 0:
770 raise ValueError("scl must be a scalar.")
771 iaxis = np.lib.array_utils.normalize_axis_index(iaxis, c.ndim)
772
773 if cnt == 0:
774 return c
775
776 c = np.moveaxis(c, iaxis, 0)
777 k = list(k) + [0] * (cnt - len(k))
778 for i in range(cnt):
779 n = len(c)
780 c *= scl
781 if n == 1 and np.all(c[0] == 0):
782 c[0] += k[i]
783 else:
784 tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
785 tmp[0] = c[0] * 0
786 tmp[1] = c[0]
787 for j in range(1, n):
788 tmp[j + 1] = c[j] / (j + 1)
789 tmp[0] += k[i] - hermeval(lbnd, tmp)
790 c = tmp
791 c = np.moveaxis(c, 0, iaxis)
792 return c
793
794
795def hermeval(x, c, tensor=True):
796 """
797 Evaluate a HermiteE series at points x.
798
799 If `c` is of length ``n + 1``, this function returns the value:
800
801 .. math:: p(x) = c_0 * He_0(x) + c_1 * He_1(x) + ... + c_n * He_n(x)
802
803 The parameter `x` is converted to an array only if it is a tuple or a
804 list, otherwise it is treated as a scalar. In either case, either `x`
805 or its elements must support multiplication and addition both with
806 themselves and with the elements of `c`.
807
808 If `c` is a 1-D array, then ``p(x)`` will have the same shape as `x`. If
809 `c` is multidimensional, then the shape of the result depends on the
810 value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
811 x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
812 scalars have shape (,).
813
814 Trailing zeros in the coefficients will be used in the evaluation, so
815 they should be avoided if efficiency is a concern.
816
817 Parameters
818 ----------
819 x : array_like, compatible object
820 If `x` is a list or tuple, it is converted to an ndarray, otherwise
821 it is left unchanged and treated as a scalar. In either case, `x`
822 or its elements must support addition and multiplication with
823 with themselves and with the elements of `c`.
824 c : array_like
825 Array of coefficients ordered so that the coefficients for terms of
826 degree n are contained in c[n]. If `c` is multidimensional the
827 remaining indices enumerate multiple polynomials. In the two
828 dimensional case the coefficients may be thought of as stored in
829 the columns of `c`.
830 tensor : boolean, optional
831 If True, the shape of the coefficient array is extended with ones
832 on the right, one for each dimension of `x`. Scalars have dimension 0
833 for this action. The result is that every column of coefficients in
834 `c` is evaluated for every element of `x`. If False, `x` is broadcast
835 over the columns of `c` for the evaluation. This keyword is useful
836 when `c` is multidimensional. The default value is True.
837
838 Returns
839 -------
840 values : ndarray, algebra_like
841 The shape of the return value is described above.
842
843 See Also
844 --------
845 hermeval2d, hermegrid2d, hermeval3d, hermegrid3d
846
847 Notes
848 -----
849 The evaluation uses Clenshaw recursion, aka synthetic division.
850
851 Examples
852 --------
853 >>> from numpy.polynomial.hermite_e import hermeval
854 >>> coef = [1,2,3]
855 >>> hermeval(1, coef)
856 3.0
857 >>> hermeval([[1,2],[3,4]], coef)
858 array([[ 3., 14.],
859 [31., 54.]])
860
861 """
862 c = np.array(c, ndmin=1, copy=None)
863 if c.dtype.char in '?bBhHiIlLqQpP':
864 c = c.astype(np.double)
865 if isinstance(x, (tuple, list)):
866 x = np.asarray(x)
867 if isinstance(x, np.ndarray) and tensor:
868 c = c.reshape(c.shape + (1,) * x.ndim)
869
870 if len(c) == 1:
871 c0 = c[0]
872 c1 = 0
873 elif len(c) == 2:
874 c0 = c[0]
875 c1 = c[1]
876 else:
877 nd = len(c)
878 c0 = c[-2]
879 c1 = c[-1]
880 for i in range(3, len(c) + 1):
881 tmp = c0
882 nd = nd - 1
883 c0 = c[-i] - c1 * (nd - 1)
884 c1 = tmp + c1 * x
885 return c0 + c1 * x
886
887
888def hermeval2d(x, y, c):
889 """
890 Evaluate a 2-D HermiteE series at points (x, y).
891
892 This function returns the values:
893
894 .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * He_i(x) * He_j(y)
895
896 The parameters `x` and `y` are converted to arrays only if they are
897 tuples or a lists, otherwise they are treated as a scalars and they
898 must have the same shape after conversion. In either case, either `x`
899 and `y` or their elements must support multiplication and addition both
900 with themselves and with the elements of `c`.
901
902 If `c` is a 1-D array a one is implicitly appended to its shape to make
903 it 2-D. The shape of the result will be c.shape[2:] + x.shape.
904
905 Parameters
906 ----------
907 x, y : array_like, compatible objects
908 The two dimensional series is evaluated at the points ``(x, y)``,
909 where `x` and `y` must have the same shape. If `x` or `y` is a list
910 or tuple, it is first converted to an ndarray, otherwise it is left
911 unchanged and if it isn't an ndarray it is treated as a scalar.
912 c : array_like
913 Array of coefficients ordered so that the coefficient of the term
914 of multi-degree i,j is contained in ``c[i,j]``. If `c` has
915 dimension greater than two the remaining indices enumerate multiple
916 sets of coefficients.
917
918 Returns
919 -------
920 values : ndarray, compatible object
921 The values of the two dimensional polynomial at points formed with
922 pairs of corresponding values from `x` and `y`.
923
924 See Also
925 --------
926 hermeval, hermegrid2d, hermeval3d, hermegrid3d
927 """
928 return pu._valnd(hermeval, c, x, y)
929
930
931def hermegrid2d(x, y, c):
932 """
933 Evaluate a 2-D HermiteE series on the Cartesian product of x and y.
934
935 This function returns the values:
936
937 .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * H_i(a) * H_j(b)
938
939 where the points ``(a, b)`` consist of all pairs formed by taking
940 `a` from `x` and `b` from `y`. The resulting points form a grid with
941 `x` in the first dimension and `y` in the second.
942
943 The parameters `x` and `y` are converted to arrays only if they are
944 tuples or a lists, otherwise they are treated as a scalars. In either
945 case, either `x` and `y` or their elements must support multiplication
946 and addition both with themselves and with the elements of `c`.
947
948 If `c` has fewer than two dimensions, ones are implicitly appended to
949 its shape to make it 2-D. The shape of the result will be c.shape[2:] +
950 x.shape.
951
952 Parameters
953 ----------
954 x, y : array_like, compatible objects
955 The two dimensional series is evaluated at the points in the
956 Cartesian product of `x` and `y`. If `x` or `y` is a list or
957 tuple, it is first converted to an ndarray, otherwise it is left
958 unchanged and, if it isn't an ndarray, it is treated as a scalar.
959 c : array_like
960 Array of coefficients ordered so that the coefficients for terms of
961 degree i,j are contained in ``c[i,j]``. If `c` has dimension
962 greater than two the remaining indices enumerate multiple sets of
963 coefficients.
964
965 Returns
966 -------
967 values : ndarray, compatible object
968 The values of the two dimensional polynomial at points in the Cartesian
969 product of `x` and `y`.
970
971 See Also
972 --------
973 hermeval, hermeval2d, hermeval3d, hermegrid3d
974 """
975 return pu._gridnd(hermeval, c, x, y)
976
977
978def hermeval3d(x, y, z, c):
979 """
980 Evaluate a 3-D Hermite_e series at points (x, y, z).
981
982 This function returns the values:
983
984 .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * He_i(x) * He_j(y) * He_k(z)
985
986 The parameters `x`, `y`, and `z` are converted to arrays only if
987 they are tuples or a lists, otherwise they are treated as a scalars and
988 they must have the same shape after conversion. In either case, either
989 `x`, `y`, and `z` or their elements must support multiplication and
990 addition both with themselves and with the elements of `c`.
991
992 If `c` has fewer than 3 dimensions, ones are implicitly appended to its
993 shape to make it 3-D. The shape of the result will be c.shape[3:] +
994 x.shape.
995
996 Parameters
997 ----------
998 x, y, z : array_like, compatible object
999 The three dimensional series is evaluated at the points
1000 `(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If
1001 any of `x`, `y`, or `z` is a list or tuple, it is first converted
1002 to an ndarray, otherwise it is left unchanged and if it isn't an
1003 ndarray it is treated as a scalar.
1004 c : array_like
1005 Array of coefficients ordered so that the coefficient of the term of
1006 multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
1007 greater than 3 the remaining indices enumerate multiple sets of
1008 coefficients.
1009
1010 Returns
1011 -------
1012 values : ndarray, compatible object
1013 The values of the multidimensional polynomial on points formed with
1014 triples of corresponding values from `x`, `y`, and `z`.
1015
1016 See Also
1017 --------
1018 hermeval, hermeval2d, hermegrid2d, hermegrid3d
1019 """
1020 return pu._valnd(hermeval, c, x, y, z)
1021
1022
1023def hermegrid3d(x, y, z, c):
1024 """
1025 Evaluate a 3-D HermiteE series on the Cartesian product of x, y, and z.
1026
1027 This function returns the values:
1028
1029 .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * He_i(a) * He_j(b) * He_k(c)
1030
1031 where the points ``(a, b, c)`` consist of all triples formed by taking
1032 `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
1033 a grid with `x` in the first dimension, `y` in the second, and `z` in
1034 the third.
1035
1036 The parameters `x`, `y`, and `z` are converted to arrays only if they
1037 are tuples or a lists, otherwise they are treated as a scalars. In
1038 either case, either `x`, `y`, and `z` or their elements must support
1039 multiplication and addition both with themselves and with the elements
1040 of `c`.
1041
1042 If `c` has fewer than three dimensions, ones are implicitly appended to
1043 its shape to make it 3-D. The shape of the result will be c.shape[3:] +
1044 x.shape + y.shape + z.shape.
1045
1046 Parameters
1047 ----------
1048 x, y, z : array_like, compatible objects
1049 The three dimensional series is evaluated at the points in the
1050 Cartesian product of `x`, `y`, and `z`. If `x`, `y`, or `z` is a
1051 list or tuple, it is first converted to an ndarray, otherwise it is
1052 left unchanged and, if it isn't an ndarray, it is treated as a
1053 scalar.
1054 c : array_like
1055 Array of coefficients ordered so that the coefficients for terms of
1056 degree i,j are contained in ``c[i,j]``. If `c` has dimension
1057 greater than two the remaining indices enumerate multiple sets of
1058 coefficients.
1059
1060 Returns
1061 -------
1062 values : ndarray, compatible object
1063 The values of the two dimensional polynomial at points in the Cartesian
1064 product of `x` and `y`.
1065
1066 See Also
1067 --------
1068 hermeval, hermeval2d, hermegrid2d, hermeval3d
1069 """
1070 return pu._gridnd(hermeval, c, x, y, z)
1071
1072
1073def hermevander(x, deg):
1074 """Pseudo-Vandermonde matrix of given degree.
1075
1076 Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
1077 `x`. The pseudo-Vandermonde matrix is defined by
1078
1079 .. math:: V[..., i] = He_i(x),
1080
1081 where ``0 <= i <= deg``. The leading indices of `V` index the elements of
1082 `x` and the last index is the degree of the HermiteE polynomial.
1083
1084 If `c` is a 1-D array of coefficients of length ``n + 1`` and `V` is the
1085 array ``V = hermevander(x, n)``, then ``np.dot(V, c)`` and
1086 ``hermeval(x, c)`` are the same up to roundoff. This equivalence is
1087 useful both for least squares fitting and for the evaluation of a large
1088 number of HermiteE series of the same degree and sample points.
1089
1090 Parameters
1091 ----------
1092 x : array_like
1093 Array of points. The dtype is converted to float64 or complex128
1094 depending on whether any of the elements are complex. If `x` is
1095 scalar it is converted to a 1-D array.
1096 deg : int
1097 Degree of the resulting matrix.
1098
1099 Returns
1100 -------
1101 vander : ndarray
1102 The pseudo-Vandermonde matrix. The shape of the returned matrix is
1103 ``x.shape + (deg + 1,)``, where The last index is the degree of the
1104 corresponding HermiteE polynomial. The dtype will be the same as
1105 the converted `x`.
1106
1107 Examples
1108 --------
1109 >>> import numpy as np
1110 >>> from numpy.polynomial.hermite_e import hermevander
1111 >>> x = np.array([-1, 0, 1])
1112 >>> hermevander(x, 3)
1113 array([[ 1., -1., 0., 2.],
1114 [ 1., 0., -1., -0.],
1115 [ 1., 1., 0., -2.]])
1116
1117 """
1118 ideg = pu._as_int(deg, "deg")
1119 if ideg < 0:
1120 raise ValueError("deg must be non-negative")
1121
1122 x = np.array(x, copy=None, ndmin=1) + 0.0
1123 dims = (ideg + 1,) + x.shape
1124 dtyp = x.dtype
1125 v = np.empty(dims, dtype=dtyp)
1126 v[0] = x * 0 + 1
1127 if ideg > 0:
1128 v[1] = x
1129 for i in range(2, ideg + 1):
1130 v[i] = (v[i - 1] * x - v[i - 2] * (i - 1))
1131 return np.moveaxis(v, 0, -1)
1132
1133
1134def hermevander2d(x, y, deg):
1135 """Pseudo-Vandermonde matrix of given degrees.
1136
1137 Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
1138 points ``(x, y)``. The pseudo-Vandermonde matrix is defined by
1139
1140 .. math:: V[..., (deg[1] + 1)*i + j] = He_i(x) * He_j(y),
1141
1142 where ``0 <= i <= deg[0]`` and ``0 <= j <= deg[1]``. The leading indices of
1143 `V` index the points ``(x, y)`` and the last index encodes the degrees of
1144 the HermiteE polynomials.
1145
1146 If ``V = hermevander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
1147 correspond to the elements of a 2-D coefficient array `c` of shape
1148 (xdeg + 1, ydeg + 1) in the order
1149
1150 .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
1151
1152 and ``np.dot(V, c.flat)`` and ``hermeval2d(x, y, c)`` will be the same
1153 up to roundoff. This equivalence is useful both for least squares
1154 fitting and for the evaluation of a large number of 2-D HermiteE
1155 series of the same degrees and sample points.
1156
1157 Parameters
1158 ----------
1159 x, y : array_like
1160 Arrays of point coordinates, all of the same shape. The dtypes
1161 will be converted to either float64 or complex128 depending on
1162 whether any of the elements are complex. Scalars are converted to
1163 1-D arrays.
1164 deg : list of ints
1165 List of maximum degrees of the form [x_deg, y_deg].
1166
1167 Returns
1168 -------
1169 vander2d : ndarray
1170 The shape of the returned matrix is ``x.shape + (order,)``, where
1171 :math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same
1172 as the converted `x` and `y`.
1173
1174 See Also
1175 --------
1176 hermevander, hermevander3d, hermeval2d, hermeval3d
1177 """
1178 return pu._vander_nd_flat((hermevander, hermevander), (x, y), deg)
1179
1180
1181def hermevander3d(x, y, z, deg):
1182 """Pseudo-Vandermonde matrix of given degrees.
1183
1184 Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
1185 points ``(x, y, z)``. If `l`, `m`, `n` are the given degrees in `x`, `y`, `z`,
1186 then Hehe pseudo-Vandermonde matrix is defined by
1187
1188 .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = He_i(x)*He_j(y)*He_k(z),
1189
1190 where ``0 <= i <= l``, ``0 <= j <= m``, and ``0 <= j <= n``. The leading
1191 indices of `V` index the points ``(x, y, z)`` and the last index encodes
1192 the degrees of the HermiteE polynomials.
1193
1194 If ``V = hermevander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
1195 of `V` correspond to the elements of a 3-D coefficient array `c` of
1196 shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
1197
1198 .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
1199
1200 and ``np.dot(V, c.flat)`` and ``hermeval3d(x, y, z, c)`` will be the
