test_classes.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. """Test inter-conversion of different polynomial classes.
  2. This tests the convert and cast methods of all the polynomial classes.
  3. """
  4. import operator as op
  5. from numbers import Number
  6. import pytest
  7. import numpy as np
  8. from numpy.polynomial import (
  9. Polynomial, Legendre, Chebyshev, Laguerre, Hermite, HermiteE)
  10. from numpy.testing import (
  11. assert_almost_equal, assert_raises, assert_equal, assert_,
  12. )
  13. from numpy.polynomial.polyutils import RankWarning
  14. #
  15. # fixtures
  16. #
  17. classes = (
  18. Polynomial, Legendre, Chebyshev, Laguerre,
  19. Hermite, HermiteE
  20. )
  21. classids = tuple(cls.__name__ for cls in classes)
  22. @pytest.fixture(params=classes, ids=classids)
  23. def Poly(request):
  24. return request.param
  25. #
  26. # helper functions
  27. #
  28. random = np.random.random
  29. def assert_poly_almost_equal(p1, p2, msg=""):
  30. try:
  31. assert_(np.all(p1.domain == p2.domain))
  32. assert_(np.all(p1.window == p2.window))
  33. assert_almost_equal(p1.coef, p2.coef)
  34. except AssertionError:
  35. msg = f"Result: {p1}\nTarget: {p2}"
  36. raise AssertionError(msg)
  37. #
  38. # Test conversion methods that depend on combinations of two classes.
  39. #
  40. Poly1 = Poly
  41. Poly2 = Poly
  42. def test_conversion(Poly1, Poly2):
  43. x = np.linspace(0, 1, 10)
  44. coef = random((3,))
  45. d1 = Poly1.domain + random((2,))*.25
  46. w1 = Poly1.window + random((2,))*.25
  47. p1 = Poly1(coef, domain=d1, window=w1)
  48. d2 = Poly2.domain + random((2,))*.25
  49. w2 = Poly2.window + random((2,))*.25
  50. p2 = p1.convert(kind=Poly2, domain=d2, window=w2)
  51. assert_almost_equal(p2.domain, d2)
  52. assert_almost_equal(p2.window, w2)
  53. assert_almost_equal(p2(x), p1(x))
  54. def test_cast(Poly1, Poly2):
  55. x = np.linspace(0, 1, 10)
  56. coef = random((3,))
  57. d1 = Poly1.domain + random((2,))*.25
  58. w1 = Poly1.window + random((2,))*.25
  59. p1 = Poly1(coef, domain=d1, window=w1)
  60. d2 = Poly2.domain + random((2,))*.25
  61. w2 = Poly2.window + random((2,))*.25
  62. p2 = Poly2.cast(p1, domain=d2, window=w2)
  63. assert_almost_equal(p2.domain, d2)
  64. assert_almost_equal(p2.window, w2)
  65. assert_almost_equal(p2(x), p1(x))
  66. #
  67. # test methods that depend on one class
  68. #
  69. def test_identity(Poly):
  70. d = Poly.domain + random((2,))*.25
  71. w = Poly.window + random((2,))*.25
  72. x = np.linspace(d[0], d[1], 11)
  73. p = Poly.identity(domain=d, window=w)
  74. assert_equal(p.domain, d)
  75. assert_equal(p.window, w)
  76. assert_almost_equal(p(x), x)
  77. def test_basis(Poly):
  78. d = Poly.domain + random((2,))*.25
  79. w = Poly.window + random((2,))*.25
  80. p = Poly.basis(5, domain=d, window=w)
  81. assert_equal(p.domain, d)
  82. assert_equal(p.window, w)
  83. assert_equal(p.coef, [0]*5 + [1])
  84. def test_fromroots(Poly):
  85. # check that requested roots are zeros of a polynomial
  86. # of correct degree, domain, and window.
  87. d = Poly.domain + random((2,))*.25
  88. w = Poly.window + random((2,))*.25
  89. r = random((5,))
  90. p1 = Poly.fromroots(r, domain=d, window=w)
  91. assert_equal(p1.degree(), len(r))
  92. assert_equal(p1.domain, d)
  93. assert_equal(p1.window, w)
  94. assert_almost_equal(p1(r), 0)
  95. # check that polynomial is monic
  96. pdom = Polynomial.domain
  97. pwin = Polynomial.window
  98. p2 = Polynomial.cast(p1, domain=pdom, window=pwin)
  99. assert_almost_equal(p2.coef[-1], 1)
  100. def test_bad_conditioned_fit(Poly):
  101. x = [0., 0., 1.]
  102. y = [1., 2., 3.]
  103. # check RankWarning is raised
  104. with pytest.warns(RankWarning) as record:
  105. Poly.fit(x, y, 2)
  106. assert record[0].message.args[0] == "The fit may be poorly conditioned"
  107. def test_fit(Poly):
  108. def f(x):
  109. return x*(x - 1)*(x - 2)
  110. x = np.linspace(0, 3)
  111. y = f(x)
  112. # check default value of domain and window
  113. p = Poly.fit(x, y, 3)
  114. assert_almost_equal(p.domain, [0, 3])
  115. assert_almost_equal(p(x), y)
  116. assert_equal(p.degree(), 3)
  117. # check with given domains and window
  118. d = Poly.domain + random((2,))*.25
  119. w = Poly.window + random((2,))*.25
  120. p = Poly.fit(x, y, 3, domain=d, window=w)
  121. assert_almost_equal(p(x), y)
  122. assert_almost_equal(p.domain, d)
  123. assert_almost_equal(p.window, w)
  124. p = Poly.fit(x, y, [0, 1, 2, 3], domain=d, window=w)
  125. assert_almost_equal(p(x), y)
  126. assert_almost_equal(p.domain, d)
  127. assert_almost_equal(p.window, w)
  128. # check with class domain default
  129. p = Poly.fit(x, y, 3, [])
  130. assert_equal(p.domain, Poly.domain)
  131. assert_equal(p.window, Poly.window)
  132. p = Poly.fit(x, y, [0, 1, 2, 3], [])
  133. assert_equal(p.domain, Poly.domain)
  134. assert_equal(p.window, Poly.window)
  135. # check that fit accepts weights.
  136. w = np.zeros_like(x)
  137. z = y + random(y.shape)*.25
  138. w[::2] = 1
  139. p1 = Poly.fit(x[::2], z[::2], 3)
  140. p2 = Poly.fit(x, z, 3, w=w)
  141. p3 = Poly.fit(x, z, [0, 1, 2, 3], w=w)
  142. assert_almost_equal(p1(x), p2(x))
  143. assert_almost_equal(p2(x), p3(x))
  144. def test_equal(Poly):
  145. p1 = Poly([1, 2, 3], domain=[0, 1], window=[2, 3])
  146. p2 = Poly([1, 1, 1], domain=[0, 1], window=[2, 3])
  147. p3 = Poly([1, 2, 3], domain=[1, 2], window=[2, 3])
  148. p4 = Poly([1, 2, 3], domain=[0, 1], window=[1, 2])
  149. assert_(p1 == p1)
  150. assert_(not p1 == p2)
  151. assert_(not p1 == p3)
  152. assert_(not p1 == p4)
  153. def test_not_equal(Poly):
  154. p1 = Poly([1, 2, 3], domain=[0, 1], window=[2, 3])
  155. p2 = Poly([1, 1, 1], domain=[0, 1], window=[2, 3])
  156. p3 = Poly([1, 2, 3], domain=[1, 2], window=[2, 3])
  157. p4 = Poly([1, 2, 3], domain=[0, 1], window=[1, 2])
  158. assert_(not p1 != p1)
  159. assert_(p1 != p2)
  160. assert_(p1 != p3)
  161. assert_(p1 != p4)
  162. def test_add(Poly):
  163. # This checks commutation, not numerical correctness
  164. c1 = list(random((4,)) + .5)
  165. c2 = list(random((3,)) + .5)
  166. p1 = Poly(c1)
  167. p2 = Poly(c2)
  168. p3 = p1 + p2
  169. assert_poly_almost_equal(p2 + p1, p3)
  170. assert_poly_almost_equal(p1 + c2, p3)
  171. assert_poly_almost_equal(c2 + p1, p3)
  172. assert_poly_almost_equal(p1 + tuple(c2), p3)
  173. assert_poly_almost_equal(tuple(c2) + p1, p3)
  174. assert_poly_almost_equal(p1 + np.array(c2), p3)
  175. assert_poly_almost_equal(np.array(c2) + p1, p3)
  176. assert_raises(TypeError, op.add, p1, Poly([0], domain=Poly.domain + 1))
  177. assert_raises(TypeError, op.add, p1, Poly([0], window=Poly.window + 1))
  178. if Poly is Polynomial:
  179. assert_raises(TypeError, op.add, p1, Chebyshev([0]))
  180. else:
  181. assert_raises(TypeError, op.add, p1, Polynomial([0]))
  182. def test_sub(Poly):
  183. # This checks commutation, not numerical correctness
  184. c1 = list(random((4,)) + .5)
  185. c2 = list(random((3,)) + .5)
  186. p1 = Poly(c1)
  187. p2 = Poly(c2)
  188. p3 = p1 - p2
  189. assert_poly_almost_equal(p2 - p1, -p3)
  190. assert_poly_almost_equal(p1 - c2, p3)
  191. assert_poly_almost_equal(c2 - p1, -p3)
  192. assert_poly_almost_equal(p1 - tuple(c2), p3)
  193. assert_poly_almost_equal(tuple(c2) - p1, -p3)
  194. assert_poly_almost_equal(p1 - np.array(c2), p3)
  195. assert_poly_almost_equal(np.array(c2) - p1, -p3)
  196. assert_raises(TypeError, op.sub, p1, Poly([0], domain=Poly.domain + 1))
  197. assert_raises(TypeError, op.sub, p1, Poly([0], window=Poly.window + 1))
  198. if Poly is Polynomial:
  199. assert_raises(TypeError, op.sub, p1, Chebyshev([0]))
  200. else:
  201. assert_raises(TypeError, op.sub, p1, Polynomial([0]))
  202. def test_mul(Poly):
  203. c1 = list(random((4,)) + .5)
  204. c2 = list(random((3,)) + .5)
  205. p1 = Poly(c1)
  206. p2 = Poly(c2)
  207. p3 = p1 * p2
  208. assert_poly_almost_equal(p2 * p1, p3)
  209. assert_poly_almost_equal(p1 * c2, p3)
  210. assert_poly_almost_equal(c2 * p1, p3)
  211. assert_poly_almost_equal(p1 * tuple(c2), p3)
  212. assert_poly_almost_equal(tuple(c2) * p1, p3)
  213. assert_poly_almost_equal(p1 * np.array(c2), p3)
  214. assert_poly_almost_equal(np.array(c2) * p1, p3)
  215. assert_poly_almost_equal(p1 * 2, p1 * Poly([2]))
  216. assert_poly_almost_equal(2 * p1, p1 * Poly([2]))
  217. assert_raises(TypeError, op.mul, p1, Poly([0], domain=Poly.domain + 1))
  218. assert_raises(TypeError, op.mul, p1, Poly([0], window=Poly.window + 1))
  219. if Poly is Polynomial:
  220. assert_raises(TypeError, op.mul, p1, Chebyshev([0]))
  221. else:
  222. assert_raises(TypeError, op.mul, p1, Polynomial([0]))
  223. def test_floordiv(Poly):
  224. c1 = list(random((4,)) + .5)
  225. c2 = list(random((3,)) + .5)
  226. c3 = list(random((2,)) + .5)
  227. p1 = Poly(c1)
  228. p2 = Poly(c2)
  229. p3 = Poly(c3)
  230. p4 = p1 * p2 + p3
  231. c4 = list(p4.coef)
  232. assert_poly_almost_equal(p4 // p2, p1)
  233. assert_poly_almost_equal(p4 // c2, p1)
  234. assert_poly_almost_equal(c4 // p2, p1)
  235. assert_poly_almost_equal(p4 // tuple(c2), p1)
  236. assert_poly_almost_equal(tuple(c4) // p2, p1)
  237. assert_poly_almost_equal(p4 // np.array(c2), p1)
  238. assert_poly_almost_equal(np.array(c4) // p2, p1)
  239. assert_poly_almost_equal(2 // p2, Poly([0]))
  240. assert_poly_almost_equal(p2 // 2, 0.5*p2)
  241. assert_raises(
  242. TypeError, op.floordiv, p1, Poly([0], domain=Poly.domain + 1))
  243. assert_raises(
  244. TypeError, op.floordiv, p1, Poly([0], window=Poly.window + 1))
  245. if Poly is Polynomial:
  246. assert_raises(TypeError, op.floordiv, p1, Chebyshev([0]))
  247. else:
  248. assert_raises(TypeError, op.floordiv, p1, Polynomial([0]))
  249. def test_truediv(Poly):
  250. # true division is valid only if the denominator is a Number and
  251. # not a python bool.
  252. p1 = Poly([1,2,3])
  253. p2 = p1 * 5
  254. for stype in np.ScalarType:
  255. if not issubclass(stype, Number) or issubclass(stype, bool):
  256. continue
  257. s = stype(5)
  258. assert_poly_almost_equal(op.truediv(p2, s), p1)
  259. assert_raises(TypeError, op.truediv, s, p2)
  260. for stype in (int, float):
  261. s = stype(5)
  262. assert_poly_almost_equal(op.truediv(p2, s), p1)
  263. assert_raises(TypeError, op.truediv, s, p2)
  264. for stype in [complex]:
  265. s = stype(5, 0)
  266. assert_poly_almost_equal(op.truediv(p2, s), p1)
  267. assert_raises(TypeError, op.truediv, s, p2)
  268. for s in [tuple(), list(), dict(), bool(), np.array([1])]:
  269. assert_raises(TypeError, op.truediv, p2, s)
  270. assert_raises(TypeError, op.truediv, s, p2)
  271. for ptype in classes:
  272. assert_raises(TypeError, op.truediv, p2, ptype(1))
  273. def test_mod(Poly):
  274. # This checks commutation, not numerical correctness
  275. c1 = list(random((4,)) + .5)
  276. c2 = list(random((3,)) + .5)
  277. c3 = list(random((2,)) + .5)
  278. p1 = Poly(c1)
  279. p2 = Poly(c2)
  280. p3 = Poly(c3)
  281. p4 = p1 * p2 + p3
  282. c4 = list(p4.coef)
  283. assert_poly_almost_equal(p4 % p2, p3)
  284. assert_poly_almost_equal(p4 % c2, p3)
  285. assert_poly_almost_equal(c4 % p2, p3)
  286. assert_poly_almost_equal(p4 % tuple(c2), p3)
  287. assert_poly_almost_equal(tuple(c4) % p2, p3)
  288. assert_poly_almost_equal(p4 % np.array(c2), p3)
  289. assert_poly_almost_equal(np.array(c4) % p2, p3)
  290. assert_poly_almost_equal(2 % p2, Poly([2]))
  291. assert_poly_almost_equal(p2 % 2, Poly([0]))
  292. assert_raises(TypeError, op.mod, p1, Poly([0], domain=Poly.domain + 1))
  293. assert_raises(TypeError, op.mod, p1, Poly([0], window=Poly.window + 1))
  294. if Poly is Polynomial:
  295. assert_raises(TypeError, op.mod, p1, Chebyshev([0]))
  296. else:
  297. assert_raises(TypeError, op.mod, p1, Polynomial([0]))
  298. def test_divmod(Poly):
  299. # This checks commutation, not numerical correctness
  300. c1 = list(random((4,)) + .5)
  301. c2 = list(random((3,)) + .5)
  302. c3 = list(random((2,)) + .5)
  303. p1 = Poly(c1)
  304. p2 = Poly(c2)
  305. p3 = Poly(c3)
  306. p4 = p1 * p2 + p3
  307. c4 = list(p4.coef)
  308. quo, rem = divmod(p4, p2)
  309. assert_poly_almost_equal(quo, p1)
  310. assert_poly_almost_equal(rem, p3)
  311. quo, rem = divmod(p4, c2)
  312. assert_poly_almost_equal(quo, p1)
  313. assert_poly_almost_equal(rem, p3)
  314. quo, rem = divmod(c4, p2)
  315. assert_poly_almost_equal(quo, p1)
  316. assert_poly_almost_equal(rem, p3)
  317. quo, rem = divmod(p4, tuple(c2))
  318. assert_poly_almost_equal(quo, p1)
  319. assert_poly_almost_equal(rem, p3)
  320. quo, rem = divmod(tuple(c4), p2)
  321. assert_poly_almost_equal(quo, p1)
  322. assert_poly_almost_equal(rem, p3)
  323. quo, rem = divmod(p4, np.array(c2))
  324. assert_poly_almost_equal(quo, p1)
  325. assert_poly_almost_equal(rem, p3)
  326. quo, rem = divmod(np.array(c4), p2)
  327. assert_poly_almost_equal(quo, p1)
  328. assert_poly_almost_equal(rem, p3)
  329. quo, rem = divmod(p2, 2)
  330. assert_poly_almost_equal(quo, 0.5*p2)
  331. assert_poly_almost_equal(rem, Poly([0]))
  332. quo, rem = divmod(2, p2)
  333. assert_poly_almost_equal(quo, Poly([0]))
  334. assert_poly_almost_equal(rem, Poly([2]))
  335. assert_raises(TypeError, divmod, p1, Poly([0], domain=Poly.domain + 1))
  336. assert_raises(TypeError, divmod, p1, Poly([0], window=Poly.window + 1))
  337. if Poly is Polynomial:
  338. assert_raises(TypeError, divmod, p1, Chebyshev([0]))
  339. else:
  340. assert_raises(TypeError, divmod, p1, Polynomial([0]))
  341. def test_roots(Poly):
  342. d = Poly.domain * 1.25 + .25
  343. w = Poly.window
  344. tgt = np.linspace(d[0], d[1], 5)
  345. res = np.sort(Poly.fromroots(tgt, domain=d, window=w).roots())
  346. assert_almost_equal(res, tgt)
  347. # default domain and window
  348. res = np.sort(Poly.fromroots(tgt).roots())
  349. assert_almost_equal(res, tgt)
  350. def test_degree(Poly):
  351. p = Poly.basis(5)
  352. assert_equal(p.degree(), 5)
  353. def test_copy(Poly):
  354. p1 = Poly.basis(5)
  355. p2 = p1.copy()
  356. assert_(p1 == p2)
  357. assert_(p1 is not p2)
  358. assert_(p1.coef is not p2.coef)
  359. assert_(p1.domain is not p2.domain)
  360. assert_(p1.window is not p2.window)
  361. def test_integ(Poly):
  362. P = Polynomial
  363. # Check defaults
  364. p0 = Poly.cast(P([1*2, 2*3, 3*4]))
  365. p1 = P.cast(p0.integ())
  366. p2 = P.cast(p0.integ(2))
  367. assert_poly_almost_equal(p1, P([0, 2, 3, 4]))
  368. assert_poly_almost_equal(p2, P([0, 0, 1, 1, 1]))
  369. # Check with k
  370. p0 = Poly.cast(P([1*2, 2*3, 3*4]))
  371. p1 = P.cast(p0.integ(k=1))
  372. p2 = P.cast(p0.integ(2, k=[1, 1]))
  373. assert_poly_almost_equal(p1, P([1, 2, 3, 4]))
  374. assert_poly_almost_equal(p2, P([1, 1, 1, 1, 1]))
  375. # Check with lbnd
  376. p0 = Poly.cast(P([1*2, 2*3, 3*4]))
  377. p1 = P.cast(p0.integ(lbnd=1))
  378. p2 = P.cast(p0.integ(2, lbnd=1))
  379. assert_poly_almost_equal(p1, P([-9, 2, 3, 4]))
  380. assert_poly_almost_equal(p2, P([6, -9, 1, 1, 1]))
  381. # Check scaling
  382. d = 2*Poly.domain
  383. p0 = Poly.cast(P([1*2, 2*3, 3*4]), domain=d)
  384. p1 = P.cast(p0.integ())
  385. p2 = P.cast(p0.integ(2))
  386. assert_poly_almost_equal(p1, P([0, 2, 3, 4]))
  387. assert_poly_almost_equal(p2, P([0, 0, 1, 1, 1]))
  388. def test_deriv(Poly):
  389. # Check that the derivative is the inverse of integration. It is
  390. # assumes that the integration has been checked elsewhere.
  391. d = Poly.domain + random((2,))*.25
  392. w = Poly.window + random((2,))*.25
  393. p1 = Poly([1, 2, 3], domain=d, window=w)
  394. p2 = p1.integ(2, k=[1, 2])
  395. p3 = p1.integ(1, k=[1])
  396. assert_almost_equal(p2.deriv(1).coef, p3.coef)
  397. assert_almost_equal(p2.deriv(2).coef, p1.coef)
  398. # default domain and window
  399. p1 = Poly([1, 2, 3])
  400. p2 = p1.integ(2, k=[1, 2])
  401. p3 = p1.integ(1, k=[1])
  402. assert_almost_equal(p2.deriv(1).coef, p3.coef)
  403. assert_almost_equal(p2.deriv(2).coef, p1.coef)
  404. def test_linspace(Poly):
  405. d = Poly.domain + random((2,))*.25
  406. w = Poly.window + random((2,))*.25
  407. p = Poly([1, 2, 3], domain=d, window=w)
  408. # check default domain
  409. xtgt = np.linspace(d[0], d[1], 20)
  410. ytgt = p(xtgt)
  411. xres, yres = p.linspace(20)
  412. assert_almost_equal(xres, xtgt)
  413. assert_almost_equal(yres, ytgt)
  414. # check specified domain
  415. xtgt = np.linspace(0, 2, 20)
  416. ytgt = p(xtgt)
  417. xres, yres = p.linspace(20, domain=[0, 2])
  418. assert_almost_equal(xres, xtgt)
  419. assert_almost_equal(yres, ytgt)
  420. def test_pow(Poly):
  421. d = Poly.domain + random((2,))*.25
  422. w = Poly.window + random((2,))*.25
  423. tgt = Poly([1], domain=d, window=w)
  424. tst = Poly([1, 2, 3], domain=d, window=w)
  425. for i in range(5):
  426. assert_poly_almost_equal(tst**i, tgt)
  427. tgt = tgt * tst
  428. # default domain and window
  429. tgt = Poly([1])
  430. tst = Poly([1, 2, 3])
  431. for i in range(5):
  432. assert_poly_almost_equal(tst**i, tgt)
  433. tgt = tgt * tst
  434. # check error for invalid powers
  435. assert_raises(ValueError, op.pow, tgt, 1.5)
  436. assert_raises(ValueError, op.pow, tgt, -1)
  437. def test_call(Poly):
  438. P = Polynomial
  439. d = Poly.domain
  440. x = np.linspace(d[0], d[1], 11)
  441. # Check defaults
  442. p = Poly.cast(P([1, 2, 3]))
  443. tgt = 1 + x*(2 + 3*x)
  444. res = p(x)
  445. assert_almost_equal(res, tgt)
  446. def test_cutdeg(Poly):
  447. p = Poly([1, 2, 3])
  448. assert_raises(ValueError, p.cutdeg, .5)
  449. assert_raises(ValueError, p.cutdeg, -1)
  450. assert_equal(len(p.cutdeg(3)), 3)
  451. assert_equal(len(p.cutdeg(2)), 3)
  452. assert_equal(len(p.cutdeg(1)), 2)
  453. assert_equal(len(p.cutdeg(0)), 1)
  454. def test_truncate(Poly):
  455. p = Poly([1, 2, 3])
  456. assert_raises(ValueError, p.truncate, .5)
  457. assert_raises(ValueError, p.truncate, 0)
  458. assert_equal(len(p.truncate(4)), 3)
  459. assert_equal(len(p.truncate(3)), 3)
  460. assert_equal(len(p.truncate(2)), 2)
  461. assert_equal(len(p.truncate(1)), 1)
  462. def test_trim(Poly):
  463. c = [1, 1e-6, 1e-12, 0]
  464. p = Poly(c)
  465. assert_equal(p.trim().coef, c[:3])
  466. assert_equal(p.trim(1e-10).coef, c[:2])
  467. assert_equal(p.trim(1e-5).coef, c[:1])
  468. def test_mapparms(Poly):
  469. # check with defaults. Should be identity.
  470. d = Poly.domain
  471. w = Poly.window
  472. p = Poly([1], domain=d, window=w)
  473. assert_almost_equal([0, 1], p.mapparms())
  474. #
  475. w = 2*d + 1
  476. p = Poly([1], domain=d, window=w)
  477. assert_almost_equal([1, 2], p.mapparms())
  478. def test_ufunc_override(Poly):
  479. p = Poly([1, 2, 3])
  480. x = np.ones(3)
  481. assert_raises(TypeError, np.add, p, x)
  482. assert_raises(TypeError, np.add, x, p)
  483. #
  484. # Test class method that only exists for some classes
  485. #
  486. class TestInterpolate:
  487. def f(self, x):
  488. return x * (x - 1) * (x - 2)
  489. def test_raises(self):
  490. assert_raises(ValueError, Chebyshev.interpolate, self.f, -1)
  491. assert_raises(TypeError, Chebyshev.interpolate, self.f, 10.)
  492. def test_dimensions(self):
  493. for deg in range(1, 5):
  494. assert_(Chebyshev.interpolate(self.f, deg).degree() == deg)
  495. def test_approximation(self):
  496. def powx(x, p):
  497. return x**p
  498. x = np.linspace(0, 2, 10)
  499. for deg in range(0, 10):
  500. for t in range(0, deg + 1):
  501. p = Chebyshev.interpolate(powx, deg, domain=[0, 2], args=(t,))
  502. assert_almost_equal(p(x), powx(x, t), decimal=11)