Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wiseplat
GitHub Repository: wiseplat/python-code
Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/numpy/polynomial/hermite.py
7763 views
1
"""
2
==============================================================
3
Hermite Series, "Physicists" (:mod:`numpy.polynomial.hermite`)
4
==============================================================
5
6
This module provides a number of objects (mostly functions) useful for
7
dealing with Hermite series, including a `Hermite` class that
8
encapsulates the usual arithmetic operations. (General information
9
on how this module represents and works with such polynomials is in the
10
docstring for its "parent" sub-package, `numpy.polynomial`).
11
12
Classes
13
-------
14
.. autosummary::
15
:toctree: generated/
16
17
Hermite
18
19
Constants
20
---------
21
.. autosummary::
22
:toctree: generated/
23
24
hermdomain
25
hermzero
26
hermone
27
hermx
28
29
Arithmetic
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
46
Calculus
47
--------
48
.. autosummary::
49
:toctree: generated/
50
51
hermder
52
hermint
53
54
Misc 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
73
See also
74
--------
75
`numpy.polynomial`
76
77
"""
78
import numpy as np
79
import numpy.linalg as la
80
from numpy.core.multiarray import normalize_axis_index
81
82
from . import polyutils as pu
83
from ._polybase import ABCPolyBase
84
85
__all__ = [
86
'hermzero', 'hermone', 'hermx', 'hermdomain', 'hermline', 'hermadd',
87
'hermsub', 'hermmulx', 'hermmul', 'hermdiv', 'hermpow', 'hermval',
88
'hermder', 'hermint', 'herm2poly', 'poly2herm', 'hermfromroots',
89
'hermvander', 'hermfit', 'hermtrim', 'hermroots', 'Hermite',
90
'hermval2d', 'hermval3d', 'hermgrid2d', 'hermgrid3d', 'hermvander2d',
91
'hermvander3d', 'hermcompanion', 'hermgauss', 'hermweight']
92
93
hermtrim = pu.trimcoef
94
95
96
def poly2herm(pol):
97
"""
98
poly2herm(pol)
99
100
Convert a polynomial to a Hermite series.
101
102
Convert an array representing the coefficients of a polynomial (relative
103
to the "standard" basis) ordered from lowest degree to highest, to an
104
array of the coefficients of the equivalent Hermite series, ordered
105
from lowest to highest degree.
106
107
Parameters
108
----------
109
pol : array_like
110
1-D array containing the polynomial coefficients
111
112
Returns
113
-------
114
c : ndarray
115
1-D array containing the coefficients of the equivalent Hermite
116
series.
117
118
See Also
119
--------
120
herm2poly
121
122
Notes
123
-----
124
The easy way to do conversions between polynomial basis sets
125
is to use the convert method of a class instance.
126
127
Examples
128
--------
129
>>> from numpy.polynomial.hermite import poly2herm
130
>>> poly2herm(np.arange(4))
131
array([1. , 2.75 , 0.5 , 0.375])
132
133
"""
134
[pol] = pu.as_series([pol])
135
deg = len(pol) - 1
136
res = 0
137
for i in range(deg, -1, -1):
138
res = hermadd(hermmulx(res), pol[i])
139
return res
140
141
142
def herm2poly(c):
143
"""
144
Convert a Hermite series to a polynomial.
145
146
Convert an array representing the coefficients of a Hermite series,
147
ordered from lowest degree to highest, to an array of the coefficients
148
of the equivalent polynomial (relative to the "standard" basis) ordered
149
from lowest to highest degree.
150
151
Parameters
152
----------
153
c : array_like
154
1-D array containing the Hermite series coefficients, ordered
155
from lowest order term to highest.
156
157
Returns
158
-------
159
pol : ndarray
160
1-D array containing the coefficients of the equivalent polynomial
161
(relative to the "standard" basis) ordered from lowest order term
162
to highest.
163
164
See Also
165
--------
166
poly2herm
167
168
Notes
169
-----
170
The easy way to do conversions between polynomial basis sets
171
is to use the convert method of a class instance.
172
173
Examples
174
--------
175
>>> from numpy.polynomial.hermite import herm2poly
176
>>> herm2poly([ 1. , 2.75 , 0.5 , 0.375])
177
array([0., 1., 2., 3.])
178
179
"""
180
from .polynomial import polyadd, polysub, polymulx
181
182
[c] = pu.as_series([c])
183
n = len(c)
184
if n == 1:
185
return c
186
if n == 2:
187
c[1] *= 2
188
return c
189
else:
190
c0 = c[-2]
191
c1 = c[-1]
192
# i is the current degree of c1
193
for i in range(n - 1, 1, -1):
194
tmp = c0
195
c0 = polysub(c[i - 2], c1*(2*(i - 1)))
196
c1 = polyadd(tmp, polymulx(c1)*2)
197
return polyadd(c0, polymulx(c1)*2)
198
199
#
200
# These are constant arrays are of integer type so as to be compatible
201
# with the widest range of other types, such as Decimal.
202
#
203
204
# Hermite
205
hermdomain = np.array([-1, 1])
206
207
# Hermite coefficients representing zero.
208
hermzero = np.array([0])
209
210
# Hermite coefficients representing one.
211
hermone = np.array([1])
212
213
# Hermite coefficients representing the identity x.
214
hermx = np.array([0, 1/2])
215
216
217
def hermline(off, scl):
218
"""
219
Hermite series whose graph is a straight line.
220
221
222
223
Parameters
224
----------
225
off, scl : scalars
226
The specified line is given by ``off + scl*x``.
227
228
Returns
229
-------
230
y : ndarray
231
This module's representation of the Hermite series for
232
``off + scl*x``.
233
234
See Also
235
--------
236
numpy.polynomial.polynomial.polyline
237
numpy.polynomial.chebyshev.chebline
238
numpy.polynomial.legendre.legline
239
numpy.polynomial.laguerre.lagline
240
numpy.polynomial.hermite_e.hermeline
241
242
Examples
243
--------
244
>>> from numpy.polynomial.hermite import hermline, hermval
245
>>> hermval(0,hermline(3, 2))
246
3.0
247
>>> hermval(1,hermline(3, 2))
248
5.0
249
250
"""
251
if scl != 0:
252
return np.array([off, scl/2])
253
else:
254
return np.array([off])
255
256
257
def hermfromroots(roots):
258
"""
259
Generate a Hermite series with given roots.
260
261
The function returns the coefficients of the polynomial
262
263
.. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
264
265
in Hermite form, where the `r_n` are the roots specified in `roots`.
266
If a zero has multiplicity n, then it must appear in `roots` n times.
267
For instance, if 2 is a root of multiplicity three and 3 is a root of
268
multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The
269
roots can appear in any order.
270
271
If the returned coefficients are `c`, then
272
273
.. math:: p(x) = c_0 + c_1 * H_1(x) + ... + c_n * H_n(x)
274
275
The coefficient of the last term is not generally 1 for monic
276
polynomials in Hermite form.
277
278
Parameters
279
----------
280
roots : array_like
281
Sequence containing the roots.
282
283
Returns
284
-------
285
out : ndarray
286
1-D array of coefficients. If all roots are real then `out` is a
287
real array, if some of the roots are complex, then `out` is complex
288
even if all the coefficients in the result are real (see Examples
289
below).
290
291
See Also
292
--------
293
numpy.polynomial.polynomial.polyfromroots
294
numpy.polynomial.legendre.legfromroots
295
numpy.polynomial.laguerre.lagfromroots
296
numpy.polynomial.chebyshev.chebfromroots
297
numpy.polynomial.hermite_e.hermefromroots
298
299
Examples
300
--------
301
>>> from numpy.polynomial.hermite import hermfromroots, hermval
302
>>> coef = hermfromroots((-1, 0, 1))
303
>>> hermval((-1, 0, 1), coef)
304
array([0., 0., 0.])
305
>>> coef = hermfromroots((-1j, 1j))
306
>>> hermval((-1j, 1j), coef)
307
array([0.+0.j, 0.+0.j])
308
309
"""
310
return pu._fromroots(hermline, hermmul, roots)
311
312
313
def hermadd(c1, c2):
314
"""
315
Add one Hermite series to another.
316
317
Returns the sum of two Hermite series `c1` + `c2`. The arguments
318
are sequences of coefficients ordered from lowest order term to
319
highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
320
321
Parameters
322
----------
323
c1, c2 : array_like
324
1-D arrays of Hermite series coefficients ordered from low to
325
high.
326
327
Returns
328
-------
329
out : ndarray
330
Array representing the Hermite series of their sum.
331
332
See Also
333
--------
334
hermsub, hermmulx, hermmul, hermdiv, hermpow
335
336
Notes
337
-----
338
Unlike multiplication, division, etc., the sum of two Hermite series
339
is a Hermite series (without having to "reproject" the result onto
340
the basis set) so addition, just like that of "standard" polynomials,
341
is simply "component-wise."
342
343
Examples
344
--------
345
>>> from numpy.polynomial.hermite import hermadd
346
>>> hermadd([1, 2, 3], [1, 2, 3, 4])
347
array([2., 4., 6., 4.])
348
349
"""
350
return pu._add(c1, c2)
351
352
353
def hermsub(c1, c2):
354
"""
355
Subtract one Hermite series from another.
356
357
Returns the difference of two Hermite series `c1` - `c2`. The
358
sequences of coefficients are from lowest order term to highest, i.e.,
359
[1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
360
361
Parameters
362
----------
363
c1, c2 : array_like
364
1-D arrays of Hermite series coefficients ordered from low to
365
high.
366
367
Returns
368
-------
369
out : ndarray
370
Of Hermite series coefficients representing their difference.
371
372
See Also
373
--------
374
hermadd, hermmulx, hermmul, hermdiv, hermpow
375
376
Notes
377
-----
378
Unlike multiplication, division, etc., the difference of two Hermite
379
series is a Hermite series (without having to "reproject" the result
380
onto the basis set) so subtraction, just like that of "standard"
381
polynomials, is simply "component-wise."
382
383
Examples
384
--------
385
>>> from numpy.polynomial.hermite import hermsub
386
>>> hermsub([1, 2, 3, 4], [1, 2, 3])
387
array([0., 0., 0., 4.])
388
389
"""
390
return pu._sub(c1, c2)
391
392
393
def hermmulx(c):
394
"""Multiply a Hermite series by x.
395
396
Multiply the Hermite series `c` by x, where x is the independent
397
variable.
398
399
400
Parameters
401
----------
402
c : array_like
403
1-D array of Hermite series coefficients ordered from low to
404
high.
405
406
Returns
407
-------
408
out : ndarray
409
Array representing the result of the multiplication.
410
411
See Also
412
--------
413
hermadd, hermsub, hermmul, hermdiv, hermpow
414
415
Notes
416
-----
417
The multiplication uses the recursion relationship for Hermite
418
polynomials in the form
419
420
.. math::
421
422
xP_i(x) = (P_{i + 1}(x)/2 + i*P_{i - 1}(x))
423
424
Examples
425
--------
426
>>> from numpy.polynomial.hermite import hermmulx
427
>>> hermmulx([1, 2, 3])
428
array([2. , 6.5, 1. , 1.5])
429
430
"""
431
# c is a trimmed copy
432
[c] = pu.as_series([c])
433
# The zero series needs special treatment
434
if len(c) == 1 and c[0] == 0:
435
return c
436
437
prd = np.empty(len(c) + 1, dtype=c.dtype)
438
prd[0] = c[0]*0
439
prd[1] = c[0]/2
440
for i in range(1, len(c)):
441
prd[i + 1] = c[i]/2
442
prd[i - 1] += c[i]*i
443
return prd
444
445
446
def hermmul(c1, c2):
447
"""
448
Multiply one Hermite series by another.
449
450
Returns the product of two Hermite series `c1` * `c2`. The arguments
451
are sequences of coefficients, from lowest order "term" to highest,
452
e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``.
453
454
Parameters
455
----------
456
c1, c2 : array_like
457
1-D arrays of Hermite series coefficients ordered from low to
458
high.
459
460
Returns
461
-------
462
out : ndarray
463
Of Hermite series coefficients representing their product.
464
465
See Also
466
--------
467
hermadd, hermsub, hermmulx, hermdiv, hermpow
468
469
Notes
470
-----
471
In general, the (polynomial) product of two C-series results in terms
472
that are not in the Hermite polynomial basis set. Thus, to express
473
the product as a Hermite series, it is necessary to "reproject" the
474
product onto said basis set, which may produce "unintuitive" (but
475
correct) results; see Examples section below.
476
477
Examples
478
--------
479
>>> from numpy.polynomial.hermite import hermmul
480
>>> hermmul([1, 2, 3], [0, 1, 2])
481
array([52., 29., 52., 7., 6.])
482
483
"""
484
# s1, s2 are trimmed copies
485
[c1, c2] = pu.as_series([c1, c2])
486
487
if len(c1) > len(c2):
488
c = c2
489
xs = c1
490
else:
491
c = c1
492
xs = c2
493
494
if len(c) == 1:
495
c0 = c[0]*xs
496
c1 = 0
497
elif len(c) == 2:
498
c0 = c[0]*xs
499
c1 = c[1]*xs
500
else:
501
nd = len(c)
502
c0 = c[-2]*xs
503
c1 = c[-1]*xs
504
for i in range(3, len(c) + 1):
505
tmp = c0
506
nd = nd - 1
507
c0 = hermsub(c[-i]*xs, c1*(2*(nd - 1)))
508
c1 = hermadd(tmp, hermmulx(c1)*2)
509
return hermadd(c0, hermmulx(c1)*2)
510
511
512
def hermdiv(c1, c2):
513
"""
514
Divide one Hermite series by another.
515
516
Returns the quotient-with-remainder of two Hermite series
517
`c1` / `c2`. The arguments are sequences of coefficients from lowest
518
order "term" to highest, e.g., [1,2,3] represents the series
519
``P_0 + 2*P_1 + 3*P_2``.
520
521
Parameters
522
----------
523
c1, c2 : array_like
524
1-D arrays of Hermite series coefficients ordered from low to
525
high.
526
527
Returns
528
-------
529
[quo, rem] : ndarrays
530
Of Hermite series coefficients representing the quotient and
531
remainder.
532
533
See Also
534
--------
535
hermadd, hermsub, hermmulx, hermmul, hermpow
536
537
Notes
538
-----
539
In general, the (polynomial) division of one Hermite series by another
540
results in quotient and remainder terms that are not in the Hermite
541
polynomial basis set. Thus, to express these results as a Hermite
542
series, it is necessary to "reproject" the results onto the Hermite
543
basis set, which may produce "unintuitive" (but correct) results; see
544
Examples section below.
545
546
Examples
547
--------
548
>>> from numpy.polynomial.hermite import hermdiv
549
>>> hermdiv([ 52., 29., 52., 7., 6.], [0, 1, 2])
550
(array([1., 2., 3.]), array([0.]))
551
>>> hermdiv([ 54., 31., 52., 7., 6.], [0, 1, 2])
552
(array([1., 2., 3.]), array([2., 2.]))
553
>>> hermdiv([ 53., 30., 52., 7., 6.], [0, 1, 2])
554
(array([1., 2., 3.]), array([1., 1.]))
555
556
"""
557
return pu._div(hermmul, c1, c2)
558
559
560
def hermpow(c, pow, maxpower=16):
561
"""Raise a Hermite series to a power.
562
563
Returns the Hermite series `c` raised to the power `pow`. The
564
argument `c` is a sequence of coefficients ordered from low to high.
565
i.e., [1,2,3] is the series ``P_0 + 2*P_1 + 3*P_2.``
566
567
Parameters
568
----------
569
c : array_like
570
1-D array of Hermite series coefficients ordered from low to
571
high.
572
pow : integer
573
Power to which the series will be raised
574
maxpower : integer, optional
575
Maximum power allowed. This is mainly to limit growth of the series
576
to unmanageable size. Default is 16
577
578
Returns
579
-------
580
coef : ndarray
581
Hermite series of power.
582
583
See Also
584
--------
585
hermadd, hermsub, hermmulx, hermmul, hermdiv
586
587
Examples
588
--------
589
>>> from numpy.polynomial.hermite import hermpow
590
>>> hermpow([1, 2, 3], 2)
591
array([81., 52., 82., 12., 9.])
592
593
"""
594
return pu._pow(hermmul, c, pow, maxpower)
595
596
597
def hermder(c, m=1, scl=1, axis=0):
598
"""
599
Differentiate a Hermite series.
600
601
Returns the Hermite series coefficients `c` differentiated `m` times
602
along `axis`. At each iteration the result is multiplied by `scl` (the
603
scaling factor is for use in a linear change of variable). The argument
604
`c` is an array of coefficients from low to high degree along each
605
axis, e.g., [1,2,3] represents the series ``1*H_0 + 2*H_1 + 3*H_2``
606
while [[1,2],[1,2]] represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) +
607
2*H_0(x)*H_1(y) + 2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is
608
``y``.
609
610
Parameters
611
----------
612
c : array_like
613
Array of Hermite series coefficients. If `c` is multidimensional the
614
different axis correspond to different variables with the degree in
615
each axis given by the corresponding index.
616
m : int, optional
617
Number of derivatives taken, must be non-negative. (Default: 1)
618
scl : scalar, optional
619
Each differentiation is multiplied by `scl`. The end result is
620
multiplication by ``scl**m``. This is for use in a linear change of
621
variable. (Default: 1)
622
axis : int, optional
623
Axis over which the derivative is taken. (Default: 0).
624
625
.. versionadded:: 1.7.0
626
627
Returns
628
-------
629
der : ndarray
630
Hermite series of the derivative.
631
632
See Also
633
--------
634
hermint
635
636
Notes
637
-----
638
In general, the result of differentiating a Hermite series does not
639
resemble the same operation on a power series. Thus the result of this
640
function may be "unintuitive," albeit correct; see Examples section
641
below.
642
643
Examples
644
--------
645
>>> from numpy.polynomial.hermite import hermder
646
>>> hermder([ 1. , 0.5, 0.5, 0.5])
647
array([1., 2., 3.])
648
>>> hermder([-0.5, 1./2., 1./8., 1./12., 1./16.], m=2)
649
array([1., 2., 3.])
650
651
"""
652
c = np.array(c, ndmin=1, copy=True)
653
if c.dtype.char in '?bBhHiIlLqQpP':
654
c = c.astype(np.double)
655
cnt = pu._deprecate_as_int(m, "the order of derivation")
656
iaxis = pu._deprecate_as_int(axis, "the axis")
657
if cnt < 0:
658
raise ValueError("The order of derivation must be non-negative")
659
iaxis = normalize_axis_index(iaxis, c.ndim)
660
661
if cnt == 0:
662
return c
663
664
c = np.moveaxis(c, iaxis, 0)
665
n = len(c)
666
if cnt >= n:
667
c = c[:1]*0
668
else:
669
for i in range(cnt):
670
n = n - 1
671
c *= scl
672
der = np.empty((n,) + c.shape[1:], dtype=c.dtype)
673
for j in range(n, 0, -1):
674
der[j - 1] = (2*j)*c[j]
675
c = der
676
c = np.moveaxis(c, 0, iaxis)
677
return c
678
679
680
def hermint(c, m=1, k=[], lbnd=0, scl=1, axis=0):
681
"""
682
Integrate a Hermite series.
683
684
Returns the Hermite series coefficients `c` integrated `m` times from
685
`lbnd` along `axis`. At each iteration the resulting series is
686
**multiplied** by `scl` and an integration constant, `k`, is added.
687
The scaling factor is for use in a linear change of variable. ("Buyer
688
beware": note that, depending on what one is doing, one may want `scl`
689
to be the reciprocal of what one might expect; for more information,
690
see the Notes section below.) The argument `c` is an array of
691
coefficients from low to high degree along each axis, e.g., [1,2,3]
692
represents the series ``H_0 + 2*H_1 + 3*H_2`` while [[1,2],[1,2]]
693
represents ``1*H_0(x)*H_0(y) + 1*H_1(x)*H_0(y) + 2*H_0(x)*H_1(y) +
694
2*H_1(x)*H_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``.
695
696
Parameters
697
----------
698
c : array_like
699
Array of Hermite series coefficients. If c is multidimensional the
700
different axis correspond to different variables with the degree in
701
each axis given by the corresponding index.
702
m : int, optional
703
Order of integration, must be positive. (Default: 1)
704
k : {[], list, scalar}, optional
705
Integration constant(s). The value of the first integral at
706
``lbnd`` is the first value in the list, the value of the second
707
integral at ``lbnd`` is the second value, etc. If ``k == []`` (the
708
default), all constants are set to zero. If ``m == 1``, a single
709
scalar can be given instead of a list.
710
lbnd : scalar, optional
711
The lower bound of the integral. (Default: 0)
712
scl : scalar, optional
713
Following each integration the result is *multiplied* by `scl`
714
before the integration constant is added. (Default: 1)
715
axis : int, optional
716
Axis over which the integral is taken. (Default: 0).
717
718
.. versionadded:: 1.7.0
719
720
Returns
721
-------
722
S : ndarray
723
Hermite series coefficients of the integral.
724
725
Raises
726
------
727
ValueError
728
If ``m < 0``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or
729
``np.ndim(scl) != 0``.
730
731
See Also
732
--------
733
hermder
734
735
Notes
736
-----
737
Note that the result of each integration is *multiplied* by `scl`.
738
Why is this important to note? Say one is making a linear change of
739
variable :math:`u = ax + b` in an integral relative to `x`. Then
740
:math:`dx = du/a`, so one will need to set `scl` equal to
741
:math:`1/a` - perhaps not what one would have first thought.
742
743
Also note that, in general, the result of integrating a C-series needs
744
to be "reprojected" onto the C-series basis set. Thus, typically,
745
the result of this function is "unintuitive," albeit correct; see
746
Examples section below.
747
748
Examples
749
--------
750
>>> from numpy.polynomial.hermite import hermint
751
>>> hermint([1,2,3]) # integrate once, value 0 at 0.
752
array([1. , 0.5, 0.5, 0.5])
753
>>> hermint([1,2,3], m=2) # integrate twice, value & deriv 0 at 0
754
array([-0.5 , 0.5 , 0.125 , 0.08333333, 0.0625 ]) # may vary
755
>>> hermint([1,2,3], k=1) # integrate once, value 1 at 0.
756
array([2. , 0.5, 0.5, 0.5])
757
>>> hermint([1,2,3], lbnd=-1) # integrate once, value 0 at -1
758
array([-2. , 0.5, 0.5, 0.5])
759
>>> hermint([1,2,3], m=2, k=[1,2], lbnd=-1)
760
array([ 1.66666667, -0.5 , 0.125 , 0.08333333, 0.0625 ]) # may vary
761
762
"""
763
c = np.array(c, ndmin=1, copy=True)
764
if c.dtype.char in '?bBhHiIlLqQpP':
765
c = c.astype(np.double)
766
if not np.iterable(k):
767
k = [k]
768
cnt = pu._deprecate_as_int(m, "the order of integration")
769
iaxis = pu._deprecate_as_int(axis, "the axis")
770
if cnt < 0:
771
raise ValueError("The order of integration must be non-negative")
772
if len(k) > cnt:
773
raise ValueError("Too many integration constants")
774
if np.ndim(lbnd) != 0:
775
raise ValueError("lbnd must be a scalar.")
776
if np.ndim(scl) != 0:
777
raise ValueError("scl must be a scalar.")
778
iaxis = normalize_axis_index(iaxis, c.ndim)
779
780
if cnt == 0:
781
return c
782
783
c = np.moveaxis(c, iaxis, 0)
784
k = list(k) + [0]*(cnt - len(k))
785
for i in range(cnt):
786
n = len(c)
787
c *= scl
788
if n == 1 and np.all(c[0] == 0):
789
c[0] += k[i]
790
else:
791
tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype)
792
tmp[0] = c[0]*0
793
tmp[1] = c[0]/2
794
for j in range(1, n):
795
tmp[j + 1] = c[j]/(2*(j + 1))
796
tmp[0] += k[i] - hermval(lbnd, tmp)
797
c = tmp
798
c = np.moveaxis(c, 0, iaxis)
799
return c
800
801
802
def hermval(x, c, tensor=True):
803
"""
804
Evaluate an Hermite series at points x.
805
806
If `c` is of length `n + 1`, this function returns the value:
807
808
.. math:: p(x) = c_0 * H_0(x) + c_1 * H_1(x) + ... + c_n * H_n(x)
809
810
The parameter `x` is converted to an array only if it is a tuple or a
811
list, otherwise it is treated as a scalar. In either case, either `x`
812
or its elements must support multiplication and addition both with
813
themselves and with the elements of `c`.
814
815
If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If
816
`c` is multidimensional, then the shape of the result depends on the
817
value of `tensor`. If `tensor` is true the shape will be c.shape[1:] +
818
x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that
819
scalars have shape (,).
820
821
Trailing zeros in the coefficients will be used in the evaluation, so
822
they should be avoided if efficiency is a concern.
823
824
Parameters
825
----------
826
x : array_like, compatible object
827
If `x` is a list or tuple, it is converted to an ndarray, otherwise
828
it is left unchanged and treated as a scalar. In either case, `x`
829
or its elements must support addition and multiplication with
830
with themselves and with the elements of `c`.
831
c : array_like
832
Array of coefficients ordered so that the coefficients for terms of
833
degree n are contained in c[n]. If `c` is multidimensional the
834
remaining indices enumerate multiple polynomials. In the two
835
dimensional case the coefficients may be thought of as stored in
836
the columns of `c`.
837
tensor : boolean, optional
838
If True, the shape of the coefficient array is extended with ones
839
on the right, one for each dimension of `x`. Scalars have dimension 0
840
for this action. The result is that every column of coefficients in
841
`c` is evaluated for every element of `x`. If False, `x` is broadcast
842
over the columns of `c` for the evaluation. This keyword is useful
843
when `c` is multidimensional. The default value is True.
844
845
.. versionadded:: 1.7.0
846
847
Returns
848
-------
849
values : ndarray, algebra_like
850
The shape of the return value is described above.
851
852
See Also
853
--------
854
hermval2d, hermgrid2d, hermval3d, hermgrid3d
855
856
Notes
857
-----
858
The evaluation uses Clenshaw recursion, aka synthetic division.
859
860
Examples
861
--------
862
>>> from numpy.polynomial.hermite import hermval
863
>>> coef = [1,2,3]
864
>>> hermval(1, coef)
865
11.0
866
>>> hermval([[1,2],[3,4]], coef)
867
array([[ 11., 51.],
868
[115., 203.]])
869
870
"""
871
c = np.array(c, ndmin=1, copy=False)
872
if c.dtype.char in '?bBhHiIlLqQpP':
873
c = c.astype(np.double)
874
if isinstance(x, (tuple, list)):
875
x = np.asarray(x)
876
if isinstance(x, np.ndarray) and tensor:
877
c = c.reshape(c.shape + (1,)*x.ndim)
878
879
x2 = x*2
880
if len(c) == 1:
881
c0 = c[0]
882
c1 = 0
883
elif len(c) == 2:
884
c0 = c[0]
885
c1 = c[1]
886
else:
887
nd = len(c)
888
c0 = c[-2]
889
c1 = c[-1]
890
for i in range(3, len(c) + 1):
891
tmp = c0
892
nd = nd - 1
893
c0 = c[-i] - c1*(2*(nd - 1))
894
c1 = tmp + c1*x2
895
return c0 + c1*x2
896
897
898
def hermval2d(x, y, c):
899
"""
900
Evaluate a 2-D Hermite series at points (x, y).
901
902
This function returns the values:
903
904
.. math:: p(x,y) = \\sum_{i,j} c_{i,j} * H_i(x) * H_j(y)
905
906
The parameters `x` and `y` are converted to arrays only if they are
907
tuples or a lists, otherwise they are treated as a scalars and they
908
must have the same shape after conversion. In either case, either `x`
909
and `y` or their elements must support multiplication and addition both
910
with themselves and with the elements of `c`.
911
912
If `c` is a 1-D array a one is implicitly appended to its shape to make
913
it 2-D. The shape of the result will be c.shape[2:] + x.shape.
914
915
Parameters
916
----------
917
x, y : array_like, compatible objects
918
The two dimensional series is evaluated at the points `(x, y)`,
919
where `x` and `y` must have the same shape. If `x` or `y` is a list
920
or tuple, it is first converted to an ndarray, otherwise it is left
921
unchanged and if it isn't an ndarray it is treated as a scalar.
922
c : array_like
923
Array of coefficients ordered so that the coefficient of the term
924
of multi-degree i,j is contained in ``c[i,j]``. If `c` has
925
dimension greater than two the remaining indices enumerate multiple
926
sets of coefficients.
927
928
Returns
929
-------
930
values : ndarray, compatible object
931
The values of the two dimensional polynomial at points formed with
932
pairs of corresponding values from `x` and `y`.
933
934
See Also
935
--------
936
hermval, hermgrid2d, hermval3d, hermgrid3d
937
938
Notes
939
-----
940
941
.. versionadded:: 1.7.0
942
943
"""
944
return pu._valnd(hermval, c, x, y)
945
946
947
def hermgrid2d(x, y, c):
948
"""
949
Evaluate a 2-D Hermite series on the Cartesian product of x and y.
950
951
This function returns the values:
952
953
.. math:: p(a,b) = \\sum_{i,j} c_{i,j} * H_i(a) * H_j(b)
954
955
where the points `(a, b)` consist of all pairs formed by taking
956
`a` from `x` and `b` from `y`. The resulting points form a grid with
957
`x` in the first dimension and `y` in the second.
958
959
The parameters `x` and `y` are converted to arrays only if they are
960
tuples or a lists, otherwise they are treated as a scalars. In either
961
case, either `x` and `y` or their elements must support multiplication
962
and addition both with themselves and with the elements of `c`.
963
964
If `c` has fewer than two dimensions, ones are implicitly appended to
965
its shape to make it 2-D. The shape of the result will be c.shape[2:] +
966
x.shape.
967
968
Parameters
969
----------
970
x, y : array_like, compatible objects
971
The two dimensional series is evaluated at the points in the
972
Cartesian product of `x` and `y`. If `x` or `y` is a list or
973
tuple, it is first converted to an ndarray, otherwise it is left
974
unchanged and, if it isn't an ndarray, it is treated as a scalar.
975
c : array_like
976
Array of coefficients ordered so that the coefficients for terms of
977
degree i,j are contained in ``c[i,j]``. If `c` has dimension
978
greater than two the remaining indices enumerate multiple sets of
979
coefficients.
980
981
Returns
982
-------
983
values : ndarray, compatible object
984
The values of the two dimensional polynomial at points in the Cartesian
985
product of `x` and `y`.
986
987
See Also
988
--------
989
hermval, hermval2d, hermval3d, hermgrid3d
990
991
Notes
992
-----
993
994
.. versionadded:: 1.7.0
995
996
"""
997
return pu._gridnd(hermval, c, x, y)
998
999
1000
def hermval3d(x, y, z, c):
1001
"""
1002
Evaluate a 3-D Hermite series at points (x, y, z).
1003
1004
This function returns the values:
1005
1006
.. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * H_i(x) * H_j(y) * H_k(z)
1007
1008
The parameters `x`, `y`, and `z` are converted to arrays only if
1009
they are tuples or a lists, otherwise they are treated as a scalars and
1010
they must have the same shape after conversion. In either case, either
1011
`x`, `y`, and `z` or their elements must support multiplication and
1012
addition both with themselves and with the elements of `c`.
1013
1014
If `c` has fewer than 3 dimensions, ones are implicitly appended to its
1015
shape to make it 3-D. The shape of the result will be c.shape[3:] +
1016
x.shape.
1017
1018
Parameters
1019
----------
1020
x, y, z : array_like, compatible object
1021
The three dimensional series is evaluated at the points
1022
`(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If
1023
any of `x`, `y`, or `z` is a list or tuple, it is first converted
1024
to an ndarray, otherwise it is left unchanged and if it isn't an
1025
ndarray it is treated as a scalar.
1026
c : array_like
1027
Array of coefficients ordered so that the coefficient of the term of
1028
multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension
1029
greater than 3 the remaining indices enumerate multiple sets of
1030
coefficients.
1031
1032
Returns
1033
-------
1034
values : ndarray, compatible object
1035
The values of the multidimensional polynomial on points formed with
1036
triples of corresponding values from `x`, `y`, and `z`.
1037
1038
See Also
1039
--------
1040
hermval, hermval2d, hermgrid2d, hermgrid3d
1041
1042
Notes
1043
-----
1044
1045
.. versionadded:: 1.7.0
1046
1047
"""
1048
return pu._valnd(hermval, c, x, y, z)
1049
1050
1051
def hermgrid3d(x, y, z, c):
1052
"""
1053
Evaluate a 3-D Hermite series on the Cartesian product of x, y, and z.
1054
1055
This function returns the values:
1056
1057
.. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * H_i(a) * H_j(b) * H_k(c)
1058
1059
where the points `(a, b, c)` consist of all triples formed by taking
1060
`a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form
1061
a grid with `x` in the first dimension, `y` in the second, and `z` in
1062
the third.
1063
1064
The parameters `x`, `y`, and `z` are converted to arrays only if they
1065
are tuples or a lists, otherwise they are treated as a scalars. In
1066
either case, either `x`, `y`, and `z` or their elements must support
1067
multiplication and addition both with themselves and with the elements
1068
of `c`.
1069
1070
If `c` has fewer than three dimensions, ones are implicitly appended to
1071
its shape to make it 3-D. The shape of the result will be c.shape[3:] +
1072
x.shape + y.shape + z.shape.
1073
1074
Parameters
1075
----------
1076
x, y, z : array_like, compatible objects
1077
The three dimensional series is evaluated at the points in the
1078
Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a
1079
list or tuple, it is first converted to an ndarray, otherwise it is
1080
left unchanged and, if it isn't an ndarray, it is treated as a
1081
scalar.
1082
c : array_like
1083
Array of coefficients ordered so that the coefficients for terms of
1084
degree i,j are contained in ``c[i,j]``. If `c` has dimension
1085
greater than two the remaining indices enumerate multiple sets of
1086
coefficients.
1087
1088
Returns
1089
-------
1090
values : ndarray, compatible object
1091
The values of the two dimensional polynomial at points in the Cartesian
1092
product of `x` and `y`.
1093
1094
See Also
1095
--------
1096
hermval, hermval2d, hermgrid2d, hermval3d
1097
1098
Notes
1099
-----
1100
1101
.. versionadded:: 1.7.0
1102
1103
"""
1104
return pu._gridnd(hermval, c, x, y, z)
1105
1106
1107
def hermvander(x, deg):
1108
"""Pseudo-Vandermonde matrix of given degree.
1109
1110
Returns the pseudo-Vandermonde matrix of degree `deg` and sample points
1111
`x`. The pseudo-Vandermonde matrix is defined by
1112
1113
.. math:: V[..., i] = H_i(x),
1114
1115
where `0 <= i <= deg`. The leading indices of `V` index the elements of
1116
`x` and the last index is the degree of the Hermite polynomial.
1117
1118
If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the
1119
array ``V = hermvander(x, n)``, then ``np.dot(V, c)`` and
1120
``hermval(x, c)`` are the same up to roundoff. This equivalence is
1121
useful both for least squares fitting and for the evaluation of a large
1122
number of Hermite series of the same degree and sample points.
1123
1124
Parameters
1125
----------
1126
x : array_like
1127
Array of points. The dtype is converted to float64 or complex128
1128
depending on whether any of the elements are complex. If `x` is
1129
scalar it is converted to a 1-D array.
1130
deg : int
1131
Degree of the resulting matrix.
1132
1133
Returns
1134
-------
1135
vander : ndarray
1136
The pseudo-Vandermonde matrix. The shape of the returned matrix is
1137
``x.shape + (deg + 1,)``, where The last index is the degree of the
1138
corresponding Hermite polynomial. The dtype will be the same as
1139
the converted `x`.
1140
1141
Examples
1142
--------
1143
>>> from numpy.polynomial.hermite import hermvander
1144
>>> x = np.array([-1, 0, 1])
1145
>>> hermvander(x, 3)
1146
array([[ 1., -2., 2., 4.],
1147
[ 1., 0., -2., -0.],
1148
[ 1., 2., 2., -4.]])
1149
1150
"""
1151
ideg = pu._deprecate_as_int(deg, "deg")
1152
if ideg < 0:
1153
raise ValueError("deg must be non-negative")
1154
1155
x = np.array(x, copy=False, ndmin=1) + 0.0
1156
dims = (ideg + 1,) + x.shape
1157
dtyp = x.dtype
1158
v = np.empty(dims, dtype=dtyp)
1159
v[0] = x*0 + 1
1160
if ideg > 0:
1161
x2 = x*2
1162
v[1] = x2
1163
for i in range(2, ideg + 1):
1164
v[i] = (v[i-1]*x2 - v[i-2]*(2*(i - 1)))
1165
return np.moveaxis(v, 0, -1)
1166
1167
1168
def hermvander2d(x, y, deg):
1169
"""Pseudo-Vandermonde matrix of given degrees.
1170
1171
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
1172
points `(x, y)`. The pseudo-Vandermonde matrix is defined by
1173
1174
.. math:: V[..., (deg[1] + 1)*i + j] = H_i(x) * H_j(y),
1175
1176
where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of
1177
`V` index the points `(x, y)` and the last index encodes the degrees of
1178
the Hermite polynomials.
1179
1180
If ``V = hermvander2d(x, y, [xdeg, ydeg])``, then the columns of `V`
1181
correspond to the elements of a 2-D coefficient array `c` of shape
1182
(xdeg + 1, ydeg + 1) in the order
1183
1184
.. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ...
1185
1186
and ``np.dot(V, c.flat)`` and ``hermval2d(x, y, c)`` will be the same
1187
up to roundoff. This equivalence is useful both for least squares
1188
fitting and for the evaluation of a large number of 2-D Hermite
1189
series of the same degrees and sample points.
1190
1191
Parameters
1192
----------
1193
x, y : array_like
1194
Arrays of point coordinates, all of the same shape. The dtypes
1195
will be converted to either float64 or complex128 depending on
1196
whether any of the elements are complex. Scalars are converted to 1-D
1197
arrays.
1198
deg : list of ints
1199
List of maximum degrees of the form [x_deg, y_deg].
1200
1201
Returns
1202
-------
1203
vander2d : ndarray
1204
The shape of the returned matrix is ``x.shape + (order,)``, where
1205
:math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same
1206
as the converted `x` and `y`.
1207
1208
See Also
1209
--------
1210
hermvander, hermvander3d, hermval2d, hermval3d
1211
1212
Notes
1213
-----
1214
1215
.. versionadded:: 1.7.0
1216
1217
"""
1218
return pu._vander_nd_flat((hermvander, hermvander), (x, y), deg)
1219
1220
1221
def hermvander3d(x, y, z, deg):
1222
"""Pseudo-Vandermonde matrix of given degrees.
1223
1224
Returns the pseudo-Vandermonde matrix of degrees `deg` and sample
1225
points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`,
1226
then The pseudo-Vandermonde matrix is defined by
1227
1228
.. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = H_i(x)*H_j(y)*H_k(z),
1229
1230
where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading
1231
indices of `V` index the points `(x, y, z)` and the last index encodes
1232
the degrees of the Hermite polynomials.
1233
1234
If ``V = hermvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns
1235
of `V` correspond to the elements of a 3-D coefficient array `c` of
1236
shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order
1237
1238
.. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},...
1239
1240
and ``np.dot(V, c.flat)`` and ``hermval3d(x, y, z, c)`` will be the
1241
same up to roundoff. This equivalence is useful both for least squares
1242
fitting and for the evaluation of a large number of 3-D Hermite
1243
series of the same degrees and sample points.
1244
1245
Parameters
1246
----------
1247
x, y, z : array_like
1248
Arrays of point coordinates, all of the same shape. The dtypes will
1249
be converted to either float64 or complex128 depending on whether
1250
any of the elements are complex. Scalars are converted to 1-D
1251
arrays.
1252
deg : list of ints
1253
List of maximum degrees of the form [x_deg, y_deg, z_deg].
1254
1255
Returns
1256
-------
1257
vander3d : ndarray
1258
The shape of the returned matrix is ``x.shape + (order,)``, where
1259
:math:`order = (deg[0]+1)*(deg[1]+1)*(deg[2]+1)`. The dtype will
1260
be the same as the converted `x`, `y`, and `z`.
1261
1262
See Also
1263
--------
1264
hermvander, hermvander3d, hermval2d, hermval3d
1265
1266
Notes
1267
-----
1268
1269
.. versionadded:: 1.7.0
1270
1271
"""
1272
return pu._vander_nd_flat((hermvander, hermvander, hermvander), (x, y, z), deg)
1273
1274
1275
def hermfit(x, y, deg, rcond=None, full=False, w=None):
1276
"""
1277
Least squares fit of Hermite series to data.
1278
1279
Return the coefficients of a Hermite series of degree `deg` that is the
1280
least squares fit to the data values `y` given at points `x`. If `y` is
1281
1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple
1282
fits are done, one for each column of `y`, and the resulting
1283
coefficients are stored in the corresponding columns of a 2-D return.
1284
The fitted polynomial(s) are in the form
1285
1286
.. math:: p(x) = c_0 + c_1 * H_1(x) + ... + c_n * H_n(x),
1287
1288
where `n` is `deg`.
1289
1290
Parameters
1291
----------
1292
x : array_like, shape (M,)
1293
x-coordinates of the M sample points ``(x[i], y[i])``.
1294
y : array_like, shape (M,) or (M, K)
1295
y-coordinates of the sample points. Several data sets of sample
1296
points sharing the same x-coordinates can be fitted at once by
1297
passing in a 2D-array that contains one dataset per column.
1298
deg : int or 1-D array_like
1299
Degree(s) of the fitting polynomials. If `deg` is a single integer
1300
all terms up to and including the `deg`'th term are included in the
1301
fit. For NumPy versions >= 1.11.0 a list of integers specifying the
1302
degrees of the terms to include may be used instead.
1303
rcond : float, optional
1304
Relative condition number of the fit. Singular values smaller than
1305
this relative to the largest singular value will be ignored. The
1306
default value is len(x)*eps, where eps is the relative precision of
1307
the float type, about 2e-16 in most cases.
1308
full : bool, optional
1309
Switch determining nature of return value. When it is False (the
1310
default) just the coefficients are returned, when True diagnostic
1311
information from the singular value decomposition is also returned.
1312
w : array_like, shape (`M`,), optional
1313
Weights. If not None, the weight ``w[i]`` applies to the unsquared
1314
residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
1315
chosen so that the errors of the products ``w[i]*y[i]`` all have the
1316
same variance. When using inverse-variance weighting, use
1317
``w[i] = 1/sigma(y[i])``. The default value is None.
1318
1319
Returns
1320
-------
1321
coef : ndarray, shape (M,) or (M, K)
1322
Hermite coefficients ordered from low to high. If `y` was 2-D,
1323
the coefficients for the data in column k of `y` are in column
1324
`k`.
1325
1326
[residuals, rank, singular_values, rcond] : list
1327
These values are only returned if ``full == True``
1328
1329
- residuals -- sum of squared residuals of the least squares fit
1330
- rank -- the numerical rank of the scaled Vandermonde matrix
1331
- singular_values -- singular values of the scaled Vandermonde matrix
1332
- rcond -- value of `rcond`.
1333
1334
For more details, see `numpy.linalg.lstsq`.
1335
1336
Warns
1337
-----
1338
RankWarning
1339
The rank of the coefficient matrix in the least-squares fit is
1340
deficient. The warning is only raised if ``full == False``. The
1341
warnings can be turned off by
1342
1343
>>> import warnings
1344
>>> warnings.simplefilter('ignore', np.RankWarning)
1345
1346
See Also
1347
--------
1348
numpy.polynomial.chebyshev.chebfit
1349
numpy.polynomial.legendre.legfit
1350
numpy.polynomial.laguerre.lagfit
1351
numpy.polynomial.polynomial.polyfit
1352
numpy.polynomial.hermite_e.hermefit
1353
hermval : Evaluates a Hermite series.
1354
hermvander : Vandermonde matrix of Hermite series.
1355
hermweight : Hermite weight function
1356
numpy.linalg.lstsq : Computes a least-squares fit from the matrix.
1357
scipy.interpolate.UnivariateSpline : Computes spline fits.
1358
1359
Notes
1360
-----
1361
The solution is the coefficients of the Hermite series `p` that
1362
minimizes the sum of the weighted squared errors
1363
1364
.. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2,
1365
1366
where the :math:`w_j` are the weights. This problem is solved by
1367
setting up the (typically) overdetermined matrix equation
1368
1369
.. math:: V(x) * c = w * y,
1370
1371
where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the
1372
coefficients to be solved for, `w` are the weights, `y` are the
1373
observed values. This equation is then solved using the singular value
1374
decomposition of `V`.
1375
1376
If some of the singular values of `V` are so small that they are
1377
neglected, then a `RankWarning` will be issued. This means that the
1378
coefficient values may be poorly determined. Using a lower order fit
1379
will usually get rid of the warning. The `rcond` parameter can also be
1380
set to a value smaller than its default, but the resulting fit may be
1381
spurious and have large contributions from roundoff error.
1382
1383
Fits using Hermite series are probably most useful when the data can be
1384
approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the Hermite
1385
weight. In that case the weight ``sqrt(w(x[i]))`` should be used
1386
together with data values ``y[i]/sqrt(w(x[i]))``. The weight function is
1387
available as `hermweight`.
1388
1389
References
1390
----------
1391
.. [1] Wikipedia, "Curve fitting",
1392
https://en.wikipedia.org/wiki/Curve_fitting
1393
1394
Examples
1395
--------
1396
>>> from numpy.polynomial.hermite import hermfit, hermval
1397
>>> x = np.linspace(-10, 10)
1398
>>> err = np.random.randn(len(x))/10
1399
>>> y = hermval(x, [1, 2, 3]) + err
1400
>>> hermfit(x, y, 2)
1401
array([1.0218, 1.9986, 2.9999]) # may vary
1402
1403
"""
1404
return pu._fit(hermvander, x, y, deg, rcond, full, w)
1405
1406
1407
def hermcompanion(c):
1408
"""Return the scaled companion matrix of c.
1409
1410
The basis polynomials are scaled so that the companion matrix is
1411
symmetric when `c` is an Hermite basis polynomial. This provides
1412
better eigenvalue estimates than the unscaled case and for basis
1413
polynomials the eigenvalues are guaranteed to be real if
1414
`numpy.linalg.eigvalsh` is used to obtain them.
1415
1416
Parameters
1417
----------
1418
c : array_like
1419
1-D array of Hermite series coefficients ordered from low to high
1420
degree.
1421
1422
Returns
1423
-------
1424
mat : ndarray
1425
Scaled companion matrix of dimensions (deg, deg).
1426
1427
Notes
1428
-----
1429
1430
.. versionadded:: 1.7.0
1431
1432
"""
1433
# c is a trimmed copy
1434
[c] = pu.as_series([c])
1435
if len(c) < 2:
1436
raise ValueError('Series must have maximum degree of at least 1.')
1437
if len(c) == 2:
1438
return np.array([[-.5*c[0]/c[1]]])
1439
1440
n = len(c) - 1
1441
mat = np.zeros((n, n), dtype=c.dtype)
1442
scl = np.hstack((1., 1./np.sqrt(2.*np.arange(n - 1, 0, -1))))
1443
scl = np.multiply.accumulate(scl)[::-1]
1444
top = mat.reshape(-1)[1::n+1]
1445
bot = mat.reshape(-1)[n::n+1]
1446
top[...] = np.sqrt(.5*np.arange(1, n))
1447
bot[...] = top
1448
mat[:, -1] -= scl*c[:-1]/(2.0*c[-1])
1449
return mat
1450
1451
1452
def hermroots(c):
1453
"""
1454
Compute the roots of a Hermite series.
1455
1456
Return the roots (a.k.a. "zeros") of the polynomial
1457
1458
.. math:: p(x) = \\sum_i c[i] * H_i(x).
1459
1460
Parameters
1461
----------
1462
c : 1-D array_like
1463
1-D array of coefficients.
1464
1465
Returns
1466
-------
1467
out : ndarray
1468
Array of the roots of the series. If all the roots are real,
1469
then `out` is also real, otherwise it is complex.
1470
1471
See Also
1472
--------
1473
numpy.polynomial.polynomial.polyroots
1474
numpy.polynomial.legendre.legroots
1475
numpy.polynomial.laguerre.lagroots
1476
numpy.polynomial.chebyshev.chebroots
1477
numpy.polynomial.hermite_e.hermeroots
1478
1479
Notes
1480
-----
1481
The root estimates are obtained as the eigenvalues of the companion
1482
matrix, Roots far from the origin of the complex plane may have large
1483
errors due to the numerical instability of the series for such
1484
values. Roots with multiplicity greater than 1 will also show larger
1485
errors as the value of the series near such points is relatively
1486
insensitive to errors in the roots. Isolated roots near the origin can
1487
be improved by a few iterations of Newton's method.
1488
1489
The Hermite series basis polynomials aren't powers of `x` so the
1490
results of this function may seem unintuitive.
1491
1492
Examples
1493
--------
1494
>>> from numpy.polynomial.hermite import hermroots, hermfromroots
1495
>>> coef = hermfromroots([-1, 0, 1])
1496
>>> coef
1497
array([0. , 0.25 , 0. , 0.125])
1498
>>> hermroots(coef)
1499
array([-1.00000000e+00, -1.38777878e-17, 1.00000000e+00])
1500
1501
"""
1502
# c is a trimmed copy
1503
[c] = pu.as_series([c])
1504
if len(c) <= 1:
1505
return np.array([], dtype=c.dtype)
1506
if len(c) == 2:
1507
return np.array([-.5*c[0]/c[1]])
1508
1509
# rotated companion matrix reduces error
1510
m = hermcompanion(c)[::-1,::-1]
1511
r = la.eigvals(m)
1512
r.sort()
1513
return r
1514
1515
1516
def _normed_hermite_n(x, n):
1517
"""
1518
Evaluate a normalized Hermite polynomial.
1519
1520
Compute the value of the normalized Hermite polynomial of degree ``n``
1521
at the points ``x``.
1522
1523
1524
Parameters
1525
----------
1526
x : ndarray of double.
1527
Points at which to evaluate the function
1528
n : int
1529
Degree of the normalized Hermite function to be evaluated.
1530
1531
Returns
1532
-------
1533
values : ndarray
1534
The shape of the return value is described above.
1535
1536
Notes
1537
-----
1538
.. versionadded:: 1.10.0
1539
1540
This function is needed for finding the Gauss points and integration
1541
weights for high degrees. The values of the standard Hermite functions
1542
overflow when n >= 207.
1543
1544
"""
1545
if n == 0:
1546
return np.full(x.shape, 1/np.sqrt(np.sqrt(np.pi)))
1547
1548
c0 = 0.
1549
c1 = 1./np.sqrt(np.sqrt(np.pi))
1550
nd = float(n)
1551
for i in range(n - 1):
1552
tmp = c0
1553
c0 = -c1*np.sqrt((nd - 1.)/nd)
1554
c1 = tmp + c1*x*np.sqrt(2./nd)
1555
nd = nd - 1.0
1556
return c0 + c1*x*np.sqrt(2)
1557
1558
1559
def hermgauss(deg):
1560
"""
1561
Gauss-Hermite quadrature.
1562
1563
Computes the sample points and weights for Gauss-Hermite quadrature.
1564
These sample points and weights will correctly integrate polynomials of
1565
degree :math:`2*deg - 1` or less over the interval :math:`[-\\inf, \\inf]`
1566
with the weight function :math:`f(x) = \\exp(-x^2)`.
1567
1568
Parameters
1569
----------
1570
deg : int
1571
Number of sample points and weights. It must be >= 1.
1572
1573
Returns
1574
-------
1575
x : ndarray
1576
1-D ndarray containing the sample points.
1577
y : ndarray
1578
1-D ndarray containing the weights.
1579
1580
Notes
1581
-----
1582
1583
.. versionadded:: 1.7.0
1584
1585
The results have only been tested up to degree 100, higher degrees may
1586
be problematic. The weights are determined by using the fact that
1587
1588
.. math:: w_k = c / (H'_n(x_k) * H_{n-1}(x_k))
1589
1590
where :math:`c` is a constant independent of :math:`k` and :math:`x_k`
1591
is the k'th root of :math:`H_n`, and then scaling the results to get
1592
the right value when integrating 1.
1593
1594
"""
1595
ideg = pu._deprecate_as_int(deg, "deg")
1596
if ideg <= 0:
1597
raise ValueError("deg must be a positive integer")
1598
1599
# first approximation of roots. We use the fact that the companion
1600
# matrix is symmetric in this case in order to obtain better zeros.
1601
c = np.array([0]*deg + [1], dtype=np.float64)
1602
m = hermcompanion(c)
1603
x = la.eigvalsh(m)
1604
1605
# improve roots by one application of Newton
1606
dy = _normed_hermite_n(x, ideg)
1607
df = _normed_hermite_n(x, ideg - 1) * np.sqrt(2*ideg)
1608
x -= dy/df
1609
1610
# compute the weights. We scale the factor to avoid possible numerical
1611
# overflow.
1612
fm = _normed_hermite_n(x, ideg - 1)
1613
fm /= np.abs(fm).max()
1614
w = 1/(fm * fm)
1615
1616
# for Hermite we can also symmetrize
1617
w = (w + w[::-1])/2
1618
x = (x - x[::-1])/2
1619
1620
# scale w to get the right value
1621
w *= np.sqrt(np.pi) / w.sum()
1622
1623
return x, w
1624
1625
1626
def hermweight(x):
1627
"""
1628
Weight function of the Hermite polynomials.
1629
1630
The weight function is :math:`\\exp(-x^2)` and the interval of
1631
integration is :math:`[-\\inf, \\inf]`. the Hermite polynomials are
1632
orthogonal, but not normalized, with respect to this weight function.
1633
1634
Parameters
1635
----------
1636
x : array_like
1637
Values at which the weight function will be computed.
1638
1639
Returns
1640
-------
1641
w : ndarray
1642
The weight function at `x`.
1643
1644
Notes
1645
-----
1646
1647
.. versionadded:: 1.7.0
1648
1649
"""
1650
w = np.exp(-x**2)
1651
return w
1652
1653
1654
#
1655
# Hermite series class
1656
#
1657
1658
class Hermite(ABCPolyBase):
1659
"""An Hermite series class.
1660
1661
The Hermite class provides the standard Python numerical methods
1662
'+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the
1663
attributes and methods listed in the `ABCPolyBase` documentation.
1664
1665
Parameters
1666
----------
1667
coef : array_like
1668
Hermite coefficients in order of increasing degree, i.e,
1669
``(1, 2, 3)`` gives ``1*H_0(x) + 2*H_1(X) + 3*H_2(x)``.
1670
domain : (2,) array_like, optional
1671
Domain to use. The interval ``[domain[0], domain[1]]`` is mapped
1672
to the interval ``[window[0], window[1]]`` by shifting and scaling.
1673
The default value is [-1, 1].
1674
window : (2,) array_like, optional
1675
Window, see `domain` for its use. The default value is [-1, 1].
1676
1677
.. versionadded:: 1.6.0
1678
1679
"""
1680
# Virtual Functions
1681
_add = staticmethod(hermadd)
1682
_sub = staticmethod(hermsub)
1683
_mul = staticmethod(hermmul)
1684
_div = staticmethod(hermdiv)
1685
_pow = staticmethod(hermpow)
1686
_val = staticmethod(hermval)
1687
_int = staticmethod(hermint)
1688
_der = staticmethod(hermder)
1689
_fit = staticmethod(hermfit)
1690
_line = staticmethod(hermline)
1691
_roots = staticmethod(hermroots)
1692
_fromroots = staticmethod(hermfromroots)
1693
1694
# Virtual properties
1695
domain = np.array(hermdomain)
1696
window = np.array(hermdomain)
1697
basis_name = 'H'
1698
1699