Skip to content

Hermite Polynomials

Polynomials in Hermite polynomial basis basis.

\[ h(x) = \sum_{k=0}^nh_kH_k(x) \qquad H = (H_n)_{n\in\mathbb{N}_0} = (H_0, H_1, H_2, \dots) \]

Polynomial results are returned in Hermite polynomial basis \(H\), if not stated otherwise.

Integers are used where possible, for multiplications and for divisions like in hermantider. Fractions are used where this was not possible, for example when a rational value has to be defined in hermx.

creation

H0 = (1,)

Zero-th Hermite polynomial in standard monomial basis.

\[ H_0(x)=1 \qquad H_0^{(P)}=\begin{pmatrix} 1 \end{pmatrix} \]

A tuple with a single one: (1,).

See also
  • other constants: H1, H2
  • for any degree: herm

H1 = (0, 2)

First Hermite polynomial in standard monomial basis.

\[ H_1(x)=2x \qquad H_1^{(P)}=\begin{pmatrix} 0 \\ 2 \end{pmatrix} \]

A tuple with a zero and a two: (0, 2).

See also
  • other constants: H0, H2
  • for any degree: herm

H2 = (-2, 0, 4)

Second Hermite polynomial in standard monomial basis.

\[ H_2(x)=4x^2-2 \qquad H_2^{(P)}=\begin{pmatrix} -2 \\ 0 \\ 4 \end{pmatrix} \]

A tuple with a negative two, a zero and a four: (-2, 0, 4).

See also
  • other constants: H0, H1
  • for any degree: herm

herm(n, method='iterative')

Return the n-th Hermite polynomial in standard monomial basis.

\[ H_n^{(P)} \]

Available methods are

Notes

numpy.polynomial.hermite.herm2poly(vecbasis(n)) differs at \(n\geq29\).

See also
Source code in poly\hermite\creation.py
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
def herm(n, method='iterative'):
    r"""Return the `n`-th Hermite polynomial in standard monomial basis.

    $$
        H_n^{(P)}
    $$

    Available methods are

    - [`recursive`][poly.hermite.creation.herm_recursive],
    - [`iterative`][poly.hermite.creation.herm_iterative] &
    - [`explicit`][poly.hermite.creation.herm_explicit].

    Notes
    -----
    [`numpy.polynomial.hermite.herm2poly(vecbasis(n))`](https://numpy.org/doc/stable/reference/generated/numpy.polynomial.hermite.herm2poly.html) differs at $n\geq29$.

    See also
    --------
    - constants: [`H0`][poly.hermite.creation.H0], [`H1`][poly.hermite.creation.H1], [`H2`][poly.hermite.creation.H2]
    - implementations: [`herm_recursive`][poly.hermite.creation.herm_recursive],
    [`herm_iterative`][poly.hermite.creation.herm_iterative],
    [`herm_explicit`][poly.hermite.creation.herm_explicit]
    - for all Hermite polynomials: [`herms`][poly.hermite.creation.herms]
    """
    match method:
        case 'recursive':
            return herm_recursive(n)
        case 'iterative':
            return herm_iterative(n)
        case 'explicit':
            return herm_explicit(n)
        case _:
            raise ValueError('Invalid method')

herm_recursive(n)

Return the n-th Hermite polynomial in standard monomial basis.

\[ H_n^{(P)} \]

Uses the recurrence relation \(H_n(x)=2xH_{n-1}(x)-2(n-1)H_{n-2}(x)\) recursively.

Cached, therefore fast if used repeatedly.

See also
References
Source code in poly\hermite\creation.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
@cache
def herm_recursive(n):
    """Return the `n`-th Hermite polynomial in standard  monomial basis.

    $$
        H_n^{(P)}
    $$

    Uses the recurrence relation $H_n(x)=2xH_{n-1}(x)-2(n-1)H_{n-2}(x)$ recursively.

    Cached, therefore fast if used repeatedly.

    See also
    --------
    - for any implementation: [`herm`][poly.hermite.creation.herm]
    - other implementations: [`herm_iterative`][poly.hermite.creation.herm_iterative],
    [`herm_explicit`][poly.hermite.creation.herm_explicit]

    References
    ----------
    - [Wikipedia - Hermite polynomials - Recurrence relation](https://en.wikipedia.org/wiki/Hermite_polynomials#Recurrence_relation)
    """
    if n == 0:
        return H0
    elif n == 1:
        return H1
    else:
        return polyscalarmul(2, polysub(polymulx(herm_recursive(n-1)),
                                        polyscalarmul(n-1, herm_recursive(n-2))))

herm_iterative(n)

Return the n-th Hermite polynomial in standard monomial basis.

\[ H_n^{(P)} \]

Uses the recurrence relation \(H_n(x)=2xH_{n-1}(x)-2(n-1)H_{n-2}(x)\) iteratively.

See also
References
Source code in poly\hermite\creation.py
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
def herm_iterative(n):
    """Return the `n`-th Hermite polynomial in standard  monomial basis.

    $$
        H_n^{(P)}
    $$

    Uses the recurrence relation $H_n(x)=2xH_{n-1}(x)-2(n-1)H_{n-2}(x)$ iteratively.

    See also
    --------
    - for any implementation: [`herm`][poly.hermite.creation.herm]
    - other implementations: [`herm_recursive`][poly.hermite.creation.herm_recursive],
    [`herm_explicit`][poly.hermite.creation.herm_explicit]
    - uses: [`herms`][poly.hermite.creation.herms]

    References
    ----------
    - [Wikipedia - Hermite polynomials - Recurrence relation](https://en.wikipedia.org/wiki/Hermite_polynomials#Recurrence_relation)
    """
    return next(islice(herms(), n, None))

herm_explicit(n)

Return the n-th Hermite polynomial in standard monomial basis.

\[ H_n^{(P)} \]

Uses the explicit expression \(H_n(x)=n!\sum_{m=0}^{\lfloor\frac{n}{2}\rfloor}\frac{(-1)^m}{m!(n-2m)!}(2x)^{n-2m}\).

Notes

The leading coefficient of the \(n\)-th Hermite polynomial is \(2^n\).

Every second coefficient is zero.

Every other one is set by \(n!\sum_{m=0}^{\lfloor\frac{n}{2}\rfloor}\frac{(-1)^m}{m!(n-2m)!}(2x)^{n-2m}\) resulting in

\[ \begin{aligned} a_{n, n-2m} &= n!2^{n-2m}\frac{(-1)^m}{m!(n-2m)!} &&\mid i=n-2m \Leftrightarrow m=\frac{n-i}{2} \\ a_{n, i} &= n!2^i\frac{(-1)^\frac{n-i}{2}}{\frac{n-i}{2}!i!} \end{aligned} \]

and following the recursion relation

\[ \begin{aligned} \frac{a_{n, i}}{a_{n, i+2}} &= \frac{n!2^i\frac{(-1)^\frac{n-i}{2}}{\frac{n-i}{2}!i!}}{n!2^{i+2}\frac{(-1)^\frac{n-i-2}{2}}{\frac{n-i-2}{2}!(i+2)!}} \\ &= \frac{n!2^i(-1)^\frac{n-i}{2}\frac{n-i-2}{2}!(i+2)!}{n!2^{i+2}(-1)^\frac{n-i-2}{2}\frac{n-i}{2}!i!} \\ &= -\frac{(i+1)(i+2)}{2(n-i)} \\ &= -\frac{(n-2m+1)(n-2m+2)}{2(n-n+2m)} \\ &= -\frac{(n-2m+1)(n-2m+2)}{4m} \end{aligned} \]

which allows setting the coefficients in descending order iteratively without factorials.

See also
References
Source code in poly\hermite\creation.py
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
def herm_explicit(n):
    r"""Return the `n`-th Hermite polynomial in standard  monomial basis.

    $$
        H_n^{(P)}
    $$

    Uses the explicit expression $H_n(x)=n!\sum_{m=0}^{\lfloor\frac{n}{2}\rfloor}\frac{(-1)^m}{m!(n-2m)!}(2x)^{n-2m}$.

    Notes
    -----
    The leading coefficient of the $n$-th Hermite polynomial is $2^n$.

    Every second coefficient is zero.

    Every other one is set by $n!\sum_{m=0}^{\lfloor\frac{n}{2}\rfloor}\frac{(-1)^m}{m!(n-2m)!}(2x)^{n-2m}$ resulting in

    $$
        \begin{aligned}
            a_{n, n-2m} &= n!2^{n-2m}\frac{(-1)^m}{m!(n-2m)!} &&\mid i=n-2m \Leftrightarrow m=\frac{n-i}{2} \\
            a_{n, i} &= n!2^i\frac{(-1)^\frac{n-i}{2}}{\frac{n-i}{2}!i!}
        \end{aligned}
    $$

    and following the recursion relation

    $$
        \begin{aligned}
            \frac{a_{n, i}}{a_{n, i+2}} &= \frac{n!2^i\frac{(-1)^\frac{n-i}{2}}{\frac{n-i}{2}!i!}}{n!2^{i+2}\frac{(-1)^\frac{n-i-2}{2}}{\frac{n-i-2}{2}!(i+2)!}} \\
            &= \frac{n!2^i(-1)^\frac{n-i}{2}\frac{n-i-2}{2}!(i+2)!}{n!2^{i+2}(-1)^\frac{n-i-2}{2}\frac{n-i}{2}!i!} \\
            &= -\frac{(i+1)(i+2)}{2(n-i)} \\
            &= -\frac{(n-2m+1)(n-2m+2)}{2(n-n+2m)} \\
            &= -\frac{(n-2m+1)(n-2m+2)}{4m}
        \end{aligned}
    $$

    which allows setting the coefficients in descending order iteratively without factorials.

    See also
    --------
    - for any implementation: [`herm`][poly.hermite.creation.herm]
    - other implementations: [`herm_recursive`][poly.hermite.creation.herm_recursive],
    [`herm_iterative`][poly.hermite.creation.herm_iterative]

    References
    ----------
    - [Wikipedia - Hermite polynomials - Explicit expression](https://en.wikipedia.org/wiki/Hermite_polynomials#Explicit_expression)
    """
    r = [0] * (n+1)
    r[-1] = 2**n
    for m in range(1, n//2+1):
        r[n-2*m] = -r[n-2*(m-1)] * (n-2*m+1)*(n-2*m+2) // (4*m)
    return tuple(r)

herms()

Yield the Hermite polynomials in standard monomial basis.

\[ (H_n^{(P)})_{n\in\mathbb{N}_0} = (H_0^{(P)}, H_2^{(P)}, H_2^{(P)}, \dots) \]

Uses the recurrence relation \(H_n(x)=2xH_{n-1}(x)-2(n-1)H_{n-2}(x)\) iteratively.

See also
References
Source code in poly\hermite\creation.py
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
def herms():
    r"""Yield the Hermite polynomials in standard monomial basis.

    $$
        (H_n^{(P)})_{n\in\mathbb{N}_0} = (H_0^{(P)}, H_2^{(P)}, H_2^{(P)}, \dots)
    $$

    Uses the recurrence relation $H_n(x)=2xH_{n-1}(x)-2(n-1)H_{n-2}(x)$ iteratively.

    See also
    --------
    - used in: [`herm_iterative`][poly.hermite.herm_iterative]

    References
    ----------
    - [Wikipedia - Hermite polynomials - Recurrence relation](https://en.wikipedia.org/wiki/Hermite_polynomials#Recurrence_relation)
    """
    yield (Hkm1 := H0)
    yield (Hk := H1)
    for km1 in count(1):
        Hkm1, Hk = Hk, polyscalarmul(2, polysub(polymulx(Hk), polyscalarmul(km1, Hkm1)))
        yield Hk

hermzero = veczero

Zero Hermite polynomial series.

\[ 0 \qquad 0^{(H)}=\vec{0} \]

An empty tuple: ().

See also
References

hermone = (1,)

Constant one Hermite polynomial series.

\[ 1=H_0 \qquad 1^{(H)}=\begin{pmatrix} 1 \end{pmatrix} \]

A tuple with a single one: (1,).

Notes

A Fraction tuple ((Fraction(1), )) would be more consitent with hermx, but would then require Fraction arithmetic for multiplicative functions, (hermmul, hermpow).

See also
References

hermx = (Fraction(0), Fraction(1, 2))

Identity Hermite polynomial series.

\[ x=\frac{1}{2}H_1(x) \qquad x^{(H)}=\begin{pmatrix} 0 \\ \frac{1}{2} \end{pmatrix} \]

A tuple with a zero and a half: (0, 1/2).

See also
References

hermmono(n, method='explicit')

Return x^n as Hermite polynomial series.

\[ (x^n)^{(H)} \]

The result is a tuple of Fractions.

Available methods are:

See also
Source code in poly\hermite\creation.py
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
def hermmono(n, method='explicit'):
    """Return `x^n` as Hermite polynomial series.

    $$
        (x^n)^{(H)}
    $$

    The result is a tuple of `Fraction`s.

    Available methods are:

    - [`recursive`][poly.hermite.creation.hermmono_recursive],
    - [`iterative`][poly.hermite.creation.hermmono_iterative] &
    - [`explicit`][poly.hermite.creation.hermmono_explicit].

    See also
    --------
    - constants: [`hermzero`][poly.hermite.creation.hermzero], [`hermone`][poly.hermite.creation.hermone], [`hermx`][poly.hermite.creation.hermx]
    - implementations: [`hermmono_recursive`][poly.hermite.creation.hermmono_recursive],
    [`hermmono_iterative`][poly.hermite.creation.hermmono_iterative],
    [`hermmono_explicit`][poly.hermite.creation.hermmono_explicit]
    - for all monomials: [`hermmonos`][poly.hermite.creation.hermmonos]
    """
    match method:
        case 'recursive':
            return hermmono_recursive(n)
        case 'iterative':
            return hermmono_iterative(n)
        case 'explicit':
            return hermmono_explicit(n)
        case _:
            raise ValueError('Invalid method')

hermmono_recursive(n)

Return x^n as Hermite polynomial series.

\[ x^n \]

Uses hermmulx recursively.

Cached, therefore fast if used repeatedly.

The result is a tuple of Fractions.

See also
Source code in poly\hermite\creation.py
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
@cache
def hermmono_recursive(n):
    """Return `x^n` as Hermite polynomial series.

    $$
        x^n
    $$

    Uses [`hermmulx`][poly.hermite.arithmetic.hermmulx] recursively.

    Cached, therefore fast if used repeatedly.

    The result is a tuple of `Fraction`s.

    See also
    --------
    - for any implementation: [`hermmono`][poly.hermite.creation.hermmono]
    - other implementations: [`hermmono_iterative`][poly.hermite.creation.hermmono_iterative],
    [`hermmono_explicit`][poly.hermite.creation.hermmono_explicit]
    """
    if n == 0:
        return (Fraction(1),) #hermone but as `Fraction`
    return hermmulx(hermmono_recursive(n-1))

hermmono_iterative(n)

Return x^n as Hermite polynomial series.

\[ x^n \]

Uses hermmulx iteratively.

The result is a tuple of Fractions.

See also
Source code in poly\hermite\creation.py
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
def hermmono_iterative(n):
    """Return `x^n` as Hermite polynomial series.

    $$
        x^n
    $$

    Uses [`hermmulx`][poly.hermite.arithmetic.hermmulx] iteratively.

    The result is a tuple of `Fraction`s.

    See also
    --------
    - for any implementation: [`hermmono`][poly.hermite.creation.hermmono]
    - other implementations: [`hermmono_recursive`][poly.hermite.creation.hermmono_recursive],
    [`hermmono_explicit`][poly.hermite.creation.hermmono_explicit]
    - uses: [`hermmonos`][poly.hermite.creation.hermmonos]
    """
    return next(hermmonos(n))

hermmono_explicit(n)

Return x^n as Hermite polynomial series.

\[ x^n \]

Uses the explicit expression \(x^n=\frac{n!}{2^n}\sum_{m=0}^{\lfloor\frac{n}{2}\rfloor}\frac{1}{m!(n-2m)!}H_{n-2m}(x)\).

The result is a tuple of Fractions.

Notes

The leading coefficient is \(\frac{1}{2^n}\).

Every second coefficient is zero.

Every other one is set by \(x^n=\frac{n!}{2^n}\sum_{m=0}^{\lfloor\frac{n}{2}\rfloor}\frac{H_{n-2m}(x)}{m!(n-2m)!}\) resulting in

\[ \begin{aligned} a^{-1}_{n, n-2m} &= \frac{n!}{2^nm!(n-2m)!} &&\mid i=n-2m \Leftrightarrow m=\frac{n-i}{2} \\ a^{-1}_{n, i} &= \frac{n!}{2^n\frac{n-i}{2}!i!} \end{aligned} \]

and following the recursion relation

\[ \begin{aligned} \frac{a_{n, i}}{a_{n, i+2}} &= \frac{\frac{n!}{2^n\frac{n-i}{2}!i!}}{\frac{n!}{2^n\frac{n-i-2}{2}!(i+2)!}} \\ &= \frac{n!2^n\frac{n-i-2}{2}!(i+2)!}{n!2^n\frac{n-i}{2}!i!} \\ &= \frac{2(i+1)(i+2))}{n-i} \\ &= \frac{2(n-2m+1)(n-2m+2))}{n-n-2m} \\ &= -\frac{(n-2m+1)(n-2m+2))}{m} \end{aligned} \]

which allows setting the coefficients in descending order iteratively without factorials.

See also
References
Source code in poly\hermite\creation.py
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
def hermmono_explicit(n):
    r"""Return `x^n` as Hermite polynomial series.

    $$
        x^n
    $$

    Uses the explicit expression $x^n=\frac{n!}{2^n}\sum_{m=0}^{\lfloor\frac{n}{2}\rfloor}\frac{1}{m!(n-2m)!}H_{n-2m}(x)$.

    The result is a tuple of `Fraction`s.

    Notes
    -----
    The leading coefficient is $\frac{1}{2^n}$.

    Every second coefficient is zero.

    Every other one is set by $x^n=\frac{n!}{2^n}\sum_{m=0}^{\lfloor\frac{n}{2}\rfloor}\frac{H_{n-2m}(x)}{m!(n-2m)!}$ resulting in

    $$
        \begin{aligned}
            a^{-1}_{n, n-2m} &= \frac{n!}{2^nm!(n-2m)!} &&\mid i=n-2m \Leftrightarrow m=\frac{n-i}{2} \\
            a^{-1}_{n, i} &= \frac{n!}{2^n\frac{n-i}{2}!i!}
        \end{aligned}
    $$

    and following the recursion relation

    $$
        \begin{aligned}
            \frac{a_{n, i}}{a_{n, i+2}} &= \frac{\frac{n!}{2^n\frac{n-i}{2}!i!}}{\frac{n!}{2^n\frac{n-i-2}{2}!(i+2)!}} \\
            &= \frac{n!2^n\frac{n-i-2}{2}!(i+2)!}{n!2^n\frac{n-i}{2}!i!} \\
            &= \frac{2(i+1)(i+2))}{n-i} \\
            &= \frac{2(n-2m+1)(n-2m+2))}{n-n-2m} \\
            &= -\frac{(n-2m+1)(n-2m+2))}{m}
        \end{aligned}
    $$

    which allows setting the coefficients in descending order iteratively without factorials.

    See also
    --------
    - for any implementation: [`hermmono`][poly.hermite.creation.hermmono]
    - other implementations: [`hermmono_recursive`][poly.hermite.creation.hermmono_recursive],
    [`hermmono_explicit`][poly.hermite.creation.hermmono_explicit]

    References
    ----------
    - [Wikipedia - Hermite polynomials - Inverse explicit expression](https://en.wikipedia.org/wiki/Hermite_polynomials#Inverse_explicit_expression)
    """
    r = [Fraction()] * (n + 1)
    r[n] = Fraction(1, 2**n)
    for m in range(1, n//2+1):
        r[n-2*m] = r[n-2*(m-1)] * ((n-2*m+1)*(n-2*m+2)) / m
    return tuple(r)

hermmonos(start=0)

Yield standard monomials x^n as Hermite polynomial series.

\[ \left(x^n\right)_{n\in\mathbb{N}_0} = (1, x, x^2, \dots) \]

Uses hermmulx iteratively.

See also
Source code in poly\hermite\creation.py
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
def hermmonos(start=0):
    r"""Yield standard monomials `x^n` as Hermite polynomial series.

    $$
        \left(x^n\right)_{n\in\mathbb{N}_0} = (1, x, x^2, \dots)
    $$

    Uses [`hermmulx`][poly.hermite.arithmetic.hermmulx] iteratively.

    See also
    --------
    - used in: [`hermmono_iterative`][poly.hermite.creation.hermmono_iterative]
    """
    h = (Fraction(1),) #hermone but as `Fraction`
    for _ in range(start):
        h = hermmulx(h)
    yield h
    for _ in count(start):
        h = hermmulx(h)
        yield h

hermrand(n)

Return a random Hermite polynomial series of degree n.

\[ \sum_{k=0}^na_kH_k(x) \quad a_k\sim\mathcal{U}([0, 1[) \]

The coefficients are sampled from a uniform distribution in [0, 1[.

See also
Source code in poly\hermite\creation.py
445
446
447
448
449
450
451
452
453
454
455
456
457
458
def hermrand(n):
    r"""Return a random Hermite polynomial series of degree `n`.

    $$
        \sum_{k=0}^na_kH_k(x) \quad a_k\sim\mathcal{U}([0, 1[)
    $$

    The coefficients are sampled from a uniform distribution in `[0, 1[`.

    See also
    --------
    - wraps: [`vector.vecrand`](https://goessl.github.io/vector/functional/#vector.functional.creation.vecrand)
    """
    return vecrand(n+1)

hermrandn(n, normed=True, mu=0, sigma=1)

Return a random Hermite polynomial series of degree n.

\[ \sum_{k=0}^na_kH_k(x) \quad a_k\sim\mathcal{N}(\mu, \sigma) \]

The coefficients are sampled from a normal distribution.

Normed with respect to the Hermite polynomial norm \(\int_\mathbb{R}h^2(x)e^{-x^2}\,\mathrm{d}x\).

See also
Source code in poly\hermite\creation.py
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
def hermrandn(n, normed=True, mu=0, sigma=1):
    r"""Return a random Hermite polynomial series of degree `n`.

    $$
        \sum_{k=0}^na_kH_k(x) \quad a_k\sim\mathcal{N}(\mu, \sigma)
    $$

    The coefficients are sampled from a normal distribution.

    Normed with respect to the Hermite polynomial norm $\int_\mathbb{R}h^2(x)e^{-x^2}\,\mathrm{d}x$.

    See also
    --------
    - wraps: [`vector.vecrandn`](https://goessl.github.io/vector/functional/#vector.functional.creation.vecrandn)
    """
    return vecrandn(n+1, normed=normed, mu=mu, sigma=sigma, weights=hermweights())

hermfromroots(*xs)

Return the Hermite polynomial series with the given roots.

\[ \prod_k(x-x_k) \]
Source code in poly\hermite\creation.py
477
478
479
480
481
482
483
484
def hermfromroots(*xs):
    r"""Return the Hermite polynomial series with the given roots.

    $$
        \prod_k(x-x_k)
    $$
    """
    return hermmul(*zip(map(neg, xs), repeat(Fraction(1, 2))))

utility

hermdeg(h)

Return the degree of a Hermite polynomial series.

\[ \deg(h) \]

\(\deg(0)=-1\) is used for the empty zero Hermite polynomial series.

Doesn't handle leading zeros, use hermtrim if needed.

Notes

\(\deg(0)=-\infty\) is more commonly used but the expected return type is an int and -math.inf is of type float. Therefore the \(\deg(0)=-1\) convention was choosen to keep the return type consistent.

See also
References
Source code in poly\hermite\utility.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def hermdeg(h):
    r"""Return the degree of a Hermite polynomial series.

    $$
        \deg(h)
    $$

    $\deg(0)=-1$ is used for the empty zero Hermite polynomial series.

    Doesn't handle leading zeros, use
    [`hermtrim`][poly.hermite.hermtrim] if needed.

    Notes
    -----
    $\deg(0)=-\infty$ is more commonly used but the expected return type is an
    `int` and `-math.inf` is of type `float`. Therefore the $\deg(0)=-1$
    convention was choosen to keep the return type consistent.

    See also
    --------
    - wraps: [`vector.veclen`](https://goessl.github.io/vector/functional/#vector.functional.utility.veclen)

    References
    ----------
    - [Wikipedia - Degree of a polynomial - Degree of the zero polynomial](https://en.wikipedia.org/wiki/Degree_of_a_polynomial#Degree_of_the_zero_polynomial)
    """
    return veclen(h) - 1

hermeq(g, h)

Return if two Hermite polynomial series are equal.

\[ g \overset{?}{=} h \]
See also
Source code in poly\hermite\utility.py
37
38
39
40
41
42
43
44
45
46
47
48
def hermeq(g, h):
    r"""Return if two Hermite polynomial series are equal.

    $$
        g \overset{?}{=} h
    $$

    See also
    --------
    - wraps: [`vector.veceq`](https://goessl.github.io/vector/functional/#vector.functional.veceq)
    """
    return veceq(g, h)

hermtrim(h, tol=1e-09)

Remove all leading near zero (abs(h_i)<=tol) coefficients.

\[ \sum_{k=0}^nh_kH_k \ \text{where} \ n=\max\{\, k\mid |a_k|>\text{tol}\,\}\cup\{-1\} \]
See also
References
Source code in poly\hermite\utility.py
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
def hermtrim(h, tol=1e-9):
    r"""Remove all leading near zero (`abs(h_i)<=tol`) coefficients.

    $$
        \sum_{k=0}^nh_kH_k \ \text{where} \ n=\max\{\, k\mid |a_k|>\text{tol}\,\}\cup\{-1\}
    $$

    See also
    --------
    - wraps: [`vector.vectrim`](https://goessl.github.io/vector/functional/#vector.functional.vectrim)

    References
    ----------
    - `numpy` equivalent: [`numpy.polynomial.hermite.hermtrim`](https://numpy.org/doc/stable/reference/generated/numpy.polynomial.hermite.hermtrim.html)
    """
    return vectrim(h, tol)

evaluation

hermval(h, x, method='clenshaw')

Return the value of Hermite polynomial series h evaluated at point x.

\[ h(x) \]

Available methods are

See also
References
Source code in poly\hermite\evaluation.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
def hermval(h, x, method='clenshaw'):
    """Return the value of Hermite polynomial series `h` evaluated at point `x`.

    $$
        h(x)
    $$

    Available methods are

    - [`naive`][poly.hermite.hermval_naive],
    - [`iterative`][poly.hermite.hermval_iterative] &
    - [`clenshaw`][poly.hermite.hermval_clenshaw] (`h` must be reversible).

    See also
    --------
    - implementations: [`hermval_naive`][poly.hermite.hermval_naive],
    [`hermval_iterative`][poly.hermite.hermval_iterative],
    [`hermval_clenshaw`][poly.hermite.hermval_clenshaw]
    - in standard monomial basis: [`polyval`][poly.standard.polyval]

    References
    ----------
    - `numpy` equivalent: [`numpy.polynomial.hermite.hermval`](https://numpy.org/doc/stable/reference/generated/numpy.polynomial.hermite.hermval.html)
    """
    match method:
        case 'naive':
            return hermval_naive(h, x)
        case 'iterative':
            return hermval_iterative(h, x)
        case 'clenshaw':
            return hermval_clenshaw(h, x)
        case _:
            raise ValueError('Invalid method')

hermval_naive(h, x)

Return the value of Hermite polynomial series h evaluated at point x.

\[ h(x) \]

Converts \(h\) to standard monomial basis and evaluates with polyval.

See also
Source code in poly\hermite\evaluation.py
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
def hermval_naive(h, x):
    """Return the value of Hermite polynomial series `h` evaluated at point `x`.

    $$
        h(x)
    $$

    Converts $h$ to standard monomial basis and evaluates with [`polyval`][poly.standard.polyval].

    See also
    --------
    - for any implementation: [`hermval`][poly.hermite.hermval]
    - other implementations: [`hermval_iterative`][poly.hermite.hermval_iterative],
    [`hermval_clenshaw`][poly.hermite.hermval_clenshaw]
    - in standard monomial basis: [`polyval_naive`][poly.standard.polyval_naive]
    """
    return polyval(herm2poly(h), x)

hermval_iterative(h, x)

Return the value of Hermite polynomial series h evaluated at point x.

\[ h(x) \]

Uses iterative \(H_n(x)\) generation.

See also
Source code in poly\hermite\evaluation.py
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
def hermval_iterative(h, x):
    """Return the value of Hermite polynomial series `h` evaluated at point `x`.

    $$
        h(x)
    $$

    Uses iterative $H_n(x)$ generation.

    See also
    --------
    - for any implementation: [`hermval`][poly.hermite.hermval]
    - other implementations: [`hermval_naive`][poly.hermite.hermval_naive],
    [`hermval_clenshaw`][poly.hermite.hermval_clenshaw]
    - uses: [`hermvals`][poly.hermite.hermvals]
    - in standard monomial basis: [`polyval_iterative`][poly.standard.polyval_iterative]
    """
    return vecdot(h, hermvals(x), zero=type(x)(0))

hermval_clenshaw(h, x)

Return the value of Hermite polynomial series h evaluated at point x.

\[ h(x) \]

Uses the Clenshaw algorithm.

h must be reversible.

See also
References
Source code in poly\hermite\evaluation.py
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def hermval_clenshaw(h, x):
    """Return the value of Hermite polynomial series `h` evaluated at point `x`.

    $$
        h(x)
    $$

    Uses the Clenshaw algorithm.

    `h` must be reversible.

    See also
    --------
    - for any implementation: [`hermval`][poly.hermite.hermval]
    - other implementations: [`hermval_naive`][poly.hermite.hermval_naive],
    [`hermval_iterative`][poly.hermite.hermval_iterative]
    - in standard monomial basis: [`polyval_horner`][poly.standard.polyval_horner]

    References
    ----------
    - [Wikipedia - Clenshaw algorithm](https://en.wikipedia.org/wiki/Clenshaw_algorithm)
    """
    h = tuple(h)
    if not h:
        return type(x)(0)
    a, b = 0, 0
    for n, hn in reversed(tuple(enumerate(h[1:], 1))):
        a, b = hn + 2*x*a - 2*(n+1)*b, a
    return h[0] + 2*x*a - 2*b

hermvals(x)

Yield the values of Hermite polynomials evaluated at point x.

\[ (H_n(x))_{n\in\mathbb{N}_0} = (H_0(x), H_1(x), H_2(x), \dots) \]

Uses the recurrence relation \(H_n(x)=2xH_{n-1}(x)-2(n-1)H_{n-2}(x)\) iteratively.

See also
References
Source code in poly\hermite\evaluation.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
def hermvals(x):
    r"""Yield the values of Hermite polynomials evaluated at point `x`.

    $$
        (H_n(x))_{n\in\mathbb{N}_0} = (H_0(x), H_1(x), H_2(x), \dots)
    $$

    Uses the recurrence relation $H_n(x)=2xH_{n-1}(x)-2(n-1)H_{n-2}(x)$ iteratively.

    See also
    --------
    - used in: [`hermval_iterative`][poly.hermite.hermval_iterative]

    References
    ----------
    - [Wikipedia - Hermite polynomials - Recurrence relation](https://en.wikipedia.org/wiki/Hermite_polynomials#Recurrence_relation)
    """
    yield (Hkm1 := type(x)(1))
    yield (Hk := 2*x)
    for k in count(1):
        Hkm1, Hk = Hk, 2*(Hk*x - k*Hkm1)
        yield Hk

hermvalzeros()

Yield the values of Hermite polynomials evaluated at point 0.

\[ (H_n(0))_{n\in\mathbb{N}_0} = (H_0(0), H_1(0), H_2(0), \dots) \]
Notes
\[ \begin{gathered} H_n(0) = \begin{cases} 0 & n\in\mathbb{U} \\ (-2)^\frac{n}{2}(n-1)!! & n\in\mathbb{G} \end{cases} \\ 1, 0, -2, 0, 12, 0, -120, 0, 1680, 0, -30240, \dots \end{gathered} \]
See also
Source code in poly\hermite\evaluation.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
def hermvalzeros():
    r"""Yield the values of Hermite polynomials evaluated at point 0.

    $$
        (H_n(0))_{n\in\mathbb{N}_0} = (H_0(0), H_1(0), H_2(0), \dots)
    $$

    Notes
    -----
    $$
        \begin{gathered}
            H_n(0) = \begin{cases}
                0 & n\in\mathbb{U} \\
                (-2)^\frac{n}{2}(n-1)!! & n\in\mathbb{G}
            \end{cases} \\
            1, 0, -2, 0, 12, 0, -120, 0, 1680, 0, -30240, \dots
        \end{gathered}
    $$

    See also
    --------
    - for any series: [`hermvalzero`][poly.hermite.hermvalzero]
    """
    yield (y := 1)
    for i in count(1, 2):
        yield 0
        y *= -2 * i
        yield y

hermvalzero(h, zero=0)

Return the value of Hermite polynomial series h evaluated at point 0.

\[ h(0) \]

More efficient than hermval(h, 0).

See also
Source code in poly\hermite\evaluation.py
166
167
168
169
170
171
172
173
174
175
176
177
178
179
def hermvalzero(h, zero=0):
    """Return the value of Hermite polynomial series `h` evaluated at point 0.

    $$
        h(0)
    $$

    More efficient than `hermval(h, 0)`.

    See also
    --------
    - for any point: [`hermval`][poly.hermite.hermval]
    """
    return vecdot(islice(h, 0, None, 2), islice(hermvalzeros(), 0, None, 2), zero=zero)

hilbert_space

hermweight(n)

Return the normalisation factor of Hermite polynomials.

\[ \int_\mathbb{R}H_n^2(x)e^{-x^2}\,\mathrm{d}x = \sqrt{\pi}2^nn! \]
See also
References
Source code in poly\hermite\hilbert_space.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def hermweight(n):
    r"""Return the normalisation factor of Hermite polynomials.

    $$
        \int_\mathbb{R}H_n^2(x)e^{-x^2}\,\mathrm{d}x = \sqrt{\pi}2^nn!
    $$

    See also
    --------
    - for the integral factor: [`hermweighti`][poly.hermite.hermweighti]
    - for all normalisation factors: [`hermweights`][poly.hermite.hermweights]

    References
    ----------
    - [Wikipedia - Hermite polynomials - Orthogonality](https://en.wikipedia.org/wiki/Hermite_polynomials#Orthogonality)
    """
    return sqrt(pi) * hermweighti(n)

hermweights(start=0)

Yield the normalisation factors of Hermite polynomials.

\[ \begin{gathered} \left(\int_\mathbb{R}H_n^2(x)e^{-x^2}\,\mathrm{d}x\right)_{n\in\mathbb{N}_0} = \sqrt{\pi}(2^nn!)_{n\in\mathbb{N}_0} \\ = \sqrt{\pi}(1, 2, 8, 48, 384, 3840, 46080, 645120, \dots) \end{gathered} \]
See also
References
Source code in poly\hermite\hilbert_space.py
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
def hermweights(start=0):
    r"""Yield the normalisation factors of Hermite polynomials.

    $$
        \begin{gathered}
            \left(\int_\mathbb{R}H_n^2(x)e^{-x^2}\,\mathrm{d}x\right)_{n\in\mathbb{N}_0} = \sqrt{\pi}(2^nn!)_{n\in\mathbb{N}_0} \\
            = \sqrt{\pi}(1, 2, 8, 48, 384, 3840, 46080, 645120, \dots)
        \end{gathered}
    $$

    See also
    --------
    - for the integral factors: [`hermweightis`][poly.hermite.hermweightis]
    - for a single normalisation factor: [`hermweight`][poly.hermite.hermweight]

    References
    ----------
    - [Wikipedia - Hermite polynomials - Orthogonality](https://en.wikipedia.org/wiki/Hermite_polynomials#Orthogonality)
    """
    sqrtpi = sqrt(pi)
    for f in hermweightis(start):
        yield sqrtpi * f

hermweighti(n)

Return the integral factor of the normalisation factor of Hermite polynomials.

\[ \frac{1}{\sqrt{\pi}}\int_\mathbb{R}H_n^2(x)e^{-x^2}\,\mathrm{d}x = 2^nn! \]
See also
References
Source code in poly\hermite\hilbert_space.py
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
def hermweighti(n):
    r"""Return the integral factor of the normalisation factor of Hermite polynomials.

    $$
        \frac{1}{\sqrt{\pi}}\int_\mathbb{R}H_n^2(x)e^{-x^2}\,\mathrm{d}x = 2^nn!
    $$

    See also
    --------
    - for the full normalisation factor: [`hermweight`][poly.hermite.hermweight]
    - for all normalisation factors: [`hermweightis`][poly.hermite.hermweightis]

    References
    ----------
    - [Wikipedia - Hermite polynomials - Orthogonality](https://en.wikipedia.org/wiki/Hermite_polynomials#Orthogonality)
    """
    return 2**n * factorial(n)

hermweightis(start=0)

Yield the integral factors of the normalisation factors of Hermite polynomials.

\[ \begin{gathered} \frac{1}{\sqrt{\pi}}\left(\int_\mathbb{R}H_n^2(x)e^{-x^2}\,\mathrm{d}x\right)_{n\in\mathbb{N}_0} = (2^nn!)_{n\in\mathbb{N}_0} \\ = (1, 2, 8, 48, 384, 3840, 46080, 645120, \dots) \end{gathered} \]
See also
References
Source code in poly\hermite\hilbert_space.py
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
def hermweightis(start=0):
    r"""Yield the integral factors of the normalisation factors of Hermite polynomials.

    $$
        \begin{gathered}
            \frac{1}{\sqrt{\pi}}\left(\int_\mathbb{R}H_n^2(x)e^{-x^2}\,\mathrm{d}x\right)_{n\in\mathbb{N}_0} = (2^nn!)_{n\in\mathbb{N}_0} \\
            = (1, 2, 8, 48, 384, 3840, 46080, 645120, \dots)
        \end{gathered}
    $$

    See also
    --------
    - for all full normalisation factors: [`hermweights`][poly.hermite.hermweights]
    - for a single normalisation factor: [`hermweighti`][poly.hermite.hermweighti]

    References
    ----------
    - [Wikipedia - Hermite polynomials - Orthogonality](https://en.wikipedia.org/wiki/Hermite_polynomials#Orthogonality)
    - [A000165](https://oeis.org/A000165)
    """
    yield (f := 2**start * factorial(start))
    for n in count(start+1):
        f *= 2 * n
        yield f

hermabs(h, conjugate=False, zero=0)

Return the norm of a Hermite polynomial series.

\[ ||h||_H = \sqrt{\int_\mathbb{R}h^{(*)}(x)h(x)e^{-x^2}\,\mathrm{d}x} = \sqrt{\sqrt{\pi}\sum_k2^kk!h^{(*)}_kh_k} \]
See also
References
Source code in poly\hermite\hilbert_space.py
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
def hermabs(h, conjugate=False, zero=0):
    r"""Return the norm of a Hermite polynomial series.

    $$
        ||h||_H = \sqrt{\int_\mathbb{R}h^{(*)}(x)h(x)e^{-x^2}\,\mathrm{d}x} = \sqrt{\sqrt{\pi}\sum_k2^kk!h^{(*)}_kh_k}
    $$

    See also
    --------
    - for the norm squared: [`hermabsq`][poly.hermite.hermabsq]
    - similar to: [`vector.vecabs`](https://goessl.github.io/vector/functional/#vector.functional.hilbert_space.vecabs)

    References
    ----------
    - [Wikipedia - Hermite polynomials - Orthogonality](https://en.wikipedia.org/wiki/Hermite_polynomials#Orthogonality)
    """
    return hermabsq(h, conjugate=conjugate, zero=zero)**0.5

hermabsq(h, conjugate=False, zero=0)

Return squared norm of a Hermite polynomial series.

\[ ||h||_H^2 = \int_\mathbb{R}h^{(*)}(x)h(x)e^{-x^2}\,\mathrm{d}x = \sqrt{\pi}\sum_k2^kk!h^{(*)}_kh_k \]
Complexity

For a Hermite polynomial series of degree \(n\) there will be

  • \(n+1\) scalar conjugations (conjugate) (if selected),
  • \(n+1\)/\(2(n+1)\) scalar multiplications (mul) without/with weights &
  • \(\begin{cases}n&n\ge1\\0&n\le1\end{cases}\) scalar additions (add).
See also
References
Source code in poly\hermite\hilbert_space.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
def hermabsq(h, conjugate=False, zero=0):
    r"""Return squared norm of a Hermite polynomial series.

    $$
        ||h||_H^2 = \int_\mathbb{R}h^{(*)}(x)h(x)e^{-x^2}\,\mathrm{d}x = \sqrt{\pi}\sum_k2^kk!h^{(*)}_kh_k
    $$

    Complexity
    ----------
    For a Hermite polynomial series of degree $n$ there will be

    - $n+1$ scalar conjugations (`conjugate`) (if selected),
    - $n+1$/$2(n+1)$ scalar multiplications (`mul`) without/with weights &
    - $\begin{cases}n&n\ge1\\0&n\le1\end{cases}$ scalar additions (`add`).

    See also
    --------
    - for the norm: [`hermabs`][poly.hermite.hermabs]
    - for the integral factor: [`hermabsqi`][poly.hermite.hermabsqi]
    - similar to: [`vector.vecabsq`](https://goessl.github.io/vector/functional/#vector.functional.hilbert_space.vecabsq)

    References
    ----------
    - [Wikipedia - Hermite polynomials - Orthogonality](https://en.wikipedia.org/wiki/Hermite_polynomials#Orthogonality)
    """
    return sqrt(pi) * hermabsqi(h, conjugate=conjugate, zero=zero)

hermabsqi(h, conjugate=False, zero=0)

Return the integral factor of the norm squared of a Hermite polynomial series.

\[ \frac{1}{\sqrt{\pi}}||h||_H^2 = \frac{1}{\sqrt{\pi}}\int_\mathbb{R}h^{(*)}(x)h(x)e^{-x^2}\,\mathrm{d}x = \sum_k2^kk!h^{(*)}_kh_k \]
Complexity

For a Hermite polynomial series of degree \(n\) there will be

  • \(n+1\) scalar conjugations (conjugate) (if selected),
  • \(\begin{cases}n&n\ge0\\0&n\le0\end{cases}\) scalar additions (add) &
  • \(2(n+1)\) scalar multiplications (mul) without/with weights.
See also
References
Source code in poly\hermite\hilbert_space.py
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def hermabsqi(h, conjugate=False, zero=0):
    r"""Return the integral factor of the norm squared of a Hermite polynomial series.

    $$
        \frac{1}{\sqrt{\pi}}||h||_H^2 = \frac{1}{\sqrt{\pi}}\int_\mathbb{R}h^{(*)}(x)h(x)e^{-x^2}\,\mathrm{d}x = \sum_k2^kk!h^{(*)}_kh_k
    $$

    Complexity
    ----------
    For a Hermite polynomial series of degree $n$ there will be

    - $n+1$ scalar conjugations (`conjugate`) (if selected),
    - $\begin{cases}n&n\ge0\\0&n\le0\end{cases}$ scalar additions (`add`) &
    - $2(n+1)$ scalar multiplications (`mul`) without/with weights.

    See also
    --------
    - for the full norm squared: [`hermabsq`][poly.hermite.hermabsq]
    - wraps: [`vector.vecabsq`](https://goessl.github.io/vector/functional/#vector.functional.hilbert_space.vecabsq)

    References
    ----------
    - [Wikipedia - Hermite polynomials - Orthogonality](https://en.wikipedia.org/wiki/Hermite_polynomials#Orthogonality)
    """
    return vecabsq(h, weights=hermweightis(), conjugate=conjugate, zero=zero)

hermdot(g, h, conjugate=False, zero=0)

Return the inner product with respect to the Hermite polynomial weight function.

\[ \left<g\mid h\right>_H = \int_\mathbb{R}g^{(*)}(x)h(x)e^{-x^2}\,\mathrm{d}x = \sqrt{\pi}\sum_k2^kk!g^{(*)}_kh_k \]
Complexity

For two Hermite polynomial series of degrees \(n\) & \(m\) there will be

  • \(\min\{n, m\}+1\) scalar conjugations (conjugate) (if selected),
  • \(\begin{cases}n&n\ge0\\0&n\le0\end{cases}\) scalar additions (add) &
  • \(2(n+1)\) scalar multiplications (mul) without/with weights.
See also
References
Source code in poly\hermite\hilbert_space.py
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
def hermdot(g, h, conjugate=False, zero=0):
    r"""Return the inner product with respect to the Hermite polynomial weight function.

    $$
        \left<g\mid h\right>_H = \int_\mathbb{R}g^{(*)}(x)h(x)e^{-x^2}\,\mathrm{d}x = \sqrt{\pi}\sum_k2^kk!g^{(*)}_kh_k
    $$

    Complexity
    ----------
    For two Hermite polynomial series of degrees $n$ & $m$ there will be

    - $\min\{n, m\}+1$ scalar conjugations (`conjugate`) (if selected),
    - $\begin{cases}n&n\ge0\\0&n\le0\end{cases}$ scalar additions (`add`) &
    - $2(n+1)$ scalar multiplications (`mul`) without/with weights.

    See also
    --------
    - for the integral factor: [`hermdoti`][poly.hermite.hermdoti]

    References
    ----------
    - [Wikipedia - Hermite polynomials - Orthogonality](https://en.wikipedia.org/wiki/Hermite_polynomials#Orthogonality)
    """
    return sqrt(pi) * hermdoti(g, h, conjugate=conjugate, zero=zero)

hermdoti(g, h, conjugate=False, zero=0)

Return the integral factor of the inner product with respect to the Hermite polynomial weight function.

\[ \frac{1}{\sqrt{\pi}}\left<g\mid h\right>_H = \frac{1}{\sqrt{\pi}}\int_\mathbb{R}g^{(*)}(x)h(x)e^{-x^2}\,\mathrm{d}x = \sum_k2^kk!g^{(*)}_kh_k \]
See also
Source code in poly\hermite\hilbert_space.py
193
194
195
196
197
198
199
200
201
202
203
204
205
def hermdoti(g, h, conjugate=False, zero=0):
    r"""Return the integral factor of the inner product with respect to the Hermite polynomial weight function.

    $$
        \frac{1}{\sqrt{\pi}}\left<g\mid h\right>_H = \frac{1}{\sqrt{\pi}}\int_\mathbb{R}g^{(*)}(x)h(x)e^{-x^2}\,\mathrm{d}x = \sum_k2^kk!g^{(*)}_kh_k
    $$

    See also
    --------
    - for the full inner product: [`hermdot`][poly.hermite.hermdot]
    - wraps: [`vector.vecdot`](https://goessl.github.io/vector/functional/#vector.functional.hilbert_space.vecdot)
    """
    return vecdot(g, h, weights=hermweightis(), conjugate=conjugate, zero=zero)

arithmetic

hermpos(h)

Return the Hermite polynomial series with the unary positive operator applied.

\[ +h \]
Complexity

For a Hermite polynomial series of degree \(n\) there will be

  • \(n+1\) scalar unary plus operations (pos).
See also
Source code in poly\hermite\arithmetic.py
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def hermpos(h):
    """Return the Hermite polynomial series with the unary positive operator applied.

    $$
        +h
    $$

    Complexity
    ----------
    For a Hermite polynomial series of degree $n$ there will be

    - $n+1$ scalar unary plus operations (`pos`).

    See also
    --------
    - wraps: [`vector.vecpos`](https://goessl.github.io/vector/functional/#vector.functional.vector_space.vecpos)
    """
    return vecpos(h)

hermneg(h)

Return the Hermite polynomial series with the unary negative operator applied.

\[ -h \]
Complexity

For a Hermite polynomial series of degree \(n\) there will be

  • \(n+1\) scalar negations (neg).
See also
Source code in poly\hermite\arithmetic.py
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def hermneg(h):
    """Return the Hermite polynomial series with the unary negative operator applied.

    $$
        -h
    $$

    Complexity
    ----------
    For a Hermite polynomial series of degree $n$ there will be

    - $n+1$ scalar negations (`neg`).

    See also
    --------
    - wraps: [`vector.vecneg`](https://goessl.github.io/vector/functional/#vector.functional.vector_space.vecneg)
    """
    return vecneg(h)

hermadd(*hs)

Return the sum of Hermite polynomial series.

\[ h_0 + h_1 + \cdots \]
Complexity

For two Hermite polynomial series of degrees \(n\) & \(m\) there will be

  • \(\min\{n, m\}+1\) scalar additions (add).
See also
Source code in poly\hermite\arithmetic.py
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
def hermadd(*hs):
    r"""Return the sum of Hermite polynomial series.

    $$
        h_0 + h_1 + \cdots
    $$

    Complexity
    ----------
    For two Hermite polynomial series of degrees $n$ & $m$ there will be

    - $\min\{n, m\}+1$ scalar additions (`add`).

    See also
    --------
    - for single coefficient summand ($cH_n$): [`hermaddc`][poly.hermite.arithmetic.hermaddc]
    - wraps: [`vector.vecadd`](https://goessl.github.io/vector/functional/#vector.functional.vector_space.vecadd)
    - `numpy` equivalent: [`numpy.polynomial.hermite.hermadd`](https://numpy.org/doc/stable/reference/generated/numpy.polynomial.hermite.hermadd.html)
    """
    return vecadd(*hs)

hermaddc(h, c, n=0)

Return the sum of Hermite polynomial series h and the n-th Hermite polynomial.

\[ h + cH_n \]

More efficient than hermadd(h, vecbasis(n, c)).

Complexity

There will be

  • one scalar addition (add) if \(n\le\deg h\) or
  • one unary plus operations (pos) otherwise.
See also
Source code in poly\hermite\arithmetic.py
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
def hermaddc(h, c, n=0):
    r"""Return the sum of Hermite polynomial series `h` and the `n`-th Hermite polynomial.

    $$
        h + cH_n
    $$

    More efficient than `hermadd(h, vecbasis(n, c))`.

    Complexity
    ----------
    There will be

    - one scalar addition (`add`) if $n\le\deg h$ or
    - one unary plus operations (`pos`) otherwise.

    See also
    --------
    - for series summand: [`hermadd`][poly.hermite.arithmetic.hermadd]
    - wraps: [`vector.vecaddc`](https://goessl.github.io/vector/functional/#vector.functional.vector_space.vecaddc)
    """
    return vecaddc(h, c, n)

hermsub(g, h)

Return the difference of two Hermite polynomial series.

\[ g - h \]
Complexity

For two Hermite polynomial series of degrees \(n\) & \(m\) there will be

  • \(\min\{n, m\}+1\) scalar subtractions (sub) &
  • \(\begin{cases}m-n&m\ge n\\0&m\le n\end{cases}\) negations (neg).
See also
Source code in poly\hermite\arithmetic.py
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
def hermsub(g, h):
    r"""Return the difference of two Hermite polynomial series.

    $$
        g - h
    $$

    Complexity
    ----------
    For two Hermite polynomial series of degrees $n$ & $m$ there will be

    - $\min\{n, m\}+1$ scalar subtractions (`sub`) &
    - $\begin{cases}m-n&m\ge n\\0&m\le n\end{cases}$ negations (`neg`).

    See also
    --------
    - for single coefficient subtrahend ($cH_n$): [`hermaddc`][poly.hermite.arithmetic.hermaddc]
    - wraps: [`vector.vecsub`](https://goessl.github.io/vector/functional/#vector.functional.vector_space.vecsub)
    - `numpy` equivalent: [`numpy.polynomial.hermite.hermsub`](https://numpy.org/doc/stable/reference/generated/numpy.polynomial.hermite.hermsub.html)
    """
    return vecsub(g, h)

hermsubc(h, c, n=0)

Return the difference of Hermite polynomial series h and the n-th Hermite polynomial.

\[ h - cH_n \]

More efficient than hermsub(h, vecbasis(n, c)).

Complexity

There will be

  • one scalar subtraction (sub) if \(n\le\deg h\) or
  • one scalar negation (neg) otherwise.
See also
Source code in poly\hermite\arithmetic.py
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
def hermsubc(h, c, n=0):
    r"""Return the difference of Hermite polynomial series `h` and the `n`-th Hermite polynomial.

    $$
        h - cH_n
    $$

    More efficient than `hermsub(h, vecbasis(n, c))`.

    Complexity
    ----------
    There will be

    - one scalar subtraction (`sub`) if $n\le\deg h$ or
    - one scalar negation (`neg`) otherwise.

    See also
    --------
    - for series minuend: [`hermsub`][poly.hermite.arithmetic.hermsub]
    - wraps: [`vector.vecsubc`](https://goessl.github.io/vector/functional/#vector.functional.vector_space.vecsubc)
    """
    return vecsubc(h, c, n)

hermscalarmul(a, h)

Return the product of a scalar and a Hermite polynomial series.

\[ a\cdot h \]
Complexity

For a Hermite polynomial series of degree \(n\) there will be

  • \(n+1\) scalar multiplications (rmul).
See also
Source code in poly\hermite\arithmetic.py
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
def hermscalarmul(a, h):
    r"""Return the product of a scalar and a Hermite polynomial series.

    $$
        a\cdot h
    $$

    Complexity
    ----------
    For a Hermite polynomial series of degree $n$ there will be

    - $n+1$ scalar multiplications (`rmul`).

    See also
    --------
    - wraps: [`vector.vecmul`](https://goessl.github.io/vector/functional/#vector.functional.vector_space.vecmul)
    """
    return vecmul(a, h)

hermscalartruediv(h, a)

Return the true division of a Hermite polynomial series and a scalar.

\[ \frac{h}{a} \]
Complexity

For a Hermite polynomial series of degree \(n\) there will be

  • \(n+1\) scalar true divisions (truediv).
See also
Source code in poly\hermite\arithmetic.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
def hermscalartruediv(h, a):
    r"""Return the true division of a Hermite polynomial series and a scalar.

    $$
        \frac{h}{a}
    $$

    Complexity
    ----------
    For a Hermite polynomial series of degree $n$ there will be

    - $n+1$ scalar true divisions (`truediv`).

    See also
    --------
    - wraps: [`vector.vectruediv`](https://goessl.github.io/vector/functional/#vector.functional.vector_space.vectruediv)
    """
    return vectruediv(h, a)

hermscalarfloordiv(h, a)

Return the floor division of a Hermite polynomial series and a scalar.

\[ \sum_k\left\lfloor\frac{a_k}{a}\right\rfloor H_k \]
Complexity

For a Hermite polynomial series of degree \(n\) there will be

  • \(n+1\) scalar floor divisions (floordiv).
See also
Source code in poly\hermite\arithmetic.py
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
def hermscalarfloordiv(h, a):
    r"""Return the floor division of a Hermite polynomial series and a scalar.

    $$
        \sum_k\left\lfloor\frac{a_k}{a}\right\rfloor H_k
    $$

    Complexity
    ----------
    For a Hermite polynomial series of degree $n$ there will be

    - $n+1$ scalar floor divisions (`floordiv`).

    See also
    --------
    - wraps: [`vector.vecmfloordiv`](https://goessl.github.io/vector/functional/#vector.functional.vector_space.vecmfloordiv)
    """
    return vecfloordiv(h, a)

hermscalarmod(h, a)

Return the elementwise mod of a Hermite polynomial series and a scalar.

\[ \sum_k\left(a_k \mod a \right)H_k \]
Complexity

For a Hermite polynomial series of degree \(n\) there will be

  • \(n+1\) scalar modulos (mod).
See also
Source code in poly\hermite\arithmetic.py
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
def hermscalarmod(h, a):
    r"""Return the elementwise mod of a Hermite polynomial series and a scalar.

    $$
        \sum_k\left(a_k \mod a \right)H_k
    $$

    Complexity
    ----------
    For a Hermite polynomial series of degree $n$ there will be

    - $n+1$ scalar modulos (`mod`).

    See also
    --------
    - wraps: [`vector.vecmod`](https://goessl.github.io/vector/functional/#vector.functional.vector_space.vecmod)
    """
    return vecmod(h, a)

hermscalardivmod(h, a)

Return the elementwise divmod of a polynomial and a scalar.

\[ \sum_k\left\lfloor\frac{a_k}{a}\right\rfloor H_k, \ \sum_k\left(a_k \mod a \right)H_k \]
Complexity

For a Hermite polynomial series of degree \(n\) there will be

  • \(n+1\) scalar divmods (divmod).
See also
Source code in poly\hermite\arithmetic.py
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
def hermscalardivmod(h, a):
    r"""Return the elementwise divmod of a polynomial and a scalar.

    $$
        \sum_k\left\lfloor\frac{a_k}{a}\right\rfloor H_k, \ \sum_k\left(a_k \mod a \right)H_k
    $$

    Complexity
    ----------
    For a Hermite polynomial series of degree $n$ there will be

    - $n+1$ scalar divmods (`divmod`).

    See also
    --------
    - wraps: [`vector.vecdivmod`](https://goessl.github.io/vector/functional/#vector.functional.vector_space.vecdivmod)
    """
    return vecdivmod(h, a)

hermmul(*hs, method='naive', one=1)

Return the product of Hermite polynomial series.

\[ h_0 h_1 \cdots \]

Available methods are

TODO: Karatsuba possible?

See also
References
Source code in poly\hermite\arithmetic.py
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
def hermmul(*hs, method='naive', one=1):
    r"""Return the product of Hermite polynomial series.

    $$
        h_0 h_1 \cdots
    $$

    Available methods are

    - [`naive`][poly.hermite.hermmul_naive].

    TODO: Karatsuba possible?

    See also
    --------
    - implementations: [`hermmul_naive`][poly.hermite.arithmetic.hermmul_naive]
    - for monomial factor: [`hermmulx`][poly.hermite.arithmetic.hermmulx]
    - for Hermite polynomial factor: [`hermmulHn`][poly.hermite.arithmetic.hermmulHn]

    References
    ----------
    - `numpy` equivalent: [`numpy.polynomial.hermite.hermmul`](https://numpy.org/doc/stable/reference/generated/numpy.polynomial.hermite.hermmul.html)
    """
    hs = tuple(map(tuple, hs))
    match method:
        case 'naive':
            return reduce_default(hermmul_naive, hs, default=(one,))
        case _:
            raise ValueError('Invalid method')

hermmul_naive(g, h)

Return the product of two Hermite polynomials series.

\[ g h \]

Uses naive multiplication and summation.

h must be a sequence.

Complexity

For two Hermite polynomial series of degrees \(n\) & \(m\) (let \(N=\min\{n, m\}\), \(M=\max\{n, m\}\)) there will be

  • \(\begin{cases}\frac{(N+1)(N+2)(3M+3-N)}{6}-(n+m+1) & n\geq0\land m\geq0 \\ 0 & n<0\lor m<0 \end{cases}\) scalar additions (add) &
  • \(\begin{cases}\frac{(N+1)(N+2)(3M+3-N)}{3} & n\geq0\land m\geq0 \\ 0 & n<0\lor m<0 \end{cases}\) scalar multiplications (mul).
Notes

From [1] eq. A.8 we know that

\[ \tilde{H}_i\tilde{H}_j = \sum_{k=0}^{\min\{i,j\}}k!\binom{i}{k}\binom{j}{k}\tilde{H}_{i+j-2k}. \]

Therefore we have

\[ \begin{aligned} &H_i(x)H_j(x) &&\mid H_j(x) = 2^\frac{j}{2}\tilde{H}_j(\sqrt{2}x) \\ &= 2^\frac{i+j}{2} \tilde{H}_i(\sqrt{2}x) \tilde{H}_j(\sqrt{2}x) &&\mid \tilde{H}_i\tilde{H}_j = \sum_{k=0}^{\min\{i, j\}}k!\binom{i}{k}\binom{j}{k}\tilde{H}_{i+j-2k} \\ &= 2^\frac{i+j}{2} \sum_{k=0}^{\min\{i, j\}} k!\binom{i}{k}\binom{j}{k} \tilde{H}_{i+j-2k}(\sqrt{2}x) &&\mid \cdot1=2^{k-k} \\ &= \sum_{k=0}^{\min\{i, j\}} 2^kk!\binom{i}{k}\binom{j}{k}2^\frac{i+j-2k}{2} \tilde{H}_{i+j-2k}(\sqrt{2}x) &&\mid H_j(x)=2^\frac{j}{2} \tilde{H}_j(\sqrt{2}x) \\ &= \sum_{k=0}^{\min\{i, j\}}2^kk!\binom{i}{k}\binom{j}{k} H_{i+j-2k}(x) \end{aligned} \]
See also
References
Source code in poly\hermite\arithmetic.py
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
def hermmul_naive(g, h):
    r"""Return the product of two Hermite polynomials series.

    $$
        g h
    $$

    Uses naive multiplication and summation.

    `h` must be a sequence.

    Complexity
    ----------
    For two Hermite polynomial series of degrees $n$ & $m$ (let $N=\min\{n, m\}$, $M=\max\{n, m\}$) there will be

    - $\begin{cases}\frac{(N+1)(N+2)(3M+3-N)}{6}-(n+m+1) & n\geq0\land m\geq0 \\ 0 & n<0\lor m<0 \end{cases}$ scalar additions (`add`) &
    - $\begin{cases}\frac{(N+1)(N+2)(3M+3-N)}{3} & n\geq0\land m\geq0 \\ 0 & n<0\lor m<0 \end{cases}$ scalar multiplications (`mul`).

    Notes
    -----
    From [1] eq. A.8 we know that

    $$
        \tilde{H}_i\tilde{H}_j = \sum_{k=0}^{\min\{i,j\}}k!\binom{i}{k}\binom{j}{k}\tilde{H}_{i+j-2k}.
    $$

    Therefore we have

    $$
        \begin{aligned}
            &H_i(x)H_j(x) &&\mid H_j(x) = 2^\frac{j}{2}\tilde{H}_j(\sqrt{2}x) \\
            &= 2^\frac{i+j}{2} \tilde{H}_i(\sqrt{2}x) \tilde{H}_j(\sqrt{2}x) &&\mid \tilde{H}_i\tilde{H}_j = \sum_{k=0}^{\min\{i, j\}}k!\binom{i}{k}\binom{j}{k}\tilde{H}_{i+j-2k} \\
            &= 2^\frac{i+j}{2} \sum_{k=0}^{\min\{i, j\}} k!\binom{i}{k}\binom{j}{k} \tilde{H}_{i+j-2k}(\sqrt{2}x) &&\mid \cdot1=2^{k-k} \\
            &= \sum_{k=0}^{\min\{i, j\}} 2^kk!\binom{i}{k}\binom{j}{k}2^\frac{i+j-2k}{2} \tilde{H}_{i+j-2k}(\sqrt{2}x) &&\mid H_j(x)=2^\frac{j}{2} \tilde{H}_j(\sqrt{2}x) \\
            &= \sum_{k=0}^{\min\{i, j\}}2^kk!\binom{i}{k}\binom{j}{k} H_{i+j-2k}(x)
        \end{aligned}
    $$

    See also
    --------
    - for any implementation: [`hermmul`][poly.hermite.arithmetic.hermmul]

    References
    ----------
    - [1] Zhi-yuan Huang & Jia-an Yan: Introduction to Infinite Dimensional Stochastic Analysis. [10.1007/978-94-011-4108-6](https://doi.org/10.1007/978-94-011-4108-6)
    - [Wikipedia - Hermite polynomials - Definition](https://en.wikipedia.org/wiki/Hermite_polynomials#Definition)
    """
    if not h:
        return () #hermzero

    r, sentinel = [], object()
    for i, gi in enumerate(g):
        r.extend([sentinel] * (i+len(h) - len(r)))
        for j, hj in enumerate(h):
            for k, f in enumerate(islice(hermweightis(), min(i, j)+1)):
                if r[i+j-2*k] is sentinel:
                    r[i+j-2*k] = f * comb(i, k)*comb(j, k) * gi*hj
                else:
                    r[i+j-2*k] += f * comb(i, k)*comb(j, k) * gi*hj
    return tuple(r)

hermmulx(h, zero=0)

Return the product of Hermite polynomial series h and a monomial of degree n.

\[ h(x)x^n \]

More efficient than hermmul(h, hermx).

Complexity

For a Hermite function series of degree \(n\) there will be

  • \(\begin{cases}n-1 & n<0 \\ 0 & n\leq0 \end{cases}\) scalar additions (add),
  • \(\begin{cases}n-1 & n<0 \\ 0 & n\leq0 \end{cases}\) scalar multiplications (mul) &
  • \(n+1\) scalar divisions (truediv) by two.
Notes

For a single Hermite polynomial

\[ \begin{aligned} H_{k+1}(x) &= 2xH_k(x)-H_k'(x) \\ H_k'(x) &= 2kH_{k-1}(x) \\ \Rightarrow \quad xH_k(x) &= \frac{H_{k+1}(x)}{2}+kH_{k-1}(x) \end{aligned} \]

and therefore for a series

\[ \begin{aligned} xh(x) &= x\sum_kh_kH_k(x) \\ &= \sum_kh_kxH_k(x) \\ &= \sum_kh_k\left(\frac{1}{2}H_{k+1}(x)+kH_{k-1}(x)\right) \\ &= \sum_k\frac{h_k}{2}H_{k+1}(x)+\sum_kkh_kH_{k-1}(x) \\ &= \sum_k\frac{h_{k-1}}{2}H_k(x)+\sum_k(k+1)h_{k+1}H_k(x) \\ &= \sum_k\left(\frac{h_{k-1}}{2}+(k+1)h_{k+1}\right)H_k(x) \end{aligned} \]
See also
References
Source code in poly\hermite\arithmetic.py
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
def hermmulx(h, zero=0):
    r"""Return the product of Hermite polynomial series `h` and a monomial of degree `n`.

    $$
        h(x)x^n
    $$

    More efficient than `hermmul(h, hermx)`.

    Complexity
    ----------
    For a Hermite function series of degree $n$ there will be

    - $\begin{cases}n-1 & n<0 \\ 0 & n\leq0 \end{cases}$ scalar additions (`add`),
    - $\begin{cases}n-1 & n<0 \\ 0 & n\leq0 \end{cases}$ scalar multiplications (`mul`) &
    - $n+1$ scalar divisions (`truediv`) by two.

    Notes
    --------
    For a single Hermite polynomial

    $$
        \begin{aligned}
            H_{k+1}(x) &= 2xH_k(x)-H_k'(x) \\
            H_k'(x) &= 2kH_{k-1}(x) \\
            \Rightarrow \quad xH_k(x) &= \frac{H_{k+1}(x)}{2}+kH_{k-1}(x)
        \end{aligned}
    $$

    and therefore for a series

    $$
        \begin{aligned}
            xh(x) &= x\sum_kh_kH_k(x) \\
            &= \sum_kh_kxH_k(x) \\
            &= \sum_kh_k\left(\frac{1}{2}H_{k+1}(x)+kH_{k-1}(x)\right) \\
            &= \sum_k\frac{h_k}{2}H_{k+1}(x)+\sum_kkh_kH_{k-1}(x) \\
            &= \sum_k\frac{h_{k-1}}{2}H_k(x)+\sum_k(k+1)h_{k+1}H_k(x) \\
            &= \sum_k\left(\frac{h_{k-1}}{2}+(k+1)h_{k+1}\right)H_k(x)
        \end{aligned}
    $$

    See also
    --------
    - for Hermite polynomial series as factor: [`hermmul`][poly.hermite.arithmetic.hermmul]
    - `numpy` equivalent: [`numpy.polynomial.hermite.hermmulx`](https://numpy.org/doc/stable/reference/generated/numpy.polynomial.hermite.hermmulx.html)

    References
    ----------
    - [Wikipedia - Hermite polynomials - Recurrence relation](https://en.wikipedia.org/wiki/Hermite_polynomials#Recurrence_relation)
    """
    im1, ip1 = tee(h)
    _, h1 = next(ip1, None), next(ip1, zero)
    return vecrshift(vecladd(vecltruediv(im1, 2), veclhadamard(count(2), ip1)), 1, zero=h1)

hermmulHn(h, n, zero=0)

Return the product of Hermite polynomial series h and the n-th Hermite polynomial.

\[ hH_n \]

More efficient than hermmul(h, vecbasis(n)).

TODO: Complexity

See also
  • for a Hermite polynomial series factor: hermmul
Source code in poly\hermite\arithmetic.py
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
def hermmulHn(h, n, zero=0):
    r"""Return the product of Hermite polynomial series `h` and the `n`-th Hermite polynomial.

    $$
        hH_n
    $$

    More efficient than `hermmul(h, vecbasis(n))`.

    TODO: Complexity

    See also
    --------
    - for a Hermite polynomial series factor: [`hermmul`][poly.hermite.arithmetic.hermmul]
    """
    r = []
    for i, hi in enumerate(h):
        r.extend([zero] * (i+n - len(r)+1))
        for k, f in enumerate(islice(hermweightis(), min(i, n)+1)):
            if r[i+n-2*k] is zero:
                r[i+n-2*k] = f * comb(i, k)*comb(n, k) * hi
            else:
                r[i+n-2*k] += f * comb(i, k)*comb(n, k) * hi
    return tuple(r)

hermpow(h, n, method='binary')

Return the Hermite polynomial series h raised to the nonnegative n-th power.

\[ h^n \]

h must be a sequence.

Available methods are

See also
Source code in poly\hermite\arithmetic.py
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
def hermpow(h, n, method='binary'):
    """Return the Hermite polynomial series `h` raised to the nonnegative `n`-th power.

    $$
        h^n
    $$

    `h` must be a sequence.

    Available methods are 

    - [`naive`][poly.hermite.hermpow_naive] &
    - [`binary`][poly.hermite.hermpow_binary].

    See also
    --------
    - implementations: [`hermpow_naive`][poly.hermite.hermpow_naive],
    [`hermpow_binary`][poly.hermite.hermpow_binary],
    - `numpy` equivalent: [`numpy.polynomial.hermite.hermpow`](https://numpy.org/doc/stable/reference/generated/numpy.polynomial.hermite.hermpow.html)
    """
    match method:
        case 'naive':
            return hermpow_naive(h, n)
        case 'binary':
            return hermpow_binary(h, n)
        case _:
            raise ValueError('Invalid method')

hermpow_naive(h, n, one=1)

Return the Hermite polynomial series h raised to the nonnegative n-th power.

\[ h^n \]

Uses repeated multiplication.

h must be a sequence.

See also
Source code in poly\hermite\arithmetic.py
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
def hermpow_naive(h, n, one=1):
    """Return the Hermite polynomial series `h` raised to the nonnegative `n`-th power.

    $$
        h^n
    $$

    Uses repeated multiplication.

    `h` must be a sequence.

    See also
    --------
    - for any implementation: [`hermpow`][poly.hermite.hermpow]
    - other implementations: [`hermpow_binary`][poly.hermite.hermpow_binary]
    """
    return next(hermpows(h, start=n, one=one))

hermpow_binary(h, n, one=1)

Return the Hermite polynomial series h raised to the nonnegative n-th power.

\[ h^n \]

Uses exponentiation by squaring.

h must be a sequence.

See also
References
Source code in poly\hermite\arithmetic.py
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
def hermpow_binary(h, n, one=1):
    """Return the Hermite polynomial series `h` raised to the nonnegative `n`-th power.

    $$
        h^n
    $$

    Uses exponentiation by squaring.

    `h` must be a sequence.

    See also
    --------
    - for any implementations: [`hermpow`][poly.hermite.hermpow]
    - other implementations[`hermpow_naive`][poly.hermite.hermpow_naive]

    References
    ----------
    - [Wikipedia - Exponentiation by squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring)
    """
    if n==0:
        return (one,) #hermone
    r = None
    while n:
        if n % 2 == 1:
            r = hermmul(r, h) if r is not None else h
        h = hermmul(h, h)
        n //= 2
    return r

hermmulpow(alpha, one=1)

Return product of Hermite Polynomials.

\[ H^\alpha = \prod_iH_i^{\alpha_i} \]
Source code in poly\hermite\arithmetic.py
486
487
488
489
490
491
492
493
494
495
496
def hermmulpow(alpha, one=1):
    r"""Return product of Hermite Polynomials.

    $$
        H^\alpha = \prod_iH_i^{\alpha_i}
    $$
    """
    r = (one,) #hermone
    for i, ai in enumerate(alpha):
        r = hermmul(r, hermpow(vecbasis(i), ai, one=one))
    return r

hermpows(h, start=0, one=1)

Yield the powers of the Hermite polynomial series h.

\[ (h^n)_{n\in\mathbb{N}_0} = (1, h, h^2, \dots) \]

Uses iterative multiplication to calculate powers consecutively.

h must be a sequence.

See also
Source code in poly\hermite\arithmetic.py
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
def hermpows(h, start=0, one=1):
    r"""Yield the powers of the Hermite polynomial series `h`.

    $$
        (h^n)_{n\in\mathbb{N}_0} = (1, h, h^2, \dots)
    $$

    Uses iterative multiplication to calculate powers consecutively.

    `h` must be a sequence.

    See also
    --------
    - used by: [`hermpow_naive`][poly.hermite.arithmetic.hermpow_naive]
    - for scalar arguments: [`hermvals`][poly.hermite.hermvals]
    """
    if start <= 0:
        yield (one,) #hermone
    yield (g := reduce_default(hermmul_naive, repeat(h, start), initial=MISSING, default=h))
    while True:
        g = hermmul_naive(g, h)
        yield g

calculus

hermder(h, k=1)

Return the k-th derivative of Hermite polynomial series h.

\[ h^{(k)} \]
Notes

For Hermite polynomials:

\[ \begin{aligned} \frac{d}{dx}H_n(x) &= 2nH_{n-1}(x) \\ \frac{d^2}{dx^2}H_n(x) &= 2^2n(n-1)H_{n-2}(x) \\ &\vdots \\ \frac{d^k}{dx^k}H_n(x) &= 2^kn(n-1)\cdots(n-k+1)H_{n-k}(x) \\ &= 2^k(n)_kH_{n-k}(x) \\ &= 2^k\frac{n!}{(n-k)!}H_{n-k}(x) \\ &= 2^k{}_nP_kH_{n-k}(x) \end{aligned} \]

And for Hermite polynomial series:

\[ \begin{aligned} \frac{d^k}{dx^k}h(x) &= \frac{d^k}{dx^k}\sum_{l=0}^nh_lH_l(x) \\ &= \sum_{l=k}^nh_l2^k{}_lP_kH_{l-k}(x) \\ &= 2^k\sum_{l=0}^{n-k}h_{l+k}\,{}_{l+k}P_kH_l(x) \end{aligned} \]

Where \((n)_k\) is the Falling factorial and \({}_nP_k\) is the number of k-permutations of n with \((n)_k=\frac{n!}{(n-k)!}={}_nP_k\) (falling factorials are used because their definition appears in the derivation; permutations are used because a fast implementation is provided by math.perm).

References
See also
Source code in poly\hermite\calculus.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
def hermder(h, k=1):
    r"""Return the `k`-th derivative of Hermite polynomial series `h`.

    $$
        h^{(k)}
    $$

    Notes
    -----
    For Hermite polynomials:

    $$
        \begin{aligned}
            \frac{d}{dx}H_n(x) &= 2nH_{n-1}(x) \\
            \frac{d^2}{dx^2}H_n(x) &= 2^2n(n-1)H_{n-2}(x) \\
            &\vdots \\
            \frac{d^k}{dx^k}H_n(x) &= 2^kn(n-1)\cdots(n-k+1)H_{n-k}(x) \\
            &= 2^k(n)_kH_{n-k}(x) \\
            &= 2^k\frac{n!}{(n-k)!}H_{n-k}(x) \\
            &= 2^k{}_nP_kH_{n-k}(x)
        \end{aligned}
    $$

    And for Hermite polynomial series:

    $$
        \begin{aligned}
            \frac{d^k}{dx^k}h(x) &= \frac{d^k}{dx^k}\sum_{l=0}^nh_lH_l(x) \\
            &= \sum_{l=k}^nh_l2^k{}_lP_kH_{l-k}(x) \\
            &= 2^k\sum_{l=0}^{n-k}h_{l+k}\,{}_{l+k}P_kH_l(x)
        \end{aligned}
    $$

    Where $(n)_k$ is the [Falling factorial](https://en.wikipedia.org/wiki/Falling_and_rising_factorials#Properties)
    and ${}_nP_k$ is the [number of k-permutations of n](https://en.wikipedia.org/wiki/Permutation#k-permutations_of_n)
    with $(n)_k=\frac{n!}{(n-k)!}={}_nP_k$ (falling factorials are
    used because their definition appears in the derivation; permutations are
    used because a fast implementation is provided by `math.perm`).

    References
    ----------
    - [Wikipedia - Hermite polynomials - Recurrence relation](https://en.wikipedia.org/wiki/Hermite_polynomials#Recurrence_relation)

    See also
    --------
    - in standard monomial basis: [`polyder`][poly.standard.polyder]
    - `numpy` equivalent: [`numpy.polynomial.hermite.hermder`](https://numpy.org/doc/stable/reference/generated/numpy.polynomial.hermite.hermder.html)
    """
    tk = 2**k
    return vechadamard((tk*perm(l+k, k) for l in count()), islice(h, k, None))

hermantider(h, b=0, c=0)

Return the antiderivative of Hermite polynomial series h.

\[ \int_b^xh(y)\,\mathrm{d}y + c \]

TODO: higher antiderivatives, complexity

Notes

Let

\[ I_{b,c}[f](x) = \int_b^xf(y)\,\mathrm{d}y+c. \]

Then we have for Hermite polynomials:

\[ \begin{aligned} I_{b,c}[H_n](x) &= \int_b^xH_n(y)\,\mathrm{d}y+c \\ &\qquad \mid H_n'=2nH_{n-1} \quad \Leftrightarrow \quad H_n^{(-1)}=\frac{H_{n+1}}{2(n+1)}+C \\ &= \left.\frac{H_{n+1}}{2(n+1)}\right|_b^x+c \\ &= \frac{H_{n+1}(x)}{2(n+1)}-\frac{H_{n+1}(b)}{2(n+1)}+c \end{aligned} \]

For Hermite polynomials series:

\[ \begin{aligned} I_{b,c}[h](x) &= I_{b,c}\left[\sum_kh_kH_k\right](x) \\ &= \int_b^x\sum_kh_kH_k(y)\,\mathrm{d}y+c \\ &= \sum_kh_k\int_b^xH_k(y)\,\mathrm{d}y+c \\ &= \sum_kh_k\left(\frac{H_{k+1}(x)}{2(k+1)}-\frac{H_{k+1}(b)}{2(k+1)}\right)+c \\ &= \sum_kh_{k-1}\left(\frac{H_k(x)}{2k}-\frac{H_k(b)}{2k}\right)+c \\ &= \sum_k\frac{h_{k-1}}{2k}H_k(x)-\sum_k\frac{h_{k-1}}{2k}H_k(b)+c \end{aligned} \]
References
See also
Source code in poly\hermite\calculus.py
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def hermantider(h, b=0, c=0):
    r"""Return the antiderivative of Hermite polynomial series `h`.

    $$
        \int_b^xh(y)\,\mathrm{d}y + c
    $$

    TODO: higher antiderivatives, complexity

    Notes
    -----
    Let

    $$
        I_{b,c}[f](x) = \int_b^xf(y)\,\mathrm{d}y+c.
    $$

    Then we have for Hermite polynomials:

    $$
        \begin{aligned}
            I_{b,c}[H_n](x) &= \int_b^xH_n(y)\,\mathrm{d}y+c \\
            &\qquad \mid H_n'=2nH_{n-1} \quad \Leftrightarrow \quad H_n^{(-1)}=\frac{H_{n+1}}{2(n+1)}+C \\
            &= \left.\frac{H_{n+1}}{2(n+1)}\right|_b^x+c \\
            &= \frac{H_{n+1}(x)}{2(n+1)}-\frac{H_{n+1}(b)}{2(n+1)}+c
        \end{aligned}
    $$

    For Hermite polynomials series:

    $$
        \begin{aligned}
            I_{b,c}[h](x) &= I_{b,c}\left[\sum_kh_kH_k\right](x) \\
            &= \int_b^x\sum_kh_kH_k(y)\,\mathrm{d}y+c \\
            &= \sum_kh_k\int_b^xH_k(y)\,\mathrm{d}y+c \\
            &= \sum_kh_k\left(\frac{H_{k+1}(x)}{2(k+1)}-\frac{H_{k+1}(b)}{2(k+1)}\right)+c \\
            &= \sum_kh_{k-1}\left(\frac{H_k(x)}{2k}-\frac{H_k(b)}{2k}\right)+c \\
            &= \sum_k\frac{h_{k-1}}{2k}H_k(x)-\sum_k\frac{h_{k-1}}{2k}H_k(b)+c
        \end{aligned}
    $$

    References
    ----------
    - [Wikipedia - Hermite polynomials - Recurrence relation](https://en.wikipedia.org/wiki/Hermite_polynomials#Recurrence_relation)

    See also
    --------
    - in standard monomial basis: [`polyantider`][poly.standard.polyantider]
    - `numpy` equivalent: [`numpy.polynomial.hermite.hermint`](https://numpy.org/doc/stable/reference/generated/numpy.polynomial.hermite.hermint.html)
    """
    H = vecrshift(veclhadamardtruediv(h, count(2, 2)), 1)
    return hermaddc(H, c-hermval_iterative(H, b))

conversion

herm2poly(h, method='iterative')

Return a Hermite polynomial series in standard monomial basis.

\[ h^{(P)} \]

Available methods are

See also
References
Source code in poly\hermite\conversion.py
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def herm2poly(h, method='iterative'):
    """Return a Hermite polynomial series in standard monomial basis.

    $$
        h^{(P)}
    $$

    Available methods are 

    - [`naive`][poly.hermite.herm2poly_naive],
    - [`iterative`][poly.hermite.herm2poly_iterative] &
    - [`clenshaw`][poly.hermite.herm2poly_clenshaw].

    See also
    --------
    - implementations: [`herm2poly_naive`][poly.hermite.herm2poly_naive],
    [`herm2poly_iterative`][poly.hermite.herm2poly_iterative],
    [`herm2poly_clenshaw`][poly.hermite.herm2poly_clenshaw]

    References
    ----------
    - `numpy` equivalent: [`numpy.polynomial.hermite.herm2poly`](https://numpy.org/doc/stable/reference/generated/numpy.polynomial.hermite.herm2poly.html)
    """
    match method:
        case 'naive':
            return herm2poly_naive(h)
        case 'iterative':
            return herm2poly_iterative(h)
        case 'clenshaw':
            return herm2poly_clenshaw(h)
        case _:
            raise ValueError('Invalid method')

herm2poly_naive(h)

Return a Hermite polynomial series in standard monomial basis.

\[ h^{(P)} \]

Uses naive Hermite polynomial creation by herm_explicit.

Complexity

For a Hermite polynomial series of degree \(n\) there will be

  • \(\frac{n(n+1)}{2}\) scalar additions (add) &
  • \(\frac{(n+1)(n+2)}{2}\) scalar multiplications (mul).
See also
Source code in poly\hermite\conversion.py
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
def herm2poly_naive(h):
    r"""Return a Hermite polynomial series in standard monomial basis.

    $$
        h^{(P)}
    $$

    Uses naive Hermite polynomial creation by [`herm_explicit`][poly.hermite.herm_explicit].

    Complexity
    ----------
    For a Hermite polynomial series of degree $n$ there will be

    - $\frac{n(n+1)}{2}$ scalar additions (`add`) &
    - $\frac{(n+1)(n+2)}{2}$ scalar multiplications (`mul`).

    See also
    --------
    - for any implementation: [`herm2poly`][poly.hermite.herm2poly]
    - other implementations: [`herm2poly_iterative`][poly.hermite.herm2poly_iterative],
    [`herm2poly_clenshaw`][poly.hermite.herm2poly_clenshaw]
    """
    return polyadd(*(polyscalarmul(hi, herm_explicit(i)) for i, hi in enumerate(h)))

herm2poly_iterative(h)

Return a Hermite polynomial series in standard monomial basis.

\[ h^{(P)} \]

Uses iterative Hermite polynomial creation like herm_iterative.

Complexity

For a Hermite polynomial series of degree \(n\) there will be

  • \(\frac{n(n+1)}{2}\) scalar additions (add) &
  • \(\frac{(n+1)(n+2)}{2}\) scalar multiplications (mul).
See also
Source code in poly\hermite\conversion.py
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
def herm2poly_iterative(h):
    r"""Return a Hermite polynomial series in standard monomial basis.

    $$
        h^{(P)}
    $$

    Uses iterative Hermite polynomial creation like
    [`herm_iterative`][poly.hermite.herm_iterative].

    Complexity
    ----------
    For a Hermite polynomial series of degree $n$ there will be

    - $\frac{n(n+1)}{2}$ scalar additions (`add`) &
    - $\frac{(n+1)(n+2)}{2}$ scalar multiplications (`mul`).

    See also
    --------
    - for any implementation: [`herm2poly`][poly.hermite.herm2poly]
    - other implementations: [`herm2poly_naive`][poly.hermite.herm2poly_naive],
    [`herm2poly_clenshaw`][poly.hermite.herm2poly_clenshaw]
    - uses: [`herms`][poly.hermite.herms]
    """
    return polyadd(*map(polyscalarmul, h, herms()))

herm2poly_clenshaw(h)

Return a Hermite polynomial series in standard monomial basis.

\[ h^{(P)} \]

Uses the Clenshaw algorithm like hermval_clenshaw.

Complexity

For a Hermite polynomial series of degree \(n\) there will be

  • \(n+1\) scalar additions (add),
  • \(\begin{cases}\frac{n(n-1)}{2} & n\geq0 \\ 0 & n\leq0\end{cases}\) scalar subtractions (sub) &
  • \(\begin{cases}n^2 & n\geq0 \\ 0 & n\leq0\end{cases}\) scalar multiplications (mul).
See also
Source code in poly\hermite\conversion.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
def herm2poly_clenshaw(h):
    r"""Return a Hermite polynomial series in standard monomial basis.

    $$
        h^{(P)}
    $$

    Uses the Clenshaw algorithm like
    [`hermval_clenshaw`][poly.hermite.hermval_clenshaw].

    Complexity
    ----------
    For a Hermite polynomial series of degree $n$ there will be

    - $n+1$ scalar additions (`add`),
    - $\begin{cases}\frac{n(n-1)}{2} & n\geq0 \\ 0 & n\leq0\end{cases}$ scalar subtractions (`sub`) &
    - $\begin{cases}n^2 & n\geq0 \\ 0 & n\leq0\end{cases}$ scalar multiplications (`mul`).

    See also
    --------
    - for any implementation: [`herm2poly`][poly.hermite.herm2poly]
    - other implementations [`herm2poly_naive`][poly.hermite.herm2poly_naive],
    [`herm2poly_iterative`][poly.hermite.herm2poly_iterative]
    """
    h = tuple(h)
    if not h:
        return polyzero
    a, b = polyzero, polyzero
    for n, hn in reversed(tuple(enumerate(h[1:], 1))):
        a, b = polyaddc(polysub(polyscalarmul(2, polymulx(a)), polyscalarmul(2*(n+1), b)), hn), a
    return polyaddc(polysub(polyscalarmul(2, polymulx(a)), polyscalarmul(2, b)), h[0])

poly2herm(p, method='iterative')

Return a standard monomial basis polynomials as a Hermite polynomial series.

\[ p^{(H)} \]

Available methods are

See also
References
Source code in poly\hermite\conversion.py
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
def poly2herm(p, method='iterative'):
    """Return a standard monomial basis polynomials as a Hermite polynomial series.

    $$
        p^{(H)}
    $$

    Available methods are 

    - [`naive`][poly.hermite.poly2herm_naive],
    - [`iterative`][poly.hermite.poly2herm_iterative] &
    - [`horner`][poly.hermite.poly2herm_horner].

    See also
    --------
    - implementations: [`poly2herm_naive`][poly.hermite.poly2herm_naive],
    [`poly2herm_iterative`][poly.hermite.poly2herm_iterative],
    [`poly2herm_horner`][poly.hermite.poly2herm_horner]

    References
    ----------
    - `numpy` equivalent: [`numpy.polynomial.hermite.poly2herm`](https://numpy.org/doc/stable/reference/generated/numpy.polynomial.hermite.poly2herm.html)
    """
    match method:
        case 'naive':
            return poly2herm_naive(p)
        case 'iterative':
            return poly2herm_iterative(p)
        case 'horner':
            return poly2herm_horner(p)
        case _:
            raise ValueError('Invalid method')

poly2herm_naive(p)

Return a standard monomial basis polynomials as a Hermite polynomial series.

\[ p^{(H)} \]

Uses naive monomial as Hermite polynomial series creation by the default method of hermmono.

See also
Source code in poly\hermite\conversion.py
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
def poly2herm_naive(p):
    """Return a standard monomial basis polynomials as a Hermite polynomial series.

    $$
        p^{(H)}
    $$

    Uses naive monomial as Hermite polynomial series creation by the default
    method of [`hermmono`][poly.hermite.hermmono].

    See also
    --------
    - any implementation: [`poly2herm`][poly.hermite.poly2herm]
    - other implementations: [`poly2herm_iterative`][poly.hermite.poly2herm_iterative],
    [`poly2herm_horner`][poly.hermite.poly2herm_horner]
    """
    return hermadd(*(hermscalarmul(pi, hermmono(i)) for i, pi in enumerate(p)))

poly2herm_iterative(p)

Return a standard monomial basis polynomials as a Hermite polynomial series.

\[ p^{(H)} \]

Uses iterative monomial creation of hermmonos.

See also
Source code in poly\hermite\conversion.py
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
def poly2herm_iterative(p):
    """Return a standard monomial basis polynomials as a Hermite polynomial series.

    $$
        p^{(H)}
    $$

    Uses iterative monomial creation of [`hermmonos`][poly.hermite.hermmonos].

    See also
    --------
    - for any implementation: [`poly2herm`][poly.hermite.poly2herm]
    - other implementations: [`poly2herm_iterative`][poly.hermite.poly2herm_iterative],
    [`poly2herm_horner`][poly.hermite.poly2herm_horner]
    """
    return hermadd(*map(hermscalarmul, p, hermmonos()))

poly2herm_horner(p)

Return a standard monomial basis polynomials as a Hermite polynomial series.

\[ p^{(H)} \]

Uses Horner's method.

p must be reversible.

See also
References
Source code in poly\hermite\conversion.py
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
def poly2herm_horner(p):
    """Return a standard monomial basis polynomials as a Hermite polynomial series.

    $$
        p^{(H)}
    $$

    Uses Horner's method.

    `p` must be reversible.

    See also
    --------
    - for any implementation: [`poly2herm`][poly.hermite.poly2herm]
    - other implementations: [`poly2herm_iterative`][poly.hermite.poly2herm_iterative],
    [`poly2herm_horner`][poly.hermite.poly2herm_horner]

    References
    ----------
    - [Wikipedia - Horner's method](https://en.wikipedia.org/wiki/Horner%27s_method)
    """
    r = hermzero
    for pi in reversed(p):
        r = hermaddc(hermmulx(r), pi)
    return r

hermsympify(h, x=x)

Return the Hermite polynomial series h as a sympy.Poly.

Source code in poly\hermite\conversion.py
226
227
228
def hermsympify(h, x=x):
    """Return the Hermite polynomial series `h` as a [`sympy.Poly`](https://docs.sympy.org/latest/modules/polys/reference.html#sympy.polys.polytools.Poly)."""
    return vecdot(h, (sp.hermite_poly(i, x, polys=True) for i in count()), zero=sp.Poly(0, x))