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