Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
hermite.py1739 linesDownload Raw Back to polynomial
1"""
2==============================================================
3Hermite Series, "Physicists" (:mod:`numpy.polynomial.hermite`)
4==============================================================
5
6This module provides a number of objects (mostly functions) useful for
7dealing with Hermite series, including a `Hermite` 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   Hermite
18
19Constants
20---------
21.. autosummary::
22   :toctree: generated/
23
24   hermdomain
25   hermzero
26   hermone
27   hermx
28
29Arithmetic
30----------
31.. autosummary::
32   :toctree: generated/
33
34   hermadd
35   hermsub
36   hermmulx
37   hermmul
38   hermdiv
39   hermpow
40   hermval
41   hermval2d
42   hermval3d
43   hermgrid2d
44   hermgrid3d
45
46Calculus
47--------
48.. autosummary::
49   :toctree: generated/
50
51   hermder
52   hermint
53
54Misc Functions
55--------------
56.. autosummary::
57   :toctree: generated/
58
59   hermfromroots
60   hermroots
61   hermvander
62   hermvander2d
63   hermvander3d
64   hermgauss
65   hermweight
66   hermcompanion
67   hermfit
68   hermtrim
69   hermline
70   herm2poly
71   poly2herm
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    'hermzero', 'hermone', 'hermx', 'hermdomain', 'hermline', 'hermadd',
85    'hermsub', 'hermmulx', 'hermmul', 'hermdiv', 'hermpow', 'hermval',
86    'hermder', 'hermint', 'herm2poly', 'poly2herm', 'hermfromroots',
87    'hermvander', 'hermfit', 'hermtrim', 'hermroots', 'Hermite',
88    'hermval2d', 'hermval3d', 'hermgrid2d', 'hermgrid3d', 'hermvander2d',
89    'hermvander3d', 'hermcompanion', 'hermgauss', 'hermweight']
90
91hermtrim = pu.trimcoef
92
93
94def poly2herm(pol):
95    """
96    poly2herm(pol)
97
98    Convert a polynomial to a Hermite series.
99
100    Convert an array representing the coefficients of a polynomial (relative
101    to the "standard" basis) ordered from lowest degree to highest, to an
102    array of the coefficients of the equivalent Hermite series, ordered
103    from lowest to highest degree.
104
105    Parameters
106    ----------
107    pol : array_like
108        1-D array containing the polynomial coefficients
109
110    Returns
111    -------
112    c : ndarray
113        1-D array containing the coefficients of the equivalent Hermite
114        series.
115
116    See Also
117    --------
118    herm2poly
119
120    Notes
121    -----
122    The easy way to do conversions between polynomial basis sets
123    is to use the convert method of a class instance.
124
125    Examples
126    --------
127    >>> from numpy.polynomial.hermite import poly2herm
128    >>> poly2herm(np.arange(4))
129    array([1.   ,  2.75 ,  0.5  ,  0.375])
130
131    """
132    [pol] = pu.as_series([pol])
133    deg = len(pol) - 1
134    res = 0
135    for i in range(deg, -1, -1):
136        res = hermadd(hermmulx(res), pol[i])
137    return res
138
139
140def herm2poly(c):
141    """
142    Convert a Hermite series to a polynomial.
143
144    Convert an array representing the coefficients of a Hermite series,
145    ordered from lowest degree to highest, to an array of the coefficients
146    of the equivalent polynomial (relative to the "standard" basis) ordered
147    from lowest to highest degree.
148
149    Parameters
150    ----------
151    c : array_like
152        1-D array containing the Hermite series coefficients, ordered
153        from lowest order term to highest.
154
155    Returns
156    -------
157    pol : ndarray
158        1-D array containing the coefficients of the equivalent polynomial
159        (relative to the "standard" basis) ordered from lowest order term
160        to highest.
161
162    See Also
163    --------
164    poly2herm
165
166    Notes
167    -----
168    The easy way to do conversions between polynomial basis sets
169    is to use the convert method of a class instance.
170
171    Examples
172    --------
173    >>> from numpy.polynomial.hermite import herm2poly
174    >>> herm2poly([ 1.   ,  2.75 ,  0.5  ,  0.375])
175    array([0., 1., 2., 3.])
176
177    """
178    from .polynomial import polyadd, polymulx, polysub
179
180    [c] = pu.as_series([c])
181    n = len(c)
182    if n == 1:
183        return c
184    if n == 2:
185        c[1] *= 2
186        return c
187    else:
188        c0 = c[-2]
189        c1 = c[-1]
190        # i is the current degree of c1
191        for i in range(n - 1, 1, -1):
192            tmp = c0
193            c0 = polysub(c[i - 2], c1 * (2 * (i - 1)))
194            c1 = polyadd(tmp, polymulx(c1) * 2)
195        return polyadd(c0, polymulx(c1) * 2)
196
197
198#
199# These are constant arrays are of integer type so as to be compatible
200# with the widest range of other types, such as Decimal.
201#
202
203# Hermite
204hermdomain = np.array([-1., 1.])
205
206# Hermite coefficients representing zero.
207hermzero = np.array([0])
208
209# Hermite coefficients representing one.
210hermone = np.array([1])
211
212# Hermite coefficients representing the identity x.
213hermx = np.array([0, 1 / 2])
214
215
216def hermline(off, scl):
217    """
218    Hermite series whose graph is a straight line.
219
220
221
222    Parameters
223    ----------
224    off, scl : scalars
225        The specified line is given by ``off + scl*x``.
226
227    Returns
228    -------
229    y : ndarray
230        This module's representation of the Hermite series for
231        ``off + scl*x``.
232
233    See Also
234    --------
235    numpy.polynomial.polynomial.polyline
236    numpy.polynomial.chebyshev.chebline
237    numpy.polynomial.legendre.legline
238    numpy.polynomial.laguerre.lagline
239    numpy.polynomial.hermite_e.hermeline
240
241    Examples
242    --------
243    >>> from numpy.polynomial.hermite import hermline, hermval
244    >>> hermval(0,hermline(3, 2))
245    3.0
246    >>> hermval(1,hermline(3, 2))
247    5.0
248
249    """
250    if scl != 0:
251        return np.array([off, scl / 2])
252    else:
253        return np.array([off])
254
255
256def hermfromroots(roots):
257    """
258    Generate a Hermite 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 Hermite 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 * H_1(x) + ... +  c_n * H_n(x)
273
274    The coefficient of the last term is not generally 1 for monic
275    polynomials in Hermite 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.chebyshev.chebfromroots
296    numpy.polynomial.hermite_e.hermefromroots
297
298    Examples
299    --------
300    >>> from numpy.polynomial.hermite import hermfromroots, hermval
301    >>> coef = hermfromroots((-1, 0, 1))
302    >>> hermval((-1, 0, 1), coef)
303    array([0.,  0.,  0.])
304    >>> coef = hermfromroots((-1j, 1j))
305    >>> hermval((-1j, 1j), coef)
306    array([0.+0.j, 0.+0.j])
307
308    """
309    return pu._fromroots(hermline, hermmul, roots)
310
311
312def hermadd(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    hermsub, hermmulx, hermmul, hermdiv, hermpow
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 import hermadd
345    >>> hermadd([1, 2, 3], [1, 2, 3, 4])
346    array([2., 4., 6., 4.])
347
348    """
349    return pu._add(c1, c2)
350
351
352def hermsub(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    hermadd, hermmulx, hermmul, hermdiv, hermpow
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 import hermsub
385    >>> hermsub([1, 2, 3, 4], [1, 2, 3])
386    array([0.,  0.,  0.,  4.])
387
388    """
389    return pu._sub(c1, c2)
390
391
392def hermmulx(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    hermadd, hermsub, hermmul, hermdiv, hermpow
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)/2 + i*P_{i - 1}(x))
422
423    Examples
424    --------
425    >>> from numpy.polynomial.hermite import hermmulx
426    >>> hermmulx([1, 2, 3])
427    array([2. , 6.5, 1. , 1.5])
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] / 2
439    for i in range(1, len(c)):
440        prd[i + 1] = c[i] / 2
441        prd[i - 1] += c[i] * i
442    return prd
443
444
445def hermmul(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    hermadd, hermsub, hermmulx, hermdiv, hermpow
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 import hermmul
479    >>> hermmul([1, 2, 3], [0, 1, 2])
480    array([52.,  29.,  52.,   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 = hermsub(c[-i] * xs, c1 * (2 * (nd - 1)))
507            c1 = hermadd(tmp, hermmulx(c1) * 2)
508    return hermadd(c0, hermmulx(c1) * 2)
509
510
511def hermdiv(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    hermadd, hermsub, hermmulx, hermmul, hermpow
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 import hermdiv
548    >>> hermdiv([ 52.,  29.,  52.,   7.,   6.], [0, 1, 2])
549    (array([1., 2., 3.]), array([0.]))
550    >>> hermdiv([ 54.,  31.,  52.,   7.,   6.], [0, 1, 2])
551    (array([1., 2., 3.]), array([2., 2.]))
552    >>> hermdiv([ 53.,  30.,  52.,   7.,   6.], [0, 1, 2])
553    (array([1., 2., 3.]), array([1., 1.]))
554
555    """
556    return pu._div(hermmul, c1, c2)
557
558
559def hermpow(c, pow, maxpower=16):
560    """Raise a Hermite series to a power.
561
562    Returns the Hermite series `c` raised to the power `pow`. The
563    argument `c` is a sequence of coefficients ordered from low to high.
564    i.e., [1,2,3] is the series  ``P_0 + 2*P_1 + 3*P_2.``
565
566    Parameters
567    ----------
568    c : array_like
569        1-D array of Hermite series coefficients ordered from low to
570        high.
571    pow : integer
572        Power to which the series will be raised
573    maxpower : integer, optional
574        Maximum power allowed. This is mainly to limit growth of the series
575        to unmanageable size. Default is 16
576
577    Returns
578    -------
579    coef : ndarray
580        Hermite series of power.
581
582    See Also
583    --------
584    hermadd, hermsub, hermmulx, hermmul, hermdiv
585
586    Examples
587    --------
588    >>> from numpy.polynomial.hermite import hermpow
589    >>> hermpow([1, 2, 3], 2)
590    array([81.,  52.,  82.,  12.,   9.])
591
592    """
593    return pu._pow(hermmul, c, pow, maxpower)
594
595
596def hermder(c, m=1, scl=1, axis=0):
597    """
598    Differentiate a Hermite series.
599
600    Returns the Hermite series coefficients `c` differentiated `m` times
601    along `axis`.  At each iteration the result is multiplied by `scl` (the
602    scaling factor is for use in a linear change of variable). The argument
603    `c` is an array of coefficients from low to high degree along each
604    axis, e.g., [1,2,3] represents the series ``1*H_0 + 2*H_1 + 3*H_2``
605    while [[1,2],[1,2]] represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) +
606    2*H_0(x)*H_1(y) + 2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is
607    ``y``.
608
609    Parameters
610    ----------
611    c : array_like
612        Array of Hermite series coefficients. If `c` is multidimensional the
613        different axis correspond to different variables with the degree in
614        each axis given by the corresponding index.
615    m : int, optional
616        Number of derivatives taken, must be non-negative. (Default: 1)
617    scl : scalar, optional
618        Each differentiation is multiplied by `scl`.  The end result is
619        multiplication by ``scl**m``.  This is for use in a linear change of
620        variable. (Default: 1)
621    axis : int, optional
622        Axis over which the derivative is taken. (Default: 0).
623
624    Returns
625    -------
626    der : ndarray
627        Hermite series of the derivative.
628
629    See Also
630    --------
631    hermint
632
633    Notes
634    -----
635    In general, the result of differentiating a Hermite series does not
636    resemble the same operation on a power series. Thus the result of this
637    function may be "unintuitive," albeit correct; see Examples section
638    below.
639
640    Examples
641    --------
642    >>> from numpy.polynomial.hermite import hermder
643    >>> hermder([ 1. ,  0.5,  0.5,  0.5])
644    array([1., 2., 3.])
645    >>> hermder([-0.5,  1./2.,  1./8.,  1./12.,  1./16.], m=2)
646    array([1., 2., 3.])
647
648    """
649    c = np.array(c, ndmin=1, copy=True)
650    if c.dtype.char in '?bBhHiIlLqQpP':
651        c = c.astype(np.double)
652    cnt = pu._as_int(m, "the order of derivation")
653    iaxis = pu._as_int(axis, "the axis")
654    if cnt < 0:
655        raise ValueError("The order of derivation must be non-negative")
656    iaxis = np.lib.array_utils.normalize_axis_index(iaxis, c.ndim)
657
658    if cnt == 0:
659        return c
660
661    c = np.moveaxis(c, iaxis, 0)
662    n = len(c)
663    if cnt >= n:
664        c = c[:1] * 0
665    else:
666        for i in range(cnt):
667            n = n - 1
668            c *= scl
669            der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
670            for j in range(n, 0, -1):
671                der[j - 1] = (2 * j) * c[j]
672            c = der
673    c = np.moveaxis(c, 0, iaxis)
674    return c
675
676
677def hermint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
678    """
679    Integrate a Hermite series.
680
681    Returns the Hermite 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 ``H_0 + 2*H_1 + 3*H_2`` while [[1,2],[1,2]]
690    represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) + 2*H_0(x)*H_1(y) +
691    2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
692
693    Parameters
694    ----------
695    c : array_like
696        Array of Hermite series coefficients. If c is multidimensional the
697        different axis correspond to different variables with the degree in
698        each axis given by the corresponding index.
699    m : int, optional
700        Order of integration, must be positive. (Default: 1)
701    k : {[], list, scalar}, optional
702        Integration constant(s).  The value of the first integral at
703        ``lbnd`` is the first value in the list, the value of the second
704        integral at ``lbnd`` is the second value, etc.  If ``k == []`` (the
705        default), all constants are set to zero.  If ``m == 1``, a single
706        scalar can be given instead of a list.
707    lbnd : scalar, optional
708        The lower bound of the integral. (Default: 0)
709    scl : scalar, optional
710        Following each integration the result is *multiplied* by `scl`
711        before the integration constant is added. (Default: 1)
712    axis : int, optional
713        Axis over which the integral is taken. (Default: 0).
714
715    Returns
716    -------
717    S : ndarray
718        Hermite series coefficients of the integral.
719
720    Raises
721    ------
722    ValueError
723        If ``m < 0``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or
724        ``np.ndim(scl) != 0``.
725
726    See Also
727    --------
728    hermder
729
730    Notes
731    -----
732    Note that the result of each integration is *multiplied* by `scl`.
733    Why is this important to note?  Say one is making a linear change of
734    variable :math:`u = ax + b` in an integral relative to `x`.  Then
735    :math:`dx = du/a`, so one will need to set `scl` equal to
736    :math:`1/a` - perhaps not what one would have first thought.
737
738    Also note that, in general, the result of integrating a C-series needs
739    to be "reprojected" onto the C-series basis set.  Thus, typically,
740    the result of this function is "unintuitive," albeit correct; see
741    Examples section below.
742
743    Examples
744    --------
745    >>> from numpy.polynomial.hermite import hermint
746    >>> hermint([1,2,3]) # integrate once, value 0 at 0.
747    array([1. , 0.5, 0.5, 0.5])
748    >>> hermint([1,2,3], m=2) # integrate twice, value & deriv 0 at 0
749    array([-0.5       ,  0.5       ,  0.125     ,  0.08333333,  0.0625    ]) # may vary
750    >>> hermint([1,2,3], k=1) # integrate once, value 1 at 0.
751    array([2. , 0.5, 0.5, 0.5])
752    >>> hermint([1,2,3], lbnd=-1) # integrate once, value 0 at -1
753    array([-2. ,  0.5,  0.5,  0.5])
754    >>> hermint([1,2,3], m=2, k=[1,2], lbnd=-1)
755    array([ 1.66666667, -0.5       ,  0.125     ,  0.08333333,  0.0625    ]) # may vary
756
757    """
758    c = np.array(c, ndmin=1, copy=True)
759    if c.dtype.char in '?bBhHiIlLqQpP':
760        c = c.astype(np.double)
761    if not np.iterable(k):
762        k = [k]
763    cnt = pu._as_int(m, "the order of integration")
764    iaxis = pu._as_int(axis, "the axis")
765    if cnt < 0:
766        raise ValueError("The order of integration must be non-negative")
767    if len(k) > cnt:
768        raise ValueError("Too many integration constants")
769    if np.ndim(lbnd) != 0:
770        raise ValueError("lbnd must be a scalar.")
771    if np.ndim(scl) != 0:
772        raise ValueError("scl must be a scalar.")
773    iaxis = np.lib.array_utils.normalize_axis_index(iaxis, c.ndim)
774
775    if cnt == 0:
776        return c
777
778    c = np.moveaxis(c, iaxis, 0)
779    k = list(k) + [0] * (cnt - len(k))
780    for i in range(cnt):
781        n = len(c)
782        c *= scl
783        if n == 1 and np.all(c[0] == 0):
784            c[0] += k[i]
785        else:
786            tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
787            tmp[0] = c[0] * 0
788            tmp[1] = c[0] / 2
789            for j in range(1, n):
790                tmp[j + 1] = c[j] / (2 * (j + 1))
791            tmp[0] += k[i] - hermval(lbnd, tmp)
792            c = tmp
793    c = np.moveaxis(c, 0, iaxis)
794    return c
795
796
797def hermval(x, c, tensor=True):
798    """
799    Evaluate a Hermite series at points x.
800
801    If `c` is of length ``n + 1``, this function returns the value:
802
803    .. math:: p(x) = c_0 * H_0(x) + c_1 * H_1(x) + ... + c_n * H_n(x)
804
805    The parameter `x` is converted to an array only if it is a tuple or a
806    list, otherwise it is treated as a scalar. In either case, either `x`
807    or its elements must support multiplication and addition both with
808    themselves and with the elements of `c`.
809
810    If `c` is a 1-D array, then ``p(x)`` will have the same shape as `x`.  If
811    `c` is multidimensional, then the shape of the result depends on the
812    value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
813    x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
814    scalars have shape (,).
815
816    Trailing zeros in the coefficients will be used in the evaluation, so
817    they should be avoided if efficiency is a concern.
818
819    Parameters
820    ----------
821    x : array_like, compatible object
822        If `x` is a list or tuple, it is converted to an ndarray, otherwise
823        it is left unchanged and treated as a scalar. In either case, `x`
824        or its elements must support addition and multiplication with
825        themselves and with the elements of `c`.
826    c : array_like
827        Array of coefficients ordered so that the coefficients for terms of
828        degree n are contained in c[n]. If `c` is multidimensional the
829        remaining indices enumerate multiple polynomials. In the two
830        dimensional case the coefficients may be thought of as stored in
831        the columns of `c`.
832    tensor : boolean, optional
833        If True, the shape of the coefficient array is extended with ones
834        on the right, one for each dimension of `x`. Scalars have dimension 0
835        for this action. The result is that every column of coefficients in
836        `c` is evaluated for every element of `x`. If False, `x` is broadcast
837        over the columns of `c` for the evaluation.  This keyword is useful
838        when `c` is multidimensional. The default value is True.
839
840    Returns
841    -------
842    values : ndarray, algebra_like
843        The shape of the return value is described above.
844
845    See Also
846    --------
847    hermval2d, hermgrid2d, hermval3d, hermgrid3d
848
849    Notes
850    -----
851    The evaluation uses Clenshaw recursion, aka synthetic division.
852
853    Examples
854    --------
855    >>> from numpy.polynomial.hermite import hermval
856    >>> coef = [1,2,3]
857    >>> hermval(1, coef)
858    11.0
859    >>> hermval([[1,2],[3,4]], coef)
860    array([[ 11.,   51.],
861           [115.,  203.]])
862
863    """
864    c = np.array(c, ndmin=1, copy=None)
865    if c.dtype.char in '?bBhHiIlLqQpP':
866        c = c.astype(np.double)
867    if isinstance(x, (tuple, list)):
868        x = np.asarray(x)
869    if isinstance(x, np.ndarray) and tensor:
870        c = c.reshape(c.shape + (1,) * x.ndim)
871
872    x2 = x * 2
873    if len(c) == 1:
874        c0 = c[0]
875        c1 = 0
876    elif len(c) == 2:
877        c0 = c[0]
878        c1 = c[1]
879    else:
880        nd = len(c)
881        c0 = c[-2]
882        c1 = c[-1]
883        for i in range(3, len(c) + 1):
884            tmp = c0
885            nd = nd - 1
886            c0 = c[-i] - c1 * (2 * (nd - 1))
887            c1 = tmp + c1 * x2
888    return c0 + c1 * x2
889
890
891def hermval2d(x, y, c):
892    """
893    Evaluate a 2-D Hermite series at points (x, y).
894
895    This function returns the values:
896
897    .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * H_i(x) * H_j(y)
898
899    The parameters `x` and `y` are converted to arrays only if they are
900    tuples or a lists, otherwise they are treated as a scalars and they
901    must have the same shape after conversion. In either case, either `x`
902    and `y` or their elements must support multiplication and addition both
903    with themselves and with the elements of `c`.
904
905    If `c` is a 1-D array a one is implicitly appended to its shape to make
906    it 2-D. The shape of the result will be c.shape[2:] + x.shape.
907
908    Parameters
909    ----------
910    x, y : array_like, compatible objects
911        The two dimensional series is evaluated at the points ``(x, y)``,
912        where `x` and `y` must have the same shape. If `x` or `y` is a list
913        or tuple, it is first converted to an ndarray, otherwise it is left
914        unchanged and if it isn't an ndarray it is treated as a scalar.
915    c : array_like
916        Array of coefficients ordered so that the coefficient of the term
917        of multi-degree i,j is contained in ``c[i,j]``. If `c` has
918        dimension greater than two the remaining indices enumerate multiple
919        sets of coefficients.
920
921    Returns
922    -------
923    values : ndarray, compatible object
924        The values of the two dimensional polynomial at points formed with
925        pairs of corresponding values from `x` and `y`.
926
927    See Also
928    --------
929    hermval, hermgrid2d, hermval3d, hermgrid3d
930
931    Examples
932    --------
933    >>> from numpy.polynomial.hermite import hermval2d
934    >>> x = [1, 2]
935    >>> y = [4, 5]
936    >>> c = [[1, 2, 3], [4, 5, 6]]
937    >>> hermval2d(x, y, c)
938    array([1035., 2883.])
939
940    """
941    return pu._valnd(hermval, c, x, y)
942
943
944def hermgrid2d(x, y, c):
945    """
946    Evaluate a 2-D Hermite series on the Cartesian product of x and y.
947
948    This function returns the values:
949
950    .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * H_i(a) * H_j(b)
951
952    where the points ``(a, b)`` consist of all pairs formed by taking
953    `a` from `x` and `b` from `y`. The resulting points form a grid with
954    `x` in the first dimension and `y` in the second.
955
956    The parameters `x` and `y` are converted to arrays only if they are
957    tuples or a lists, otherwise they are treated as a scalars. In either
958    case, either `x` and `y` or their elements must support multiplication
959    and addition both with themselves and with the elements of `c`.
960
961    If `c` has fewer than two dimensions, ones are implicitly appended to
962    its shape to make it 2-D. The shape of the result will be c.shape[2:] +
963    x.shape.
964
965    Parameters
966    ----------
967    x, y : array_like, compatible objects
968        The two dimensional series is evaluated at the points in the
969        Cartesian product of `x` and `y`.  If `x` or `y` is a list or
970        tuple, it is first converted to an ndarray, otherwise it is left
971        unchanged and, if it isn't an ndarray, it is treated as a scalar.
972    c : array_like
973        Array of coefficients ordered so that the coefficients for terms of
974        degree i,j are contained in ``c[i,j]``. If `c` has dimension
975        greater than two the remaining indices enumerate multiple sets of
976        coefficients.
977
978    Returns
979    -------
980    values : ndarray, compatible object
981        The values of the two dimensional polynomial at points in the Cartesian
982        product of `x` and `y`.
983
984    See Also
985    --------
986    hermval, hermval2d, hermval3d, hermgrid3d
987
988    Examples
989    --------
990    >>> from numpy.polynomial.hermite import hermgrid2d
991    >>> x = [1, 2, 3]
992    >>> y = [4, 5]
993    >>> c = [[1, 2, 3], [4, 5, 6]]
994    >>> hermgrid2d(x, y, c)
995    array([[1035., 1599.],
996           [1867., 2883.],
997           [2699., 4167.]])
998
999    """
1000    return pu._gridnd(hermval, c, x, y)
1001
1002
1003def hermval3d(x, y, z, c):
1004    """
1005    Evaluate a 3-D Hermite series at points (x, y, z).
1006
1007    This function returns the values:
1008
1009    .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * H_i(x) * H_j(y) * H_k(z)
1010
1011    The parameters `x`, `y`, and `z` are converted to arrays only if
1012    they are tuples or a lists, otherwise they are treated as a scalars and
1013    they must have the same shape after conversion. In either case, either
1014    `x`, `y`, and `z` or their elements must support multiplication and
1015    addition both with themselves and with the elements of `c`.
1016
1017    If `c` has fewer than 3 dimensions, ones are implicitly appended to its
1018    shape to make it 3-D. The shape of the result will be c.shape[3:] +
1019    x.shape.
1020
1021    Parameters
1022    ----------
1023    x, y, z : array_like, compatible object
1024        The three dimensional series is evaluated at the points
1025        ``(x, y, z)``, where `x`, `y`, and `z` must have the same shape.  If
1026        any of `x`, `y`, or `z` is a list or tuple, it is first converted
1027        to an ndarray, otherwise it is left unchanged and if it isn't an
1028        ndarray it is  treated as a scalar.
1029    c : array_like
1030        Array of coefficients ordered so that the coefficient of the term of
1031        multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
1032        greater than 3 the remaining indices enumerate multiple sets of
1033        coefficients.
1034
1035    Returns
1036    -------
1037    values : ndarray, compatible object
1038        The values of the multidimensional polynomial on points formed with
1039        triples of corresponding values from `x`, `y`, and `z`.
1040
1041    See Also
1042    --------
1043    hermval, hermval2d, hermgrid2d, hermgrid3d
1044
1045    Examples
1046    --------
1047    >>> from numpy.polynomial.hermite import hermval3d
1048    >>> x = [1, 2]
1049    >>> y = [4, 5]
1050    >>> z = [6, 7]
1051    >>> c = [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]
1052    >>> hermval3d(x, y, z, c)
1053    array([ 40077., 120131.])
1054
1055    """
1056    return pu._valnd(hermval, c, x, y, z)
1057
1058
1059def hermgrid3d(x, y, z, c):
1060    """
1061    Evaluate a 3-D Hermite series on the Cartesian product of x, y, and z.
1062
1063    This function returns the values:
1064
1065    .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * H_i(a) * H_j(b) * H_k(c)
1066
1067    where the points ``(a, b, c)`` consist of all triples formed by taking
1068    `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
1069    a grid with `x` in the first dimension, `y` in the second, and `z` in
1070    the third.
1071
1072    The parameters `x`, `y`, and `z` are converted to arrays only if they
1073    are tuples or a lists, otherwise they are treated as a scalars. In
1074    either case, either `x`, `y`, and `z` or their elements must support
1075    multiplication and addition both with themselves and with the elements
1076    of `c`.
1077
1078    If `c` has fewer than three dimensions, ones are implicitly appended to
1079    its shape to make it 3-D. The shape of the result will be c.shape[3:] +
1080    x.shape + y.shape + z.shape.
1081
1082    Parameters
1083    ----------
1084    x, y, z : array_like, compatible objects
1085        The three dimensional series is evaluated at the points in the
1086        Cartesian product of `x`, `y`, and `z`.  If `x`, `y`, or `z` is a
1087        list or tuple, it is first converted to an ndarray, otherwise it is
1088        left unchanged and, if it isn't an ndarray, it is treated as a
1089        scalar.
1090    c : array_like
1091        Array of coefficients ordered so that the coefficients for terms of
1092        degree i,j are contained in ``c[i,j]``. If `c` has dimension
1093        greater than two the remaining indices enumerate multiple sets of
1094        coefficients.
1095
1096    Returns
1097    -------
1098    values : ndarray, compatible object
1099        The values of the two dimensional polynomial at points in the Cartesian
1100        product of `x` and `y`.
1101
1102    See Also
1103    --------
1104    hermval, hermval2d, hermgrid2d, hermval3d
1105
1106    Examples
1107    --------
1108    >>> from numpy.polynomial.hermite import hermgrid3d
1109    >>> x = [1, 2]
1110    >>> y = [4, 5]
1111    >>> z = [6, 7]
1112    >>> c = [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]
1113    >>> hermgrid3d(x, y, z, c)
1114    array([[[ 40077.,  54117.],
1115            [ 49293.,  66561.]],
1116           [[ 72375.,  97719.],
1117            [ 88975., 120131.]]])
1118
1119    """
1120    return pu._gridnd(hermval, c, x, y, z)
1121
1122
1123def hermvander(x, deg):
1124    """Pseudo-Vandermonde matrix of given degree.
1125
1126    Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
1127    `x`. The pseudo-Vandermonde matrix is defined by
1128
1129    .. math:: V[..., i] = H_i(x),
1130
1131    where ``0 <= i <= deg``. The leading indices of `V` index the elements of
1132    `x` and the last index is the degree of the Hermite polynomial.
1133
1134    If `c` is a 1-D array of coefficients of length ``n + 1`` and `V` is the
1135    array ``V = hermvander(x, n)``, then ``np.dot(V, c)`` and
1136    ``hermval(x, c)`` are the same up to roundoff. This equivalence is
1137    useful both for least squares fitting and for the evaluation of a large
1138    number of Hermite series of the same degree and sample points.
1139
1140    Parameters
1141    ----------
1142    x : array_like
1143        Array of points. The dtype is converted to float64 or complex128
1144        depending on whether any of the elements are complex. If `x` is
1145        scalar it is converted to a 1-D array.
1146    deg : int
1147        Degree of the resulting matrix.
1148
1149    Returns
1150    -------
1151    vander : ndarray
1152        The pseudo-Vandermonde matrix. The shape of the returned matrix is
1153        ``x.shape + (deg + 1,)``, where The last index is the degree of the
1154        corresponding Hermite polynomial.  The dtype will be the same as
1155        the converted `x`.
1156
1157    Examples
1158    --------
1159    >>> import numpy as np
1160    >>> from numpy.polynomial.hermite import hermvander
1161    >>> x = np.array([-1, 0, 1])
1162    >>> hermvander(x, 3)
1163    array([[ 1., -2.,  2.,  4.],
1164           [ 1.,  0., -2., -0.],
1165           [ 1.,  2.,  2., -4.]])
1166
1167    """
1168    ideg = pu._as_int(deg, "deg")
1169    if ideg < 0:
1170        raise ValueError("deg must be non-negative")
1171
1172    x = np.array(x, copy=None, ndmin=1) + 0.0
1173    dims = (ideg + 1,) + x.shape
1174    dtyp = x.dtype
1175    v = np.empty(dims, dtype=dtyp)
1176    v[0] = x * 0 + 1
1177    if ideg > 0:
1178        x2 = x * 2
1179        v[1] = x2
1180        for i in range(2, ideg + 1):
1181            v[i] = (v[i - 1] * x2 - v[i - 2] * (2 * (i - 1)))
1182    return np.moveaxis(v, 0, -1)
1183
1184
1185def hermvander2d(x, y, deg):
1186    """Pseudo-Vandermonde matrix of given degrees.
1187
1188    Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
1189    points ``(x, y)``. The pseudo-Vandermonde matrix is defined by
1190
1191    .. math:: V[..., (deg[1] + 1)*i + j] = H_i(x) * H_j(y),
1192
1193    where ``0 <= i <= deg[0]`` and ``0 <= j <= deg[1]``. The leading indices of
1194    `V` index the points ``(x, y)`` and the last index encodes the degrees of
1195    the Hermite polynomials.
1196
1197    If ``V = hermvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
1198    correspond to the elements of a 2-D coefficient array `c` of shape
1199    (xdeg + 1, ydeg + 1) in the order
1200

Showing the first 1,200 of 1739 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai