test_polynomial.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. """Tests for polynomial module.
  2. """
  3. import pickle
  4. from copy import deepcopy
  5. from fractions import Fraction
  6. from functools import reduce
  7. import pytest
  8. import numpy as np
  9. import numpy.polynomial.polynomial as poly
  10. from numpy.testing import (
  11. assert_,
  12. assert_almost_equal,
  13. assert_array_equal,
  14. assert_equal,
  15. assert_raises,
  16. assert_raises_regex,
  17. )
  18. def trim(x):
  19. return poly.polytrim(x, tol=1e-6)
  20. T0 = [1]
  21. T1 = [0, 1]
  22. T2 = [-1, 0, 2]
  23. T3 = [0, -3, 0, 4]
  24. T4 = [1, 0, -8, 0, 8]
  25. T5 = [0, 5, 0, -20, 0, 16]
  26. T6 = [-1, 0, 18, 0, -48, 0, 32]
  27. T7 = [0, -7, 0, 56, 0, -112, 0, 64]
  28. T8 = [1, 0, -32, 0, 160, 0, -256, 0, 128]
  29. T9 = [0, 9, 0, -120, 0, 432, 0, -576, 0, 256]
  30. Tlist = [T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]
  31. class TestConstants:
  32. def test_polydomain(self):
  33. assert_equal(poly.polydomain, [-1, 1])
  34. def test_polyzero(self):
  35. assert_equal(poly.polyzero, [0])
  36. def test_polyone(self):
  37. assert_equal(poly.polyone, [1])
  38. def test_polyx(self):
  39. assert_equal(poly.polyx, [0, 1])
  40. def test_copy(self):
  41. x = poly.Polynomial([1, 2, 3])
  42. y = deepcopy(x)
  43. assert_equal(x, y)
  44. def test_pickle(self):
  45. x = poly.Polynomial([1, 2, 3])
  46. y = pickle.loads(pickle.dumps(x))
  47. assert_equal(x, y)
  48. class TestArithmetic:
  49. def test_polyadd(self):
  50. for i in range(5):
  51. for j in range(5):
  52. msg = f"At i={i}, j={j}"
  53. tgt = np.zeros(max(i, j) + 1)
  54. tgt[i] += 1
  55. tgt[j] += 1
  56. res = poly.polyadd([0] * i + [1], [0] * j + [1])
  57. assert_equal(trim(res), trim(tgt), err_msg=msg)
  58. def test_polysub(self):
  59. for i in range(5):
  60. for j in range(5):
  61. msg = f"At i={i}, j={j}"
  62. tgt = np.zeros(max(i, j) + 1)
  63. tgt[i] += 1
  64. tgt[j] -= 1
  65. res = poly.polysub([0] * i + [1], [0] * j + [1])
  66. assert_equal(trim(res), trim(tgt), err_msg=msg)
  67. def test_polymulx(self):
  68. assert_equal(poly.polymulx([0]), [0])
  69. assert_equal(poly.polymulx([1]), [0, 1])
  70. for i in range(1, 5):
  71. ser = [0] * i + [1]
  72. tgt = [0] * (i + 1) + [1]
  73. assert_equal(poly.polymulx(ser), tgt)
  74. def test_polymul(self):
  75. for i in range(5):
  76. for j in range(5):
  77. msg = f"At i={i}, j={j}"
  78. tgt = np.zeros(i + j + 1)
  79. tgt[i + j] += 1
  80. res = poly.polymul([0] * i + [1], [0] * j + [1])
  81. assert_equal(trim(res), trim(tgt), err_msg=msg)
  82. def test_polydiv(self):
  83. # check zero division
  84. assert_raises(ZeroDivisionError, poly.polydiv, [1], [0])
  85. # check scalar division
  86. quo, rem = poly.polydiv([2], [2])
  87. assert_equal((quo, rem), (1, 0))
  88. quo, rem = poly.polydiv([2, 2], [2])
  89. assert_equal((quo, rem), ((1, 1), 0))
  90. # check rest.
  91. for i in range(5):
  92. for j in range(5):
  93. msg = f"At i={i}, j={j}"
  94. ci = [0] * i + [1, 2]
  95. cj = [0] * j + [1, 2]
  96. tgt = poly.polyadd(ci, cj)
  97. quo, rem = poly.polydiv(tgt, ci)
  98. res = poly.polyadd(poly.polymul(quo, ci), rem)
  99. assert_equal(res, tgt, err_msg=msg)
  100. def test_polypow(self):
  101. for i in range(5):
  102. for j in range(5):
  103. msg = f"At i={i}, j={j}"
  104. c = np.arange(i + 1)
  105. tgt = reduce(poly.polymul, [c] * j, np.array([1]))
  106. res = poly.polypow(c, j)
  107. assert_equal(trim(res), trim(tgt), err_msg=msg)
  108. class TestFraction:
  109. def test_Fraction(self):
  110. # assert we can use Polynomials with coefficients of object dtype
  111. f = Fraction(2, 3)
  112. one = Fraction(1, 1)
  113. zero = Fraction(0, 1)
  114. p = poly.Polynomial([f, f], domain=[zero, one], window=[zero, one])
  115. x = 2 * p + p ** 2
  116. assert_equal(x.coef, np.array([Fraction(16, 9), Fraction(20, 9),
  117. Fraction(4, 9)], dtype=object))
  118. assert_equal(p.domain, [zero, one])
  119. assert_equal(p.coef.dtype, np.dtypes.ObjectDType())
  120. assert_(isinstance(p(f), Fraction))
  121. assert_equal(p(f), Fraction(10, 9))
  122. p_deriv = poly.Polynomial([Fraction(2, 3)], domain=[zero, one],
  123. window=[zero, one])
  124. assert_equal(p.deriv(), p_deriv)
  125. class TestEvaluation:
  126. # coefficients of 1 + 2*x + 3*x**2
  127. c1d = np.array([1., 2., 3.])
  128. c2d = np.einsum('i,j->ij', c1d, c1d)
  129. c3d = np.einsum('i,j,k->ijk', c1d, c1d, c1d)
  130. # some random values in [-1, 1)
  131. x = np.random.random((3, 5)) * 2 - 1
  132. y = poly.polyval(x, [1., 2., 3.])
  133. def test_polyval(self):
  134. # check empty input
  135. assert_equal(poly.polyval([], [1]).size, 0)
  136. # check normal input)
  137. x = np.linspace(-1, 1)
  138. y = [x**i for i in range(5)]
  139. for i in range(5):
  140. tgt = y[i]
  141. res = poly.polyval(x, [0] * i + [1])
  142. assert_almost_equal(res, tgt)
  143. tgt = x * (x**2 - 1)
  144. res = poly.polyval(x, [0, -1, 0, 1])
  145. assert_almost_equal(res, tgt)
  146. # check that shape is preserved
  147. for i in range(3):
  148. dims = [2] * i
  149. x = np.zeros(dims)
  150. assert_equal(poly.polyval(x, [1]).shape, dims)
  151. assert_equal(poly.polyval(x, [1, 0]).shape, dims)
  152. assert_equal(poly.polyval(x, [1, 0, 0]).shape, dims)
  153. # check masked arrays are processed correctly
  154. mask = [False, True, False]
  155. mx = np.ma.array([1, 2, 3], mask=mask)
  156. res = np.polyval([7, 5, 3], mx)
  157. assert_array_equal(res.mask, mask)
  158. # check subtypes of ndarray are preserved
  159. class C(np.ndarray):
  160. pass
  161. cx = np.array([1, 2, 3]).view(C)
  162. assert_equal(type(np.polyval([2, 3, 4], cx)), C)
  163. def test_polyvalfromroots(self):
  164. # check exception for broadcasting x values over root array with
  165. # too few dimensions
  166. assert_raises(ValueError, poly.polyvalfromroots,
  167. [1], [1], tensor=False)
  168. # check empty input
  169. assert_equal(poly.polyvalfromroots([], [1]).size, 0)
  170. assert_(poly.polyvalfromroots([], [1]).shape == (0,))
  171. # check empty input + multidimensional roots
  172. assert_equal(poly.polyvalfromroots([], [[1] * 5]).size, 0)
  173. assert_(poly.polyvalfromroots([], [[1] * 5]).shape == (5, 0))
  174. # check scalar input
  175. assert_equal(poly.polyvalfromroots(1, 1), 0)
  176. assert_(poly.polyvalfromroots(1, np.ones((3, 3))).shape == (3,))
  177. # check normal input)
  178. x = np.linspace(-1, 1)
  179. y = [x**i for i in range(5)]
  180. for i in range(1, 5):
  181. tgt = y[i]
  182. res = poly.polyvalfromroots(x, [0] * i)
  183. assert_almost_equal(res, tgt)
  184. tgt = x * (x - 1) * (x + 1)
  185. res = poly.polyvalfromroots(x, [-1, 0, 1])
  186. assert_almost_equal(res, tgt)
  187. # check that shape is preserved
  188. for i in range(3):
  189. dims = [2] * i
  190. x = np.zeros(dims)
  191. assert_equal(poly.polyvalfromroots(x, [1]).shape, dims)
  192. assert_equal(poly.polyvalfromroots(x, [1, 0]).shape, dims)
  193. assert_equal(poly.polyvalfromroots(x, [1, 0, 0]).shape, dims)
  194. # check compatibility with factorization
  195. ptest = [15, 2, -16, -2, 1]
  196. r = poly.polyroots(ptest)
  197. x = np.linspace(-1, 1)
  198. assert_almost_equal(poly.polyval(x, ptest),
  199. poly.polyvalfromroots(x, r))
  200. # check multidimensional arrays of roots and values
  201. # check tensor=False
  202. rshape = (3, 5)
  203. x = np.arange(-3, 2)
  204. r = np.random.randint(-5, 5, size=rshape)
  205. res = poly.polyvalfromroots(x, r, tensor=False)
  206. tgt = np.empty(r.shape[1:])
  207. for ii in range(tgt.size):
  208. tgt[ii] = poly.polyvalfromroots(x[ii], r[:, ii])
  209. assert_equal(res, tgt)
  210. # check tensor=True
  211. x = np.vstack([x, 2 * x])
  212. res = poly.polyvalfromroots(x, r, tensor=True)
  213. tgt = np.empty(r.shape[1:] + x.shape)
  214. for ii in range(r.shape[1]):
  215. for jj in range(x.shape[0]):
  216. tgt[ii, jj, :] = poly.polyvalfromroots(x[jj], r[:, ii])
  217. assert_equal(res, tgt)
  218. def test_polyval2d(self):
  219. x1, x2, x3 = self.x
  220. y1, y2, y3 = self.y
  221. # test exceptions
  222. assert_raises_regex(ValueError, 'incompatible',
  223. poly.polyval2d, x1, x2[:2], self.c2d)
  224. # test values
  225. tgt = y1 * y2
  226. res = poly.polyval2d(x1, x2, self.c2d)
  227. assert_almost_equal(res, tgt)
  228. # test shape
  229. z = np.ones((2, 3))
  230. res = poly.polyval2d(z, z, self.c2d)
  231. assert_(res.shape == (2, 3))
  232. def test_polyval3d(self):
  233. x1, x2, x3 = self.x
  234. y1, y2, y3 = self.y
  235. # test exceptions
  236. assert_raises_regex(ValueError, 'incompatible',
  237. poly.polyval3d, x1, x2, x3[:2], self.c3d)
  238. # test values
  239. tgt = y1 * y2 * y3
  240. res = poly.polyval3d(x1, x2, x3, self.c3d)
  241. assert_almost_equal(res, tgt)
  242. # test shape
  243. z = np.ones((2, 3))
  244. res = poly.polyval3d(z, z, z, self.c3d)
  245. assert_(res.shape == (2, 3))
  246. def test_polygrid2d(self):
  247. x1, x2, x3 = self.x
  248. y1, y2, y3 = self.y
  249. # test values
  250. tgt = np.einsum('i,j->ij', y1, y2)
  251. res = poly.polygrid2d(x1, x2, self.c2d)
  252. assert_almost_equal(res, tgt)
  253. # test shape
  254. z = np.ones((2, 3))
  255. res = poly.polygrid2d(z, z, self.c2d)
  256. assert_(res.shape == (2, 3) * 2)
  257. def test_polygrid3d(self):
  258. x1, x2, x3 = self.x
  259. y1, y2, y3 = self.y
  260. # test values
  261. tgt = np.einsum('i,j,k->ijk', y1, y2, y3)
  262. res = poly.polygrid3d(x1, x2, x3, self.c3d)
  263. assert_almost_equal(res, tgt)
  264. # test shape
  265. z = np.ones((2, 3))
  266. res = poly.polygrid3d(z, z, z, self.c3d)
  267. assert_(res.shape == (2, 3) * 3)
  268. class TestIntegral:
  269. def test_polyint(self):
  270. # check exceptions
  271. assert_raises(TypeError, poly.polyint, [0], .5)
  272. assert_raises(ValueError, poly.polyint, [0], -1)
  273. assert_raises(ValueError, poly.polyint, [0], 1, [0, 0])
  274. assert_raises(ValueError, poly.polyint, [0], lbnd=[0])
  275. assert_raises(ValueError, poly.polyint, [0], scl=[0])
  276. assert_raises(TypeError, poly.polyint, [0], axis=.5)
  277. assert_raises(TypeError, poly.polyint, [1, 1], 1.)
  278. # test integration of zero polynomial
  279. for i in range(2, 5):
  280. k = [0] * (i - 2) + [1]
  281. res = poly.polyint([0], m=i, k=k)
  282. assert_almost_equal(res, [0, 1])
  283. # check single integration with integration constant
  284. for i in range(5):
  285. scl = i + 1
  286. pol = [0] * i + [1]
  287. tgt = [i] + [0] * i + [1 / scl]
  288. res = poly.polyint(pol, m=1, k=[i])
  289. assert_almost_equal(trim(res), trim(tgt))
  290. # check single integration with integration constant and lbnd
  291. for i in range(5):
  292. scl = i + 1
  293. pol = [0] * i + [1]
  294. res = poly.polyint(pol, m=1, k=[i], lbnd=-1)
  295. assert_almost_equal(poly.polyval(-1, res), i)
  296. # check single integration with integration constant and scaling
  297. for i in range(5):
  298. scl = i + 1
  299. pol = [0] * i + [1]
  300. tgt = [i] + [0] * i + [2 / scl]
  301. res = poly.polyint(pol, m=1, k=[i], scl=2)
  302. assert_almost_equal(trim(res), trim(tgt))
  303. # check multiple integrations with default k
  304. for i in range(5):
  305. for j in range(2, 5):
  306. pol = [0] * i + [1]
  307. tgt = pol[:]
  308. for k in range(j):
  309. tgt = poly.polyint(tgt, m=1)
  310. res = poly.polyint(pol, m=j)
  311. assert_almost_equal(trim(res), trim(tgt))
  312. # check multiple integrations with defined k
  313. for i in range(5):
  314. for j in range(2, 5):
  315. pol = [0] * i + [1]
  316. tgt = pol[:]
  317. for k in range(j):
  318. tgt = poly.polyint(tgt, m=1, k=[k])
  319. res = poly.polyint(pol, m=j, k=list(range(j)))
  320. assert_almost_equal(trim(res), trim(tgt))
  321. # check multiple integrations with lbnd
  322. for i in range(5):
  323. for j in range(2, 5):
  324. pol = [0] * i + [1]
  325. tgt = pol[:]
  326. for k in range(j):
  327. tgt = poly.polyint(tgt, m=1, k=[k], lbnd=-1)
  328. res = poly.polyint(pol, m=j, k=list(range(j)), lbnd=-1)
  329. assert_almost_equal(trim(res), trim(tgt))
  330. # check multiple integrations with scaling
  331. for i in range(5):
  332. for j in range(2, 5):
  333. pol = [0] * i + [1]
  334. tgt = pol[:]
  335. for k in range(j):
  336. tgt = poly.polyint(tgt, m=1, k=[k], scl=2)
  337. res = poly.polyint(pol, m=j, k=list(range(j)), scl=2)
  338. assert_almost_equal(trim(res), trim(tgt))
  339. def test_polyint_axis(self):
  340. # check that axis keyword works
  341. c2d = np.random.random((3, 4))
  342. tgt = np.vstack([poly.polyint(c) for c in c2d.T]).T
  343. res = poly.polyint(c2d, axis=0)
  344. assert_almost_equal(res, tgt)
  345. tgt = np.vstack([poly.polyint(c) for c in c2d])
  346. res = poly.polyint(c2d, axis=1)
  347. assert_almost_equal(res, tgt)
  348. tgt = np.vstack([poly.polyint(c, k=3) for c in c2d])
  349. res = poly.polyint(c2d, k=3, axis=1)
  350. assert_almost_equal(res, tgt)
  351. class TestDerivative:
  352. def test_polyder(self):
  353. # check exceptions
  354. assert_raises(TypeError, poly.polyder, [0], .5)
  355. assert_raises(ValueError, poly.polyder, [0], -1)
  356. # check that zeroth derivative does nothing
  357. for i in range(5):
  358. tgt = [0] * i + [1]
  359. res = poly.polyder(tgt, m=0)
  360. assert_equal(trim(res), trim(tgt))
  361. # check that derivation is the inverse of integration
  362. for i in range(5):
  363. for j in range(2, 5):
  364. tgt = [0] * i + [1]
  365. res = poly.polyder(poly.polyint(tgt, m=j), m=j)
  366. assert_almost_equal(trim(res), trim(tgt))
  367. # check derivation with scaling
  368. for i in range(5):
  369. for j in range(2, 5):
  370. tgt = [0] * i + [1]
  371. res = poly.polyder(poly.polyint(tgt, m=j, scl=2), m=j, scl=.5)
  372. assert_almost_equal(trim(res), trim(tgt))
  373. def test_polyder_axis(self):
  374. # check that axis keyword works
  375. c2d = np.random.random((3, 4))
  376. tgt = np.vstack([poly.polyder(c) for c in c2d.T]).T
  377. res = poly.polyder(c2d, axis=0)
  378. assert_almost_equal(res, tgt)
  379. tgt = np.vstack([poly.polyder(c) for c in c2d])
  380. res = poly.polyder(c2d, axis=1)
  381. assert_almost_equal(res, tgt)
  382. class TestVander:
  383. # some random values in [-1, 1)
  384. x = np.random.random((3, 5)) * 2 - 1
  385. def test_polyvander(self):
  386. # check for 1d x
  387. x = np.arange(3)
  388. v = poly.polyvander(x, 3)
  389. assert_(v.shape == (3, 4))
  390. for i in range(4):
  391. coef = [0] * i + [1]
  392. assert_almost_equal(v[..., i], poly.polyval(x, coef))
  393. # check for 2d x
  394. x = np.array([[1, 2], [3, 4], [5, 6]])
  395. v = poly.polyvander(x, 3)
  396. assert_(v.shape == (3, 2, 4))
  397. for i in range(4):
  398. coef = [0] * i + [1]
  399. assert_almost_equal(v[..., i], poly.polyval(x, coef))
  400. def test_polyvander2d(self):
  401. # also tests polyval2d for non-square coefficient array
  402. x1, x2, x3 = self.x
  403. c = np.random.random((2, 3))
  404. van = poly.polyvander2d(x1, x2, [1, 2])
  405. tgt = poly.polyval2d(x1, x2, c)
  406. res = np.dot(van, c.flat)
  407. assert_almost_equal(res, tgt)
  408. # check shape
  409. van = poly.polyvander2d([x1], [x2], [1, 2])
  410. assert_(van.shape == (1, 5, 6))
  411. def test_polyvander3d(self):
  412. # also tests polyval3d for non-square coefficient array
  413. x1, x2, x3 = self.x
  414. c = np.random.random((2, 3, 4))
  415. van = poly.polyvander3d(x1, x2, x3, [1, 2, 3])
  416. tgt = poly.polyval3d(x1, x2, x3, c)
  417. res = np.dot(van, c.flat)
  418. assert_almost_equal(res, tgt)
  419. # check shape
  420. van = poly.polyvander3d([x1], [x2], [x3], [1, 2, 3])
  421. assert_(van.shape == (1, 5, 24))
  422. def test_polyvandernegdeg(self):
  423. x = np.arange(3)
  424. assert_raises(ValueError, poly.polyvander, x, -1)
  425. class TestCompanion:
  426. def test_raises(self):
  427. assert_raises(ValueError, poly.polycompanion, [])
  428. assert_raises(ValueError, poly.polycompanion, [1])
  429. def test_dimensions(self):
  430. for i in range(1, 5):
  431. coef = [0] * i + [1]
  432. assert_(poly.polycompanion(coef).shape == (i, i))
  433. def test_linear_root(self):
  434. assert_(poly.polycompanion([1, 2])[0, 0] == -.5)
  435. class TestMisc:
  436. def test_polyfromroots(self):
  437. res = poly.polyfromroots([])
  438. assert_almost_equal(trim(res), [1])
  439. for i in range(1, 5):
  440. roots = np.cos(np.linspace(-np.pi, 0, 2 * i + 1)[1::2])
  441. tgt = Tlist[i]
  442. res = poly.polyfromroots(roots) * 2**(i - 1)
  443. assert_almost_equal(trim(res), trim(tgt))
  444. def test_polyroots(self):
  445. assert_almost_equal(poly.polyroots([1]), [])
  446. assert_almost_equal(poly.polyroots([1, 2]), [-.5])
  447. for i in range(2, 5):
  448. tgt = np.linspace(-1, 1, i)
  449. res = poly.polyroots(poly.polyfromroots(tgt))
  450. assert_almost_equal(trim(res), trim(tgt))
  451. # Testing for larger root values
  452. for i in np.logspace(10, 25, num=1000, base=10):
  453. tgt = np.array([-1, 1, i])
  454. res = poly.polyroots(poly.polyfromroots(tgt))
  455. # Adapting the expected precision according to the root value,
  456. # to take into account numerical calculation error.
  457. assert_almost_equal(res, tgt, 15 - int(np.log10(i)))
  458. for i in np.logspace(10, 25, num=1000, base=10):
  459. tgt = np.array([-1, 1.01, i])
  460. res = poly.polyroots(poly.polyfromroots(tgt))
  461. # Adapting the expected precision according to the root value,
  462. # to take into account numerical calculation error.
  463. assert_almost_equal(res, tgt, 14 - int(np.log10(i)))
  464. def test_polyfit(self):
  465. def f(x):
  466. return x * (x - 1) * (x - 2)
  467. def f2(x):
  468. return x**4 + x**2 + 1
  469. # Test exceptions
  470. assert_raises(ValueError, poly.polyfit, [1], [1], -1)
  471. assert_raises(TypeError, poly.polyfit, [[1]], [1], 0)
  472. assert_raises(TypeError, poly.polyfit, [], [1], 0)
  473. assert_raises(TypeError, poly.polyfit, [1], [[[1]]], 0)
  474. assert_raises(TypeError, poly.polyfit, [1, 2], [1], 0)
  475. assert_raises(TypeError, poly.polyfit, [1], [1, 2], 0)
  476. assert_raises(TypeError, poly.polyfit, [1], [1], 0, w=[[1]])
  477. assert_raises(TypeError, poly.polyfit, [1], [1], 0, w=[1, 1])
  478. assert_raises(ValueError, poly.polyfit, [1], [1], [-1,])
  479. assert_raises(ValueError, poly.polyfit, [1], [1], [2, -1, 6])
  480. assert_raises(TypeError, poly.polyfit, [1], [1], [])
  481. # Test fit
  482. x = np.linspace(0, 2)
  483. y = f(x)
  484. #
  485. coef3 = poly.polyfit(x, y, 3)
  486. assert_equal(len(coef3), 4)
  487. assert_almost_equal(poly.polyval(x, coef3), y)
  488. coef3 = poly.polyfit(x, y, [0, 1, 2, 3])
  489. assert_equal(len(coef3), 4)
  490. assert_almost_equal(poly.polyval(x, coef3), y)
  491. #
  492. coef4 = poly.polyfit(x, y, 4)
  493. assert_equal(len(coef4), 5)
  494. assert_almost_equal(poly.polyval(x, coef4), y)
  495. coef4 = poly.polyfit(x, y, [0, 1, 2, 3, 4])
  496. assert_equal(len(coef4), 5)
  497. assert_almost_equal(poly.polyval(x, coef4), y)
  498. #
  499. coef2d = poly.polyfit(x, np.array([y, y]).T, 3)
  500. assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
  501. coef2d = poly.polyfit(x, np.array([y, y]).T, [0, 1, 2, 3])
  502. assert_almost_equal(coef2d, np.array([coef3, coef3]).T)
  503. # test weighting
  504. w = np.zeros_like(x)
  505. yw = y.copy()
  506. w[1::2] = 1
  507. yw[0::2] = 0
  508. wcoef3 = poly.polyfit(x, yw, 3, w=w)
  509. assert_almost_equal(wcoef3, coef3)
  510. wcoef3 = poly.polyfit(x, yw, [0, 1, 2, 3], w=w)
  511. assert_almost_equal(wcoef3, coef3)
  512. #
  513. wcoef2d = poly.polyfit(x, np.array([yw, yw]).T, 3, w=w)
  514. assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
  515. wcoef2d = poly.polyfit(x, np.array([yw, yw]).T, [0, 1, 2, 3], w=w)
  516. assert_almost_equal(wcoef2d, np.array([coef3, coef3]).T)
  517. # test scaling with complex values x points whose square
  518. # is zero when summed.
  519. x = [1, 1j, -1, -1j]
  520. assert_almost_equal(poly.polyfit(x, x, 1), [0, 1])
  521. assert_almost_equal(poly.polyfit(x, x, [0, 1]), [0, 1])
  522. # test fitting only even Polyendre polynomials
  523. x = np.linspace(-1, 1)
  524. y = f2(x)
  525. coef1 = poly.polyfit(x, y, 4)
  526. assert_almost_equal(poly.polyval(x, coef1), y)
  527. coef2 = poly.polyfit(x, y, [0, 2, 4])
  528. assert_almost_equal(poly.polyval(x, coef2), y)
  529. assert_almost_equal(coef1, coef2)
  530. def test_polytrim(self):
  531. coef = [2, -1, 1, 0]
  532. # Test exceptions
  533. assert_raises(ValueError, poly.polytrim, coef, -1)
  534. # Test results
  535. assert_equal(poly.polytrim(coef), coef[:-1])
  536. assert_equal(poly.polytrim(coef, 1), coef[:-3])
  537. assert_equal(poly.polytrim(coef, 2), [0])
  538. def test_polyline(self):
  539. assert_equal(poly.polyline(3, 4), [3, 4])
  540. def test_polyline_zero(self):
  541. assert_equal(poly.polyline(3, 0), [3])
  542. def test_fit_degenerate_domain(self):
  543. p = poly.Polynomial.fit([1], [2], deg=0)
  544. assert_equal(p.coef, [2.])
  545. p = poly.Polynomial.fit([1, 1], [2, 2.1], deg=0)
  546. assert_almost_equal(p.coef, [2.05])
  547. with pytest.warns(np.exceptions.RankWarning):
  548. p = poly.Polynomial.fit([1, 1], [2, 2.1], deg=1)
  549. def test_result_type(self):
  550. w = np.array([-1, 1], dtype=np.float32)
  551. p = np.polynomial.Polynomial(w, domain=w, window=w)
  552. v = p(2)
  553. assert_equal(v.dtype, np.float32)
  554. arr = np.polydiv(1, np.float32(1))
  555. assert_equal(arr[0].dtype, np.float64)
  556. class ArrayFunctionInterceptor:
  557. def __init__(self):
  558. self.called = False
  559. def __array_function__(self, func, types, args, kwargs):
  560. self.called = True
  561. return "intercepted"
  562. def test_polyval2d_array_function_hook():
  563. x = ArrayFunctionInterceptor()
  564. y = ArrayFunctionInterceptor()
  565. c = ArrayFunctionInterceptor()
  566. result = np.polynomial.polynomial.polyval2d(x, y, c)
  567. assert result == "intercepted"
  568. def test_polygrid2d_array_function_hook():
  569. x = ArrayFunctionInterceptor()
  570. y = ArrayFunctionInterceptor()
  571. c = ArrayFunctionInterceptor()
  572. result = np.polynomial.polynomial.polygrid2d(x, y, c)
  573. assert result == "intercepted"