hermite.py 57 KB

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