hermite.py 56 KB

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