Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/numpy/polynomial/chebyshev.py: 14%

357 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1""" 

2==================================================== 

3Chebyshev Series (:mod:`numpy.polynomial.chebyshev`) 

4==================================================== 

5 

6This module provides a number of objects (mostly functions) useful for 

7dealing with Chebyshev series, including a `Chebyshev` class that 

8encapsulates the usual arithmetic operations. (General information 

9on how this module represents and works with such polynomials is in the 

10docstring for its "parent" sub-package, `numpy.polynomial`). 

11 

12Classes 

13------- 

14 

15.. autosummary:: 

16 :toctree: generated/ 

17 

18 Chebyshev 

19 

20 

21Constants 

22--------- 

23 

24.. autosummary:: 

25 :toctree: generated/ 

26 

27 chebdomain 

28 chebzero 

29 chebone 

30 chebx 

31 

32Arithmetic 

33---------- 

34 

35.. autosummary:: 

36 :toctree: generated/ 

37 

38 chebadd 

39 chebsub 

40 chebmulx 

41 chebmul 

42 chebdiv 

43 chebpow 

44 chebval 

45 chebval2d 

46 chebval3d 

47 chebgrid2d 

48 chebgrid3d 

49 

50Calculus 

51-------- 

52 

53.. autosummary:: 

54 :toctree: generated/ 

55 

56 chebder 

57 chebint 

58 

59Misc Functions 

60-------------- 

61 

62.. autosummary:: 

63 :toctree: generated/ 

64 

65 chebfromroots 

66 chebroots 

67 chebvander 

68 chebvander2d 

69 chebvander3d 

70 chebgauss 

71 chebweight 

72 chebcompanion 

73 chebfit 

74 chebpts1 

75 chebpts2 

76 chebtrim 

77 chebline 

78 cheb2poly 

79 poly2cheb 

80 chebinterpolate 

81 

82See also 

83-------- 

84`numpy.polynomial` 

85 

86Notes 

87----- 

88The implementations of multiplication, division, integration, and 

89differentiation use the algebraic identities [1]_: 

90 

91.. math:: 

92 T_n(x) = \\frac{z^n + z^{-n}}{2} \\\\ 

93 z\\frac{dx}{dz} = \\frac{z - z^{-1}}{2}. 

94 

95where 

96 

97.. math:: x = \\frac{z + z^{-1}}{2}. 

98 

99These identities allow a Chebyshev series to be expressed as a finite, 

100symmetric Laurent series. In this module, this sort of Laurent series 

101is referred to as a "z-series." 

102 

103References 

104---------- 

105.. [1] A. T. Benjamin, et al., "Combinatorial Trigonometry with Chebyshev 

106 Polynomials," *Journal of Statistical Planning and Inference 14*, 2008 

107 (https://web.archive.org/web/20080221202153/https://www.math.hmc.edu/~benjamin/papers/CombTrig.pdf, pg. 4) 

108 

109""" 

110import numpy as np 

111import numpy.linalg as la 

112from numpy.core.multiarray import normalize_axis_index 

113 

114from . import polyutils as pu 

115from ._polybase import ABCPolyBase 

116 

117__all__ = [ 

118 'chebzero', 'chebone', 'chebx', 'chebdomain', 'chebline', 'chebadd', 

119 'chebsub', 'chebmulx', 'chebmul', 'chebdiv', 'chebpow', 'chebval', 

120 'chebder', 'chebint', 'cheb2poly', 'poly2cheb', 'chebfromroots', 

121 'chebvander', 'chebfit', 'chebtrim', 'chebroots', 'chebpts1', 

122 'chebpts2', 'Chebyshev', 'chebval2d', 'chebval3d', 'chebgrid2d', 

123 'chebgrid3d', 'chebvander2d', 'chebvander3d', 'chebcompanion', 

124 'chebgauss', 'chebweight', 'chebinterpolate'] 

125 

126chebtrim = pu.trimcoef 

127 

128# 

129# A collection of functions for manipulating z-series. These are private 

130# functions and do minimal error checking. 

131# 

132 

133def _cseries_to_zseries(c): 

134 """Convert Chebyshev series to z-series. 

135 

136 Convert a Chebyshev series to the equivalent z-series. The result is 

137 never an empty array. The dtype of the return is the same as that of 

138 the input. No checks are run on the arguments as this routine is for 

139 internal use. 

140 

141 Parameters 

142 ---------- 

143 c : 1-D ndarray 

144 Chebyshev coefficients, ordered from low to high 

145 

146 Returns 

147 ------- 

148 zs : 1-D ndarray 

149 Odd length symmetric z-series, ordered from low to high. 

150 

151 """ 

152 n = c.size 

153 zs = np.zeros(2*n-1, dtype=c.dtype) 

154 zs[n-1:] = c/2 

155 return zs + zs[::-1] 

156 

157 

158def _zseries_to_cseries(zs): 

159 """Convert z-series to a Chebyshev series. 

160 

161 Convert a z series to the equivalent Chebyshev series. The result is 

162 never an empty array. The dtype of the return is the same as that of 

163 the input. No checks are run on the arguments as this routine is for 

164 internal use. 

165 

166 Parameters 

167 ---------- 

168 zs : 1-D ndarray 

169 Odd length symmetric z-series, ordered from low to high. 

170 

171 Returns 

172 ------- 

173 c : 1-D ndarray 

174 Chebyshev coefficients, ordered from low to high. 

175 

176 """ 

177 n = (zs.size + 1)//2 

178 c = zs[n-1:].copy() 

179 c[1:n] *= 2 

180 return c 

181 

182 

183def _zseries_mul(z1, z2): 

184 """Multiply two z-series. 

185 

186 Multiply two z-series to produce a z-series. 

187 

188 Parameters 

189 ---------- 

190 z1, z2 : 1-D ndarray 

191 The arrays must be 1-D but this is not checked. 

192 

193 Returns 

194 ------- 

195 product : 1-D ndarray 

196 The product z-series. 

197 

198 Notes 

199 ----- 

200 This is simply convolution. If symmetric/anti-symmetric z-series are 

201 denoted by S/A then the following rules apply: 

202 

203 S*S, A*A -> S 

204 S*A, A*S -> A 

205 

206 """ 

207 return np.convolve(z1, z2) 

208 

209 

210def _zseries_div(z1, z2): 

211 """Divide the first z-series by the second. 

212 

213 Divide `z1` by `z2` and return the quotient and remainder as z-series. 

214 Warning: this implementation only applies when both z1 and z2 have the 

215 same symmetry, which is sufficient for present purposes. 

216 

217 Parameters 

218 ---------- 

219 z1, z2 : 1-D ndarray 

220 The arrays must be 1-D and have the same symmetry, but this is not 

221 checked. 

222 

223 Returns 

224 ------- 

225 

226 (quotient, remainder) : 1-D ndarrays 

227 Quotient and remainder as z-series. 

228 

229 Notes 

230 ----- 

231 This is not the same as polynomial division on account of the desired form 

232 of the remainder. If symmetric/anti-symmetric z-series are denoted by S/A 

233 then the following rules apply: 

234 

235 S/S -> S,S 

236 A/A -> S,A 

237 

238 The restriction to types of the same symmetry could be fixed but seems like 

239 unneeded generality. There is no natural form for the remainder in the case 

240 where there is no symmetry. 

241 

242 """ 

243 z1 = z1.copy() 

244 z2 = z2.copy() 

245 lc1 = len(z1) 

246 lc2 = len(z2) 

247 if lc2 == 1: 

248 z1 /= z2 

249 return z1, z1[:1]*0 

250 elif lc1 < lc2: 

251 return z1[:1]*0, z1 

252 else: 

253 dlen = lc1 - lc2 

254 scl = z2[0] 

255 z2 /= scl 

256 quo = np.empty(dlen + 1, dtype=z1.dtype) 

257 i = 0 

258 j = dlen 

259 while i < j: 

260 r = z1[i] 

261 quo[i] = z1[i] 

262 quo[dlen - i] = r 

263 tmp = r*z2 

264 z1[i:i+lc2] -= tmp 

265 z1[j:j+lc2] -= tmp 

266 i += 1 

267 j -= 1 

268 r = z1[i] 

269 quo[i] = r 

270 tmp = r*z2 

271 z1[i:i+lc2] -= tmp 

272 quo /= scl 

273 rem = z1[i+1:i-1+lc2].copy() 

274 return quo, rem 

275 

276 

277def _zseries_der(zs): 

278 """Differentiate a z-series. 

279 

280 The derivative is with respect to x, not z. This is achieved using the 

281 chain rule and the value of dx/dz given in the module notes. 

282 

283 Parameters 

284 ---------- 

285 zs : z-series 

286 The z-series to differentiate. 

287 

288 Returns 

289 ------- 

290 derivative : z-series 

291 The derivative 

292 

293 Notes 

294 ----- 

295 The zseries for x (ns) has been multiplied by two in order to avoid 

296 using floats that are incompatible with Decimal and likely other 

297 specialized scalar types. This scaling has been compensated by 

298 multiplying the value of zs by two also so that the two cancels in the 

299 division. 

300 

301 """ 

302 n = len(zs)//2 

303 ns = np.array([-1, 0, 1], dtype=zs.dtype) 

304 zs *= np.arange(-n, n+1)*2 

305 d, r = _zseries_div(zs, ns) 

306 return d 

307 

308 

309def _zseries_int(zs): 

310 """Integrate a z-series. 

311 

312 The integral is with respect to x, not z. This is achieved by a change 

313 of variable using dx/dz given in the module notes. 

314 

315 Parameters 

316 ---------- 

317 zs : z-series 

318 The z-series to integrate 

319 

320 Returns 

321 ------- 

322 integral : z-series 

323 The indefinite integral 

324 

325 Notes 

326 ----- 

327 The zseries for x (ns) has been multiplied by two in order to avoid 

328 using floats that are incompatible with Decimal and likely other 

329 specialized scalar types. This scaling has been compensated by 

330 dividing the resulting zs by two. 

331 

332 """ 

333 n = 1 + len(zs)//2 

334 ns = np.array([-1, 0, 1], dtype=zs.dtype) 

335 zs = _zseries_mul(zs, ns) 

336 div = np.arange(-n, n+1)*2 

337 zs[:n] /= div[:n] 

338 zs[n+1:] /= div[n+1:] 

339 zs[n] = 0 

340 return zs 

341 

342# 

343# Chebyshev series functions 

344# 

345 

346 

347def poly2cheb(pol): 

348 """ 

349 Convert a polynomial to a Chebyshev series. 

350 

351 Convert an array representing the coefficients of a polynomial (relative 

352 to the "standard" basis) ordered from lowest degree to highest, to an 

353 array of the coefficients of the equivalent Chebyshev series, ordered 

354 from lowest to highest degree. 

355 

356 Parameters 

357 ---------- 

358 pol : array_like 

359 1-D array containing the polynomial coefficients 

360 

361 Returns 

362 ------- 

363 c : ndarray 

364 1-D array containing the coefficients of the equivalent Chebyshev 

365 series. 

366 

367 See Also 

368 -------- 

369 cheb2poly 

370 

371 Notes 

372 ----- 

373 The easy way to do conversions between polynomial basis sets 

374 is to use the convert method of a class instance. 

375 

376 Examples 

377 -------- 

378 >>> from numpy import polynomial as P 

379 >>> p = P.Polynomial(range(4)) 

380 >>> p 

381 Polynomial([0., 1., 2., 3.], domain=[-1, 1], window=[-1, 1]) 

382 >>> c = p.convert(kind=P.Chebyshev) 

383 >>> c 

384 Chebyshev([1. , 3.25, 1. , 0.75], domain=[-1., 1.], window=[-1., 1.]) 

385 >>> P.chebyshev.poly2cheb(range(4)) 

386 array([1. , 3.25, 1. , 0.75]) 

387 

388 """ 

389 [pol] = pu.as_series([pol]) 

390 deg = len(pol) - 1 

391 res = 0 

392 for i in range(deg, -1, -1): 

393 res = chebadd(chebmulx(res), pol[i]) 

394 return res 

395 

396 

397def cheb2poly(c): 

398 """ 

399 Convert a Chebyshev series to a polynomial. 

400 

401 Convert an array representing the coefficients of a Chebyshev series, 

402 ordered from lowest degree to highest, to an array of the coefficients 

403 of the equivalent polynomial (relative to the "standard" basis) ordered 

404 from lowest to highest degree. 

405 

406 Parameters 

407 ---------- 

408 c : array_like 

409 1-D array containing the Chebyshev series coefficients, ordered 

410 from lowest order term to highest. 

411 

412 Returns 

413 ------- 

414 pol : ndarray 

415 1-D array containing the coefficients of the equivalent polynomial 

416 (relative to the "standard" basis) ordered from lowest order term 

417 to highest. 

418 

419 See Also 

420 -------- 

421 poly2cheb 

422 

423 Notes 

424 ----- 

425 The easy way to do conversions between polynomial basis sets 

426 is to use the convert method of a class instance. 

427 

428 Examples 

429 -------- 

430 >>> from numpy import polynomial as P 

431 >>> c = P.Chebyshev(range(4)) 

432 >>> c 

433 Chebyshev([0., 1., 2., 3.], domain=[-1, 1], window=[-1, 1]) 

434 >>> p = c.convert(kind=P.Polynomial) 

435 >>> p 

436 Polynomial([-2., -8., 4., 12.], domain=[-1., 1.], window=[-1., 1.]) 

437 >>> P.chebyshev.cheb2poly(range(4)) 

438 array([-2., -8., 4., 12.]) 

439 

440 """ 

441 from .polynomial import polyadd, polysub, polymulx 

442 

443 [c] = pu.as_series([c]) 

444 n = len(c) 

445 if n < 3: 

446 return c 

447 else: 

448 c0 = c[-2] 

449 c1 = c[-1] 

450 # i is the current degree of c1 

451 for i in range(n - 1, 1, -1): 

452 tmp = c0 

453 c0 = polysub(c[i - 2], c1) 

454 c1 = polyadd(tmp, polymulx(c1)*2) 

455 return polyadd(c0, polymulx(c1)) 

456 

457 

458# 

459# These are constant arrays are of integer type so as to be compatible 

460# with the widest range of other types, such as Decimal. 

461# 

462 

463# Chebyshev default domain. 

464chebdomain = np.array([-1, 1]) 

465 

466# Chebyshev coefficients representing zero. 

467chebzero = np.array([0]) 

468 

469# Chebyshev coefficients representing one. 

470chebone = np.array([1]) 

471 

472# Chebyshev coefficients representing the identity x. 

473chebx = np.array([0, 1]) 

474 

475 

476def chebline(off, scl): 

477 """ 

478 Chebyshev series whose graph is a straight line. 

479 

480 Parameters 

481 ---------- 

482 off, scl : scalars 

483 The specified line is given by ``off + scl*x``. 

484 

485 Returns 

486 ------- 

487 y : ndarray 

488 This module's representation of the Chebyshev series for 

489 ``off + scl*x``. 

490 

491 See Also 

492 -------- 

493 numpy.polynomial.polynomial.polyline 

494 numpy.polynomial.legendre.legline 

495 numpy.polynomial.laguerre.lagline 

496 numpy.polynomial.hermite.hermline 

497 numpy.polynomial.hermite_e.hermeline 

498 

499 Examples 

500 -------- 

501 >>> import numpy.polynomial.chebyshev as C 

502 >>> C.chebline(3,2) 

503 array([3, 2]) 

504 >>> C.chebval(-3, C.chebline(3,2)) # should be -3 

505 -3.0 

506 

507 """ 

508 if scl != 0: 

509 return np.array([off, scl]) 

510 else: 

511 return np.array([off]) 

512 

513 

514def chebfromroots(roots): 

515 """ 

516 Generate a Chebyshev series with given roots. 

517 

518 The function returns the coefficients of the polynomial 

519 

520 .. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n), 

521 

522 in Chebyshev form, where the `r_n` are the roots specified in `roots`. 

523 If a zero has multiplicity n, then it must appear in `roots` n times. 

524 For instance, if 2 is a root of multiplicity three and 3 is a root of 

525 multiplicity 2, then `roots` looks something like [2, 2, 2, 3, 3]. The 

526 roots can appear in any order. 

527 

528 If the returned coefficients are `c`, then 

529 

530 .. math:: p(x) = c_0 + c_1 * T_1(x) + ... + c_n * T_n(x) 

531 

532 The coefficient of the last term is not generally 1 for monic 

533 polynomials in Chebyshev form. 

534 

535 Parameters 

536 ---------- 

537 roots : array_like 

538 Sequence containing the roots. 

539 

540 Returns 

541 ------- 

542 out : ndarray 

543 1-D array of coefficients. If all roots are real then `out` is a 

544 real array, if some of the roots are complex, then `out` is complex 

545 even if all the coefficients in the result are real (see Examples 

546 below). 

547 

548 See Also 

549 -------- 

550 numpy.polynomial.polynomial.polyfromroots 

551 numpy.polynomial.legendre.legfromroots 

552 numpy.polynomial.laguerre.lagfromroots 

553 numpy.polynomial.hermite.hermfromroots 

554 numpy.polynomial.hermite_e.hermefromroots 

555 

556 Examples 

557 -------- 

558 >>> import numpy.polynomial.chebyshev as C 

559 >>> C.chebfromroots((-1,0,1)) # x^3 - x relative to the standard basis 

560 array([ 0. , -0.25, 0. , 0.25]) 

561 >>> j = complex(0,1) 

562 >>> C.chebfromroots((-j,j)) # x^2 + 1 relative to the standard basis 

563 array([1.5+0.j, 0. +0.j, 0.5+0.j]) 

564 

565 """ 

566 return pu._fromroots(chebline, chebmul, roots) 

567 

568 

569def chebadd(c1, c2): 

570 """ 

571 Add one Chebyshev series to another. 

572 

573 Returns the sum of two Chebyshev series `c1` + `c2`. The arguments 

574 are sequences of coefficients ordered from lowest order term to 

575 highest, i.e., [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``. 

576 

577 Parameters 

578 ---------- 

579 c1, c2 : array_like 

580 1-D arrays of Chebyshev series coefficients ordered from low to 

581 high. 

582 

583 Returns 

584 ------- 

585 out : ndarray 

586 Array representing the Chebyshev series of their sum. 

587 

588 See Also 

589 -------- 

590 chebsub, chebmulx, chebmul, chebdiv, chebpow 

591 

592 Notes 

593 ----- 

594 Unlike multiplication, division, etc., the sum of two Chebyshev series 

595 is a Chebyshev series (without having to "reproject" the result onto 

596 the basis set) so addition, just like that of "standard" polynomials, 

597 is simply "component-wise." 

598 

599 Examples 

600 -------- 

601 >>> from numpy.polynomial import chebyshev as C 

602 >>> c1 = (1,2,3) 

603 >>> c2 = (3,2,1) 

604 >>> C.chebadd(c1,c2) 

605 array([4., 4., 4.]) 

606 

607 """ 

608 return pu._add(c1, c2) 

609 

610 

611def chebsub(c1, c2): 

612 """ 

613 Subtract one Chebyshev series from another. 

614 

615 Returns the difference of two Chebyshev series `c1` - `c2`. The 

616 sequences of coefficients are from lowest order term to highest, i.e., 

617 [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``. 

618 

619 Parameters 

620 ---------- 

621 c1, c2 : array_like 

622 1-D arrays of Chebyshev series coefficients ordered from low to 

623 high. 

624 

625 Returns 

626 ------- 

627 out : ndarray 

628 Of Chebyshev series coefficients representing their difference. 

629 

630 See Also 

631 -------- 

632 chebadd, chebmulx, chebmul, chebdiv, chebpow 

633 

634 Notes 

635 ----- 

636 Unlike multiplication, division, etc., the difference of two Chebyshev 

637 series is a Chebyshev series (without having to "reproject" the result 

638 onto the basis set) so subtraction, just like that of "standard" 

639 polynomials, is simply "component-wise." 

640 

641 Examples 

642 -------- 

643 >>> from numpy.polynomial import chebyshev as C 

644 >>> c1 = (1,2,3) 

645 >>> c2 = (3,2,1) 

646 >>> C.chebsub(c1,c2) 

647 array([-2., 0., 2.]) 

648 >>> C.chebsub(c2,c1) # -C.chebsub(c1,c2) 

649 array([ 2., 0., -2.]) 

650 

651 """ 

652 return pu._sub(c1, c2) 

653 

654 

655def chebmulx(c): 

656 """Multiply a Chebyshev series by x. 

657 

658 Multiply the polynomial `c` by x, where x is the independent 

659 variable. 

660 

661 

662 Parameters 

663 ---------- 

664 c : array_like 

665 1-D array of Chebyshev series coefficients ordered from low to 

666 high. 

667 

668 Returns 

669 ------- 

670 out : ndarray 

671 Array representing the result of the multiplication. 

672 

673 Notes 

674 ----- 

675 

676 .. versionadded:: 1.5.0 

677 

678 Examples 

679 -------- 

680 >>> from numpy.polynomial import chebyshev as C 

681 >>> C.chebmulx([1,2,3]) 

682 array([1. , 2.5, 1. , 1.5]) 

683 

684 """ 

685 # c is a trimmed copy 

686 [c] = pu.as_series([c]) 

687 # The zero series needs special treatment 

688 if len(c) == 1 and c[0] == 0: 

689 return c 

690 

691 prd = np.empty(len(c) + 1, dtype=c.dtype) 

692 prd[0] = c[0]*0 

693 prd[1] = c[0] 

694 if len(c) > 1: 

695 tmp = c[1:]/2 

696 prd[2:] = tmp 

697 prd[0:-2] += tmp 

698 return prd 

699 

700 

701def chebmul(c1, c2): 

702 """ 

703 Multiply one Chebyshev series by another. 

704 

705 Returns the product of two Chebyshev series `c1` * `c2`. The arguments 

706 are sequences of coefficients, from lowest order "term" to highest, 

707 e.g., [1,2,3] represents the series ``T_0 + 2*T_1 + 3*T_2``. 

708 

709 Parameters 

710 ---------- 

711 c1, c2 : array_like 

712 1-D arrays of Chebyshev series coefficients ordered from low to 

713 high. 

714 

715 Returns 

716 ------- 

717 out : ndarray 

718 Of Chebyshev series coefficients representing their product. 

719 

720 See Also 

721 -------- 

722 chebadd, chebsub, chebmulx, chebdiv, chebpow 

723 

724 Notes 

725 ----- 

726 In general, the (polynomial) product of two C-series results in terms 

727 that are not in the Chebyshev polynomial basis set. Thus, to express 

728 the product as a C-series, it is typically necessary to "reproject" 

729 the product onto said basis set, which typically produces 

730 "unintuitive live" (but correct) results; see Examples section below. 

731 

732 Examples 

733 -------- 

734 >>> from numpy.polynomial import chebyshev as C 

735 >>> c1 = (1,2,3) 

736 >>> c2 = (3,2,1) 

737 >>> C.chebmul(c1,c2) # multiplication requires "reprojection" 

738 array([ 6.5, 12. , 12. , 4. , 1.5]) 

739 

740 """ 

741 # c1, c2 are trimmed copies 

742 [c1, c2] = pu.as_series([c1, c2]) 

743 z1 = _cseries_to_zseries(c1) 

744 z2 = _cseries_to_zseries(c2) 

745 prd = _zseries_mul(z1, z2) 

746 ret = _zseries_to_cseries(prd) 

747 return pu.trimseq(ret) 

748 

749 

750def chebdiv(c1, c2): 

751 """ 

752 Divide one Chebyshev series by another. 

753 

754 Returns the quotient-with-remainder of two Chebyshev series 

755 `c1` / `c2`. The arguments are sequences of coefficients from lowest 

756 order "term" to highest, e.g., [1,2,3] represents the series 

757 ``T_0 + 2*T_1 + 3*T_2``. 

758 

759 Parameters 

760 ---------- 

761 c1, c2 : array_like 

762 1-D arrays of Chebyshev series coefficients ordered from low to 

763 high. 

764 

765 Returns 

766 ------- 

767 [quo, rem] : ndarrays 

768 Of Chebyshev series coefficients representing the quotient and 

769 remainder. 

770 

771 See Also 

772 -------- 

773 chebadd, chebsub, chebmulx, chebmul, chebpow 

774 

775 Notes 

776 ----- 

777 In general, the (polynomial) division of one C-series by another 

778 results in quotient and remainder terms that are not in the Chebyshev 

779 polynomial basis set. Thus, to express these results as C-series, it 

780 is typically necessary to "reproject" the results onto said basis 

781 set, which typically produces "unintuitive" (but correct) results; 

782 see Examples section below. 

783 

784 Examples 

785 -------- 

786 >>> from numpy.polynomial import chebyshev as C 

787 >>> c1 = (1,2,3) 

788 >>> c2 = (3,2,1) 

789 >>> C.chebdiv(c1,c2) # quotient "intuitive," remainder not 

790 (array([3.]), array([-8., -4.])) 

791 >>> c2 = (0,1,2,3) 

792 >>> C.chebdiv(c2,c1) # neither "intuitive" 

793 (array([0., 2.]), array([-2., -4.])) 

794 

795 """ 

796 # c1, c2 are trimmed copies 

797 [c1, c2] = pu.as_series([c1, c2]) 

798 if c2[-1] == 0: 

799 raise ZeroDivisionError() 

800 

801 # note: this is more efficient than `pu._div(chebmul, c1, c2)` 

802 lc1 = len(c1) 

803 lc2 = len(c2) 

804 if lc1 < lc2: 

805 return c1[:1]*0, c1 

806 elif lc2 == 1: 

807 return c1/c2[-1], c1[:1]*0 

808 else: 

809 z1 = _cseries_to_zseries(c1) 

810 z2 = _cseries_to_zseries(c2) 

811 quo, rem = _zseries_div(z1, z2) 

812 quo = pu.trimseq(_zseries_to_cseries(quo)) 

813 rem = pu.trimseq(_zseries_to_cseries(rem)) 

814 return quo, rem 

815 

816 

817def chebpow(c, pow, maxpower=16): 

818 """Raise a Chebyshev series to a power. 

819 

820 Returns the Chebyshev series `c` raised to the power `pow`. The 

821 argument `c` is a sequence of coefficients ordered from low to high. 

822 i.e., [1,2,3] is the series ``T_0 + 2*T_1 + 3*T_2.`` 

823 

824 Parameters 

825 ---------- 

826 c : array_like 

827 1-D array of Chebyshev series coefficients ordered from low to 

828 high. 

829 pow : integer 

830 Power to which the series will be raised 

831 maxpower : integer, optional 

832 Maximum power allowed. This is mainly to limit growth of the series 

833 to unmanageable size. Default is 16 

834 

835 Returns 

836 ------- 

837 coef : ndarray 

838 Chebyshev series of power. 

839 

840 See Also 

841 -------- 

842 chebadd, chebsub, chebmulx, chebmul, chebdiv 

843 

844 Examples 

845 -------- 

846 >>> from numpy.polynomial import chebyshev as C 

847 >>> C.chebpow([1, 2, 3, 4], 2) 

848 array([15.5, 22. , 16. , ..., 12.5, 12. , 8. ]) 

849 

850 """ 

851 # note: this is more efficient than `pu._pow(chebmul, c1, c2)`, as it 

852 # avoids converting between z and c series repeatedly 

853 

854 # c is a trimmed copy 

855 [c] = pu.as_series([c]) 

856 power = int(pow) 

857 if power != pow or power < 0: 

858 raise ValueError("Power must be a non-negative integer.") 

859 elif maxpower is not None and power > maxpower: 

860 raise ValueError("Power is too large") 

861 elif power == 0: 

862 return np.array([1], dtype=c.dtype) 

863 elif power == 1: 

864 return c 

865 else: 

866 # This can be made more efficient by using powers of two 

867 # in the usual way. 

868 zs = _cseries_to_zseries(c) 

869 prd = zs 

870 for i in range(2, power + 1): 

871 prd = np.convolve(prd, zs) 

872 return _zseries_to_cseries(prd) 

873 

874 

875def chebder(c, m=1, scl=1, axis=0): 

876 """ 

877 Differentiate a Chebyshev series. 

878 

879 Returns the Chebyshev series coefficients `c` differentiated `m` times 

880 along `axis`. At each iteration the result is multiplied by `scl` (the 

881 scaling factor is for use in a linear change of variable). The argument 

882 `c` is an array of coefficients from low to high degree along each 

883 axis, e.g., [1,2,3] represents the series ``1*T_0 + 2*T_1 + 3*T_2`` 

884 while [[1,2],[1,2]] represents ``1*T_0(x)*T_0(y) + 1*T_1(x)*T_0(y) + 

885 2*T_0(x)*T_1(y) + 2*T_1(x)*T_1(y)`` if axis=0 is ``x`` and axis=1 is 

886 ``y``. 

887 

888 Parameters 

889 ---------- 

890 c : array_like 

891 Array of Chebyshev series coefficients. If c is multidimensional 

892 the different axis correspond to different variables with the 

893 degree in each axis given by the corresponding index. 

894 m : int, optional 

895 Number of derivatives taken, must be non-negative. (Default: 1) 

896 scl : scalar, optional 

897 Each differentiation is multiplied by `scl`. The end result is 

898 multiplication by ``scl**m``. This is for use in a linear change of 

899 variable. (Default: 1) 

900 axis : int, optional 

901 Axis over which the derivative is taken. (Default: 0). 

902 

903 .. versionadded:: 1.7.0 

904 

905 Returns 

906 ------- 

907 der : ndarray 

908 Chebyshev series of the derivative. 

909 

910 See Also 

911 -------- 

912 chebint 

913 

914 Notes 

915 ----- 

916 In general, the result of differentiating a C-series needs to be 

917 "reprojected" onto the C-series basis set. Thus, typically, the 

918 result of this function is "unintuitive," albeit correct; see Examples 

919 section below. 

920 

921 Examples 

922 -------- 

923 >>> from numpy.polynomial import chebyshev as C 

924 >>> c = (1,2,3,4) 

925 >>> C.chebder(c) 

926 array([14., 12., 24.]) 

927 >>> C.chebder(c,3) 

928 array([96.]) 

929 >>> C.chebder(c,scl=-1) 

930 array([-14., -12., -24.]) 

931 >>> C.chebder(c,2,-1) 

932 array([12., 96.]) 

933 

934 """ 

935 c = np.array(c, ndmin=1, copy=True) 

936 if c.dtype.char in '?bBhHiIlLqQpP': 

937 c = c.astype(np.double) 

938 cnt = pu._deprecate_as_int(m, "the order of derivation") 

939 iaxis = pu._deprecate_as_int(axis, "the axis") 

940 if cnt < 0: 

941 raise ValueError("The order of derivation must be non-negative") 

942 iaxis = normalize_axis_index(iaxis, c.ndim) 

943 

944 if cnt == 0: 

945 return c 

946 

947 c = np.moveaxis(c, iaxis, 0) 

948 n = len(c) 

949 if cnt >= n: 

950 c = c[:1]*0 

951 else: 

952 for i in range(cnt): 

953 n = n - 1 

954 c *= scl 

955 der = np.empty((n,) + c.shape[1:], dtype=c.dtype) 

956 for j in range(n, 2, -1): 

957 der[j - 1] = (2*j)*c[j] 

958 c[j - 2] += (j*c[j])/(j - 2) 

959 if n > 1: 

960 der[1] = 4*c[2] 

961 der[0] = c[1] 

962 c = der 

963 c = np.moveaxis(c, 0, iaxis) 

964 return c 

965 

966 

967def chebint(c, m=1, k=[], lbnd=0, scl=1, axis=0): 

968 """ 

969 Integrate a Chebyshev series. 

970 

971 Returns the Chebyshev series coefficients `c` integrated `m` times from 

972 `lbnd` along `axis`. At each iteration the resulting series is 

973 **multiplied** by `scl` and an integration constant, `k`, is added. 

974 The scaling factor is for use in a linear change of variable. ("Buyer 

975 beware": note that, depending on what one is doing, one may want `scl` 

976 to be the reciprocal of what one might expect; for more information, 

977 see the Notes section below.) The argument `c` is an array of 

978 coefficients from low to high degree along each axis, e.g., [1,2,3] 

979 represents the series ``T_0 + 2*T_1 + 3*T_2`` while [[1,2],[1,2]] 

980 represents ``1*T_0(x)*T_0(y) + 1*T_1(x)*T_0(y) + 2*T_0(x)*T_1(y) + 

981 2*T_1(x)*T_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``. 

982 

983 Parameters 

984 ---------- 

985 c : array_like 

986 Array of Chebyshev series coefficients. If c is multidimensional 

987 the different axis correspond to different variables with the 

988 degree in each axis given by the corresponding index. 

989 m : int, optional 

990 Order of integration, must be positive. (Default: 1) 

991 k : {[], list, scalar}, optional 

992 Integration constant(s). The value of the first integral at zero 

993 is the first value in the list, the value of the second integral 

994 at zero is the second value, etc. If ``k == []`` (the default), 

995 all constants are set to zero. If ``m == 1``, a single scalar can 

996 be given instead of a list. 

997 lbnd : scalar, optional 

998 The lower bound of the integral. (Default: 0) 

999 scl : scalar, optional 

1000 Following each integration the result is *multiplied* by `scl` 

1001 before the integration constant is added. (Default: 1) 

1002 axis : int, optional 

1003 Axis over which the integral is taken. (Default: 0). 

1004 

1005 .. versionadded:: 1.7.0 

1006 

1007 Returns 

1008 ------- 

1009 S : ndarray 

1010 C-series coefficients of the integral. 

1011 

1012 Raises 

1013 ------ 

1014 ValueError 

1015 If ``m < 1``, ``len(k) > m``, ``np.ndim(lbnd) != 0``, or 

1016 ``np.ndim(scl) != 0``. 

1017 

1018 See Also 

1019 -------- 

1020 chebder 

1021 

1022 Notes 

1023 ----- 

1024 Note that the result of each integration is *multiplied* by `scl`. 

1025 Why is this important to note? Say one is making a linear change of 

1026 variable :math:`u = ax + b` in an integral relative to `x`. Then 

1027 :math:`dx = du/a`, so one will need to set `scl` equal to 

1028 :math:`1/a`- perhaps not what one would have first thought. 

1029 

1030 Also note that, in general, the result of integrating a C-series needs 

1031 to be "reprojected" onto the C-series basis set. Thus, typically, 

1032 the result of this function is "unintuitive," albeit correct; see 

1033 Examples section below. 

1034 

1035 Examples 

1036 -------- 

1037 >>> from numpy.polynomial import chebyshev as C 

1038 >>> c = (1,2,3) 

1039 >>> C.chebint(c) 

1040 array([ 0.5, -0.5, 0.5, 0.5]) 

1041 >>> C.chebint(c,3) 

1042 array([ 0.03125 , -0.1875 , 0.04166667, -0.05208333, 0.01041667, # may vary 

1043 0.00625 ]) 

1044 >>> C.chebint(c, k=3) 

1045 array([ 3.5, -0.5, 0.5, 0.5]) 

1046 >>> C.chebint(c,lbnd=-2) 

1047 array([ 8.5, -0.5, 0.5, 0.5]) 

1048 >>> C.chebint(c,scl=-2) 

1049 array([-1., 1., -1., -1.]) 

1050 

1051 """ 

1052 c = np.array(c, ndmin=1, copy=True) 

1053 if c.dtype.char in '?bBhHiIlLqQpP': 

1054 c = c.astype(np.double) 

1055 if not np.iterable(k): 

1056 k = [k] 

1057 cnt = pu._deprecate_as_int(m, "the order of integration") 

1058 iaxis = pu._deprecate_as_int(axis, "the axis") 

1059 if cnt < 0: 

1060 raise ValueError("The order of integration must be non-negative") 

1061 if len(k) > cnt: 

1062 raise ValueError("Too many integration constants") 

1063 if np.ndim(lbnd) != 0: 

1064 raise ValueError("lbnd must be a scalar.") 

1065 if np.ndim(scl) != 0: 

1066 raise ValueError("scl must be a scalar.") 

1067 iaxis = normalize_axis_index(iaxis, c.ndim) 

1068 

1069 if cnt == 0: 

1070 return c 

1071 

1072 c = np.moveaxis(c, iaxis, 0) 

1073 k = list(k) + [0]*(cnt - len(k)) 

1074 for i in range(cnt): 

1075 n = len(c) 

1076 c *= scl 

1077 if n == 1 and np.all(c[0] == 0): 

1078 c[0] += k[i] 

1079 else: 

1080 tmp = np.empty((n + 1,) + c.shape[1:], dtype=c.dtype) 

1081 tmp[0] = c[0]*0 

1082 tmp[1] = c[0] 

1083 if n > 1: 

1084 tmp[2] = c[1]/4 

1085 for j in range(2, n): 

1086 tmp[j + 1] = c[j]/(2*(j + 1)) 

1087 tmp[j - 1] -= c[j]/(2*(j - 1)) 

1088 tmp[0] += k[i] - chebval(lbnd, tmp) 

1089 c = tmp 

1090 c = np.moveaxis(c, 0, iaxis) 

1091 return c 

1092 

1093 

1094def chebval(x, c, tensor=True): 

1095 """ 

1096 Evaluate a Chebyshev series at points x. 

1097 

1098 If `c` is of length `n + 1`, this function returns the value: 

1099 

1100 .. math:: p(x) = c_0 * T_0(x) + c_1 * T_1(x) + ... + c_n * T_n(x) 

1101 

1102 The parameter `x` is converted to an array only if it is a tuple or a 

1103 list, otherwise it is treated as a scalar. In either case, either `x` 

1104 or its elements must support multiplication and addition both with 

1105 themselves and with the elements of `c`. 

1106 

1107 If `c` is a 1-D array, then `p(x)` will have the same shape as `x`. If 

1108 `c` is multidimensional, then the shape of the result depends on the 

1109 value of `tensor`. If `tensor` is true the shape will be c.shape[1:] + 

1110 x.shape. If `tensor` is false the shape will be c.shape[1:]. Note that 

1111 scalars have shape (,). 

1112 

1113 Trailing zeros in the coefficients will be used in the evaluation, so 

1114 they should be avoided if efficiency is a concern. 

1115 

1116 Parameters 

1117 ---------- 

1118 x : array_like, compatible object 

1119 If `x` is a list or tuple, it is converted to an ndarray, otherwise 

1120 it is left unchanged and treated as a scalar. In either case, `x` 

1121 or its elements must support addition and multiplication with 

1122 themselves and with the elements of `c`. 

1123 c : array_like 

1124 Array of coefficients ordered so that the coefficients for terms of 

1125 degree n are contained in c[n]. If `c` is multidimensional the 

1126 remaining indices enumerate multiple polynomials. In the two 

1127 dimensional case the coefficients may be thought of as stored in 

1128 the columns of `c`. 

1129 tensor : boolean, optional 

1130 If True, the shape of the coefficient array is extended with ones 

1131 on the right, one for each dimension of `x`. Scalars have dimension 0 

1132 for this action. The result is that every column of coefficients in 

1133 `c` is evaluated for every element of `x`. If False, `x` is broadcast 

1134 over the columns of `c` for the evaluation. This keyword is useful 

1135 when `c` is multidimensional. The default value is True. 

1136 

1137 .. versionadded:: 1.7.0 

1138 

1139 Returns 

1140 ------- 

1141 values : ndarray, algebra_like 

1142 The shape of the return value is described above. 

1143 

1144 See Also 

1145 -------- 

1146 chebval2d, chebgrid2d, chebval3d, chebgrid3d 

1147 

1148 Notes 

1149 ----- 

1150 The evaluation uses Clenshaw recursion, aka synthetic division. 

1151 

1152 """ 

1153 c = np.array(c, ndmin=1, copy=True) 

1154 if c.dtype.char in '?bBhHiIlLqQpP': 

1155 c = c.astype(np.double) 

1156 if isinstance(x, (tuple, list)): 

1157 x = np.asarray(x) 

1158 if isinstance(x, np.ndarray) and tensor: 

1159 c = c.reshape(c.shape + (1,)*x.ndim) 

1160 

1161 if len(c) == 1: 

1162 c0 = c[0] 

1163 c1 = 0 

1164 elif len(c) == 2: 

1165 c0 = c[0] 

1166 c1 = c[1] 

1167 else: 

1168 x2 = 2*x 

1169 c0 = c[-2] 

1170 c1 = c[-1] 

1171 for i in range(3, len(c) + 1): 

1172 tmp = c0 

1173 c0 = c[-i] - c1 

1174 c1 = tmp + c1*x2 

1175 return c0 + c1*x 

1176 

1177 

1178def chebval2d(x, y, c): 

1179 """ 

1180 Evaluate a 2-D Chebyshev series at points (x, y). 

1181 

1182 This function returns the values: 

1183 

1184 .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * T_i(x) * T_j(y) 

1185 

1186 The parameters `x` and `y` are converted to arrays only if they are 

1187 tuples or a lists, otherwise they are treated as a scalars and they 

1188 must have the same shape after conversion. In either case, either `x` 

1189 and `y` or their elements must support multiplication and addition both 

1190 with themselves and with the elements of `c`. 

1191 

1192 If `c` is a 1-D array a one is implicitly appended to its shape to make 

1193 it 2-D. The shape of the result will be c.shape[2:] + x.shape. 

1194 

1195 Parameters 

1196 ---------- 

1197 x, y : array_like, compatible objects 

1198 The two dimensional series is evaluated at the points `(x, y)`, 

1199 where `x` and `y` must have the same shape. If `x` or `y` is a list 

1200 or tuple, it is first converted to an ndarray, otherwise it is left 

1201 unchanged and if it isn't an ndarray it is treated as a scalar. 

1202 c : array_like 

1203 Array of coefficients ordered so that the coefficient of the term 

1204 of multi-degree i,j is contained in ``c[i,j]``. If `c` has 

1205 dimension greater than 2 the remaining indices enumerate multiple 

1206 sets of coefficients. 

1207 

1208 Returns 

1209 ------- 

1210 values : ndarray, compatible object 

1211 The values of the two dimensional Chebyshev series at points formed 

1212 from pairs of corresponding values from `x` and `y`. 

1213 

1214 See Also 

1215 -------- 

1216 chebval, chebgrid2d, chebval3d, chebgrid3d 

1217 

1218 Notes 

1219 ----- 

1220 

1221 .. versionadded:: 1.7.0 

1222 

1223 """ 

1224 return pu._valnd(chebval, c, x, y) 

1225 

1226 

1227def chebgrid2d(x, y, c): 

1228 """ 

1229 Evaluate a 2-D Chebyshev series on the Cartesian product of x and y. 

1230 

1231 This function returns the values: 

1232 

1233 .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * T_i(a) * T_j(b), 

1234 

1235 where the points `(a, b)` consist of all pairs formed by taking 

1236 `a` from `x` and `b` from `y`. The resulting points form a grid with 

1237 `x` in the first dimension and `y` in the second. 

1238 

1239 The parameters `x` and `y` are converted to arrays only if they are 

1240 tuples or a lists, otherwise they are treated as a scalars. In either 

1241 case, either `x` and `y` or their elements must support multiplication 

1242 and addition both with themselves and with the elements of `c`. 

1243 

1244 If `c` has fewer than two dimensions, ones are implicitly appended to 

1245 its shape to make it 2-D. The shape of the result will be c.shape[2:] + 

1246 x.shape + y.shape. 

1247 

1248 Parameters 

1249 ---------- 

1250 x, y : array_like, compatible objects 

1251 The two dimensional series is evaluated at the points in the 

1252 Cartesian product of `x` and `y`. If `x` or `y` is a list or 

1253 tuple, it is first converted to an ndarray, otherwise it is left 

1254 unchanged and, if it isn't an ndarray, it is treated as a scalar. 

1255 c : array_like 

1256 Array of coefficients ordered so that the coefficient of the term of 

1257 multi-degree i,j is contained in `c[i,j]`. If `c` has dimension 

1258 greater than two the remaining indices enumerate multiple sets of 

1259 coefficients. 

1260 

1261 Returns 

1262 ------- 

1263 values : ndarray, compatible object 

1264 The values of the two dimensional Chebyshev series at points in the 

1265 Cartesian product of `x` and `y`. 

1266 

1267 See Also 

1268 -------- 

1269 chebval, chebval2d, chebval3d, chebgrid3d 

1270 

1271 Notes 

1272 ----- 

1273 

1274 .. versionadded:: 1.7.0 

1275 

1276 """ 

1277 return pu._gridnd(chebval, c, x, y) 

1278 

1279 

1280def chebval3d(x, y, z, c): 

1281 """ 

1282 Evaluate a 3-D Chebyshev series at points (x, y, z). 

1283 

1284 This function returns the values: 

1285 

1286 .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * T_i(x) * T_j(y) * T_k(z) 

1287 

1288 The parameters `x`, `y`, and `z` are converted to arrays only if 

1289 they are tuples or a lists, otherwise they are treated as a scalars and 

1290 they must have the same shape after conversion. In either case, either 

1291 `x`, `y`, and `z` or their elements must support multiplication and 

1292 addition both with themselves and with the elements of `c`. 

1293 

1294 If `c` has fewer than 3 dimensions, ones are implicitly appended to its 

1295 shape to make it 3-D. The shape of the result will be c.shape[3:] + 

1296 x.shape. 

1297 

1298 Parameters 

1299 ---------- 

1300 x, y, z : array_like, compatible object 

1301 The three dimensional series is evaluated at the points 

1302 `(x, y, z)`, where `x`, `y`, and `z` must have the same shape. If 

1303 any of `x`, `y`, or `z` is a list or tuple, it is first converted 

1304 to an ndarray, otherwise it is left unchanged and if it isn't an 

1305 ndarray it is treated as a scalar. 

1306 c : array_like 

1307 Array of coefficients ordered so that the coefficient of the term of 

1308 multi-degree i,j,k is contained in ``c[i,j,k]``. If `c` has dimension 

1309 greater than 3 the remaining indices enumerate multiple sets of 

1310 coefficients. 

1311 

1312 Returns 

1313 ------- 

1314 values : ndarray, compatible object 

1315 The values of the multidimensional polynomial on points formed with 

1316 triples of corresponding values from `x`, `y`, and `z`. 

1317 

1318 See Also 

1319 -------- 

1320 chebval, chebval2d, chebgrid2d, chebgrid3d 

1321 

1322 Notes 

1323 ----- 

1324 

1325 .. versionadded:: 1.7.0 

1326 

1327 """ 

1328 return pu._valnd(chebval, c, x, y, z) 

1329 

1330 

1331def chebgrid3d(x, y, z, c): 

1332 """ 

1333 Evaluate a 3-D Chebyshev series on the Cartesian product of x, y, and z. 

1334 

1335 This function returns the values: 

1336 

1337 .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * T_i(a) * T_j(b) * T_k(c) 

1338 

1339 where the points `(a, b, c)` consist of all triples formed by taking 

1340 `a` from `x`, `b` from `y`, and `c` from `z`. The resulting points form 

1341 a grid with `x` in the first dimension, `y` in the second, and `z` in 

1342 the third. 

1343 

1344 The parameters `x`, `y`, and `z` are converted to arrays only if they 

1345 are tuples or a lists, otherwise they are treated as a scalars. In 

1346 either case, either `x`, `y`, and `z` or their elements must support 

1347 multiplication and addition both with themselves and with the elements 

1348 of `c`. 

1349 

1350 If `c` has fewer than three dimensions, ones are implicitly appended to 

1351 its shape to make it 3-D. The shape of the result will be c.shape[3:] + 

1352 x.shape + y.shape + z.shape. 

1353 

1354 Parameters 

1355 ---------- 

1356 x, y, z : array_like, compatible objects 

1357 The three dimensional series is evaluated at the points in the 

1358 Cartesian product of `x`, `y`, and `z`. If `x`,`y`, or `z` is a 

1359 list or tuple, it is first converted to an ndarray, otherwise it is 

1360 left unchanged and, if it isn't an ndarray, it is treated as a 

1361 scalar. 

1362 c : array_like 

1363 Array of coefficients ordered so that the coefficients for terms of 

1364 degree i,j are contained in ``c[i,j]``. If `c` has dimension 

1365 greater than two the remaining indices enumerate multiple sets of 

1366 coefficients. 

1367 

1368 Returns 

1369 ------- 

1370 values : ndarray, compatible object 

1371 The values of the two dimensional polynomial at points in the Cartesian 

1372 product of `x` and `y`. 

1373 

1374 See Also 

1375 -------- 

1376 chebval, chebval2d, chebgrid2d, chebval3d 

1377 

1378 Notes 

1379 ----- 

1380 

1381 .. versionadded:: 1.7.0 

1382 

1383 """ 

1384 return pu._gridnd(chebval, c, x, y, z) 

1385 

1386 

1387def chebvander(x, deg): 

1388 """Pseudo-Vandermonde matrix of given degree. 

1389 

1390 Returns the pseudo-Vandermonde matrix of degree `deg` and sample points 

1391 `x`. The pseudo-Vandermonde matrix is defined by 

1392 

1393 .. math:: V[..., i] = T_i(x), 

1394 

1395 where `0 <= i <= deg`. The leading indices of `V` index the elements of 

1396 `x` and the last index is the degree of the Chebyshev polynomial. 

1397 

1398 If `c` is a 1-D array of coefficients of length `n + 1` and `V` is the 

1399 matrix ``V = chebvander(x, n)``, then ``np.dot(V, c)`` and 

1400 ``chebval(x, c)`` are the same up to roundoff. This equivalence is 

1401 useful both for least squares fitting and for the evaluation of a large 

1402 number of Chebyshev series of the same degree and sample points. 

1403 

1404 Parameters 

1405 ---------- 

1406 x : array_like 

1407 Array of points. The dtype is converted to float64 or complex128 

1408 depending on whether any of the elements are complex. If `x` is 

1409 scalar it is converted to a 1-D array. 

1410 deg : int 

1411 Degree of the resulting matrix. 

1412 

1413 Returns 

1414 ------- 

1415 vander : ndarray 

1416 The pseudo Vandermonde matrix. The shape of the returned matrix is 

1417 ``x.shape + (deg + 1,)``, where The last index is the degree of the 

1418 corresponding Chebyshev polynomial. The dtype will be the same as 

1419 the converted `x`. 

1420 

1421 """ 

1422 ideg = pu._deprecate_as_int(deg, "deg") 

1423 if ideg < 0: 

1424 raise ValueError("deg must be non-negative") 

1425 

1426 x = np.array(x, copy=False, ndmin=1) + 0.0 

1427 dims = (ideg + 1,) + x.shape 

1428 dtyp = x.dtype 

1429 v = np.empty(dims, dtype=dtyp) 

1430 # Use forward recursion to generate the entries. 

1431 v[0] = x*0 + 1 

1432 if ideg > 0: 

1433 x2 = 2*x 

1434 v[1] = x 

1435 for i in range(2, ideg + 1): 

1436 v[i] = v[i-1]*x2 - v[i-2] 

1437 return np.moveaxis(v, 0, -1) 

1438 

1439 

1440def chebvander2d(x, y, deg): 

1441 """Pseudo-Vandermonde matrix of given degrees. 

1442 

1443 Returns the pseudo-Vandermonde matrix of degrees `deg` and sample 

1444 points `(x, y)`. The pseudo-Vandermonde matrix is defined by 

1445 

1446 .. math:: V[..., (deg[1] + 1)*i + j] = T_i(x) * T_j(y), 

1447 

1448 where `0 <= i <= deg[0]` and `0 <= j <= deg[1]`. The leading indices of 

1449 `V` index the points `(x, y)` and the last index encodes the degrees of 

1450 the Chebyshev polynomials. 

1451 

1452 If ``V = chebvander2d(x, y, [xdeg, ydeg])``, then the columns of `V` 

1453 correspond to the elements of a 2-D coefficient array `c` of shape 

1454 (xdeg + 1, ydeg + 1) in the order 

1455 

1456 .. math:: c_{00}, c_{01}, c_{02} ... , c_{10}, c_{11}, c_{12} ... 

1457 

1458 and ``np.dot(V, c.flat)`` and ``chebval2d(x, y, c)`` will be the same 

1459 up to roundoff. This equivalence is useful both for least squares 

1460 fitting and for the evaluation of a large number of 2-D Chebyshev 

1461 series of the same degrees and sample points. 

1462 

1463 Parameters 

1464 ---------- 

1465 x, y : array_like 

1466 Arrays of point coordinates, all of the same shape. The dtypes 

1467 will be converted to either float64 or complex128 depending on 

1468 whether any of the elements are complex. Scalars are converted to 

1469 1-D arrays. 

1470 deg : list of ints 

1471 List of maximum degrees of the form [x_deg, y_deg]. 

1472 

1473 Returns 

1474 ------- 

1475 vander2d : ndarray 

1476 The shape of the returned matrix is ``x.shape + (order,)``, where 

1477 :math:`order = (deg[0]+1)*(deg[1]+1)`. The dtype will be the same 

1478 as the converted `x` and `y`. 

1479 

1480 See Also 

1481 -------- 

1482 chebvander, chebvander3d, chebval2d, chebval3d 

1483 

1484 Notes 

1485 ----- 

1486 

1487 .. versionadded:: 1.7.0 

1488 

1489 """ 

1490 return pu._vander_nd_flat((chebvander, chebvander), (x, y), deg) 

1491 

1492 

1493def chebvander3d(x, y, z, deg): 

1494 """Pseudo-Vandermonde matrix of given degrees. 

1495 

1496 Returns the pseudo-Vandermonde matrix of degrees `deg` and sample 

1497 points `(x, y, z)`. If `l, m, n` are the given degrees in `x, y, z`, 

1498 then The pseudo-Vandermonde matrix is defined by 

1499 

1500 .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = T_i(x)*T_j(y)*T_k(z), 

1501 

1502 where `0 <= i <= l`, `0 <= j <= m`, and `0 <= j <= n`. The leading 

1503 indices of `V` index the points `(x, y, z)` and the last index encodes 

1504 the degrees of the Chebyshev polynomials. 

1505 

1506 If ``V = chebvander3d(x, y, z, [xdeg, ydeg, zdeg])``, then the columns 

1507 of `V` correspond to the elements of a 3-D coefficient array `c` of 

1508 shape (xdeg + 1, ydeg + 1, zdeg + 1) in the order 

1509 

1510 .. math:: c_{000}, c_{001}, c_{002},... , c_{010}, c_{011}, c_{012},... 

1511 

1512 and ``np.dot(V, c.flat)`` and ``chebval3d(x, y, z, c)`` will be the 

1513 same up to roundoff. This equivalence is useful both for least squares 

1514 fitting and for the evaluation of a large number of 3-D Chebyshev 

1515 series of the same degrees and sample points. 

1516 

1517 Parameters 

1518 ---------- 

1519 x, y, z : array_like 

1520 Arrays of point coordinates, all of the same shape. The dtypes will 

1521 be converted to either float64 or complex128 depending on whether 

1522 any of the elements are complex. Scalars are converted to 1-D 

1523 arrays. 

1524 deg : list of ints 

1525 List of maximum degrees of the form [x_deg, y_deg, z_deg]. 

1526 

1527 Returns 

1528 ------- 

1529 vander3d : ndarray 

1530 The shape of the returned matrix is ``x.shape + (order,)``, where 

1531 :math:`order = (deg[0]+1)*(deg[1]+1)*(deg[2]+1)`. The dtype will 

1532 be the same as the converted `x`, `y`, and `z`. 

1533 

1534 See Also 

1535 -------- 

1536 chebvander, chebvander3d, chebval2d, chebval3d 

1537 

1538 Notes 

1539 ----- 

1540 

1541 .. versionadded:: 1.7.0 

1542 

1543 """ 

1544 return pu._vander_nd_flat((chebvander, chebvander, chebvander), (x, y, z), deg) 

1545 

1546 

1547def chebfit(x, y, deg, rcond=None, full=False, w=None): 

1548 """ 

1549 Least squares fit of Chebyshev series to data. 

1550 

1551 Return the coefficients of a Chebyshev series of degree `deg` that is the 

1552 least squares fit to the data values `y` given at points `x`. If `y` is 

1553 1-D the returned coefficients will also be 1-D. If `y` is 2-D multiple 

1554 fits are done, one for each column of `y`, and the resulting 

1555 coefficients are stored in the corresponding columns of a 2-D return. 

1556 The fitted polynomial(s) are in the form 

1557 

1558 .. math:: p(x) = c_0 + c_1 * T_1(x) + ... + c_n * T_n(x), 

1559 

1560 where `n` is `deg`. 

1561 

1562 Parameters 

1563 ---------- 

1564 x : array_like, shape (M,) 

1565 x-coordinates of the M sample points ``(x[i], y[i])``. 

1566 y : array_like, shape (M,) or (M, K) 

1567 y-coordinates of the sample points. Several data sets of sample 

1568 points sharing the same x-coordinates can be fitted at once by 

1569 passing in a 2D-array that contains one dataset per column. 

1570 deg : int or 1-D array_like 

1571 Degree(s) of the fitting polynomials. If `deg` is a single integer, 

1572 all terms up to and including the `deg`'th term are included in the 

1573 fit. For NumPy versions >= 1.11.0 a list of integers specifying the 

1574 degrees of the terms to include may be used instead. 

1575 rcond : float, optional 

1576 Relative condition number of the fit. Singular values smaller than 

1577 this relative to the largest singular value will be ignored. The 

1578 default value is len(x)*eps, where eps is the relative precision of 

1579 the float type, about 2e-16 in most cases. 

1580 full : bool, optional 

1581 Switch determining nature of return value. When it is False (the 

1582 default) just the coefficients are returned, when True diagnostic 

1583 information from the singular value decomposition is also returned. 

1584 w : array_like, shape (`M`,), optional 

1585 Weights. If not None, the weight ``w[i]`` applies to the unsquared 

1586 residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are 

1587 chosen so that the errors of the products ``w[i]*y[i]`` all have the 

1588 same variance. When using inverse-variance weighting, use 

1589 ``w[i] = 1/sigma(y[i])``. The default value is None. 

1590 

1591 .. versionadded:: 1.5.0 

1592 

1593 Returns 

1594 ------- 

1595 coef : ndarray, shape (M,) or (M, K) 

1596 Chebyshev coefficients ordered from low to high. If `y` was 2-D, 

1597 the coefficients for the data in column k of `y` are in column 

1598 `k`. 

1599 

1600 [residuals, rank, singular_values, rcond] : list 

1601 These values are only returned if ``full == True`` 

1602 

1603 - residuals -- sum of squared residuals of the least squares fit 

1604 - rank -- the numerical rank of the scaled Vandermonde matrix 

1605 - singular_values -- singular values of the scaled Vandermonde matrix 

1606 - rcond -- value of `rcond`. 

1607 

1608 For more details, see `numpy.linalg.lstsq`. 

1609 

1610 Warns 

1611 ----- 

1612 RankWarning 

1613 The rank of the coefficient matrix in the least-squares fit is 

1614 deficient. The warning is only raised if ``full == False``. The 

1615 warnings can be turned off by 

1616 

1617 >>> import warnings 

1618 >>> warnings.simplefilter('ignore', np.RankWarning) 

1619 

1620 See Also 

1621 -------- 

1622 numpy.polynomial.polynomial.polyfit 

1623 numpy.polynomial.legendre.legfit 

1624 numpy.polynomial.laguerre.lagfit 

1625 numpy.polynomial.hermite.hermfit 

1626 numpy.polynomial.hermite_e.hermefit 

1627 chebval : Evaluates a Chebyshev series. 

1628 chebvander : Vandermonde matrix of Chebyshev series. 

1629 chebweight : Chebyshev weight function. 

1630 numpy.linalg.lstsq : Computes a least-squares fit from the matrix. 

1631 scipy.interpolate.UnivariateSpline : Computes spline fits. 

1632 

1633 Notes 

1634 ----- 

1635 The solution is the coefficients of the Chebyshev series `p` that 

1636 minimizes the sum of the weighted squared errors 

1637 

1638 .. math:: E = \\sum_j w_j^2 * |y_j - p(x_j)|^2, 

1639 

1640 where :math:`w_j` are the weights. This problem is solved by setting up 

1641 as the (typically) overdetermined matrix equation 

1642 

1643 .. math:: V(x) * c = w * y, 

1644 

1645 where `V` is the weighted pseudo Vandermonde matrix of `x`, `c` are the 

1646 coefficients to be solved for, `w` are the weights, and `y` are the 

1647 observed values. This equation is then solved using the singular value 

1648 decomposition of `V`. 

1649 

1650 If some of the singular values of `V` are so small that they are 

1651 neglected, then a `RankWarning` will be issued. This means that the 

1652 coefficient values may be poorly determined. Using a lower order fit 

1653 will usually get rid of the warning. The `rcond` parameter can also be 

1654 set to a value smaller than its default, but the resulting fit may be 

1655 spurious and have large contributions from roundoff error. 

1656 

1657 Fits using Chebyshev series are usually better conditioned than fits 

1658 using power series, but much can depend on the distribution of the 

1659 sample points and the smoothness of the data. If the quality of the fit 

1660 is inadequate splines may be a good alternative. 

1661 

1662 References 

1663 ---------- 

1664 .. [1] Wikipedia, "Curve fitting", 

1665 https://en.wikipedia.org/wiki/Curve_fitting 

1666 

1667 Examples 

1668 -------- 

1669 

1670 """ 

1671 return pu._fit(chebvander, x, y, deg, rcond, full, w) 

1672 

1673 

1674def chebcompanion(c): 

1675 """Return the scaled companion matrix of c. 

1676 

1677 The basis polynomials are scaled so that the companion matrix is 

1678 symmetric when `c` is a Chebyshev basis polynomial. This provides 

1679 better eigenvalue estimates than the unscaled case and for basis 

1680 polynomials the eigenvalues are guaranteed to be real if 

1681 `numpy.linalg.eigvalsh` is used to obtain them. 

1682 

1683 Parameters 

1684 ---------- 

1685 c : array_like 

1686 1-D array of Chebyshev series coefficients ordered from low to high 

1687 degree. 

1688 

1689 Returns 

1690 ------- 

1691 mat : ndarray 

1692 Scaled companion matrix of dimensions (deg, deg). 

1693 

1694 Notes 

1695 ----- 

1696 

1697 .. versionadded:: 1.7.0 

1698 

1699 """ 

1700 # c is a trimmed copy 

1701 [c] = pu.as_series([c]) 

1702 if len(c) < 2: 

1703 raise ValueError('Series must have maximum degree of at least 1.') 

1704 if len(c) == 2: 

1705 return np.array([[-c[0]/c[1]]]) 

1706 

1707 n = len(c) - 1 

1708 mat = np.zeros((n, n), dtype=c.dtype) 

1709 scl = np.array([1.] + [np.sqrt(.5)]*(n-1)) 

1710 top = mat.reshape(-1)[1::n+1] 

1711 bot = mat.reshape(-1)[n::n+1] 

1712 top[0] = np.sqrt(.5) 

1713 top[1:] = 1/2 

1714 bot[...] = top 

1715 mat[:, -1] -= (c[:-1]/c[-1])*(scl/scl[-1])*.5 

1716 return mat 

1717 

1718 

1719def chebroots(c): 

1720 """ 

1721 Compute the roots of a Chebyshev series. 

1722 

1723 Return the roots (a.k.a. "zeros") of the polynomial 

1724 

1725 .. math:: p(x) = \\sum_i c[i] * T_i(x). 

1726 

1727 Parameters 

1728 ---------- 

1729 c : 1-D array_like 

1730 1-D array of coefficients. 

1731 

1732 Returns 

1733 ------- 

1734 out : ndarray 

1735 Array of the roots of the series. If all the roots are real, 

1736 then `out` is also real, otherwise it is complex. 

1737 

1738 See Also 

1739 -------- 

1740 numpy.polynomial.polynomial.polyroots 

1741 numpy.polynomial.legendre.legroots 

1742 numpy.polynomial.laguerre.lagroots 

1743 numpy.polynomial.hermite.hermroots 

1744 numpy.polynomial.hermite_e.hermeroots 

1745 

1746 Notes 

1747 ----- 

1748 The root estimates are obtained as the eigenvalues of the companion 

1749 matrix, Roots far from the origin of the complex plane may have large 

1750 errors due to the numerical instability of the series for such 

1751 values. Roots with multiplicity greater than 1 will also show larger 

1752 errors as the value of the series near such points is relatively 

1753 insensitive to errors in the roots. Isolated roots near the origin can 

1754 be improved by a few iterations of Newton's method. 

1755 

1756 The Chebyshev series basis polynomials aren't powers of `x` so the 

1757 results of this function may seem unintuitive. 

1758 

1759 Examples 

1760 -------- 

1761 >>> import numpy.polynomial.chebyshev as cheb 

1762 >>> cheb.chebroots((-1, 1,-1, 1)) # T3 - T2 + T1 - T0 has real roots 

1763 array([ -5.00000000e-01, 2.60860684e-17, 1.00000000e+00]) # may vary 

1764 

1765 """ 

1766 # c is a trimmed copy 

1767 [c] = pu.as_series([c]) 

1768 if len(c) < 2: 

1769 return np.array([], dtype=c.dtype) 

1770 if len(c) == 2: 

1771 return np.array([-c[0]/c[1]]) 

1772 

1773 # rotated companion matrix reduces error 

1774 m = chebcompanion(c)[::-1,::-1] 

1775 r = la.eigvals(m) 

1776 r.sort() 

1777 return r 

1778 

1779 

1780def chebinterpolate(func, deg, args=()): 

1781 """Interpolate a function at the Chebyshev points of the first kind. 

1782 

1783 Returns the Chebyshev series that interpolates `func` at the Chebyshev 

1784 points of the first kind in the interval [-1, 1]. The interpolating 

1785 series tends to a minmax approximation to `func` with increasing `deg` 

1786 if the function is continuous in the interval. 

1787 

1788 .. versionadded:: 1.14.0 

1789 

1790 Parameters 

1791 ---------- 

1792 func : function 

1793 The function to be approximated. It must be a function of a single 

1794 variable of the form ``f(x, a, b, c...)``, where ``a, b, c...`` are 

1795 extra arguments passed in the `args` parameter. 

1796 deg : int 

1797 Degree of the interpolating polynomial 

1798 args : tuple, optional 

1799 Extra arguments to be used in the function call. Default is no extra 

1800 arguments. 

1801 

1802 Returns 

1803 ------- 

1804 coef : ndarray, shape (deg + 1,) 

1805 Chebyshev coefficients of the interpolating series ordered from low to 

1806 high. 

1807 

1808 Examples 

1809 -------- 

1810 >>> import numpy.polynomial.chebyshev as C 

1811 >>> C.chebfromfunction(lambda x: np.tanh(x) + 0.5, 8) 

1812 array([ 5.00000000e-01, 8.11675684e-01, -9.86864911e-17, 

1813 -5.42457905e-02, -2.71387850e-16, 4.51658839e-03, 

1814 2.46716228e-17, -3.79694221e-04, -3.26899002e-16]) 

1815 

1816 Notes 

1817 ----- 

1818 

1819 The Chebyshev polynomials used in the interpolation are orthogonal when 

1820 sampled at the Chebyshev points of the first kind. If it is desired to 

1821 constrain some of the coefficients they can simply be set to the desired 

1822 value after the interpolation, no new interpolation or fit is needed. This 

1823 is especially useful if it is known apriori that some of coefficients are 

1824 zero. For instance, if the function is even then the coefficients of the 

1825 terms of odd degree in the result can be set to zero. 

1826 

1827 """ 

1828 deg = np.asarray(deg) 

1829 

1830 # check arguments. 

1831 if deg.ndim > 0 or deg.dtype.kind not in 'iu' or deg.size == 0: 

1832 raise TypeError("deg must be an int") 

1833 if deg < 0: 

1834 raise ValueError("expected deg >= 0") 

1835 

1836 order = deg + 1 

1837 xcheb = chebpts1(order) 

1838 yfunc = func(xcheb, *args) 

1839 m = chebvander(xcheb, deg) 

1840 c = np.dot(m.T, yfunc) 

1841 c[0] /= order 

1842 c[1:] /= 0.5*order 

1843 

1844 return c 

1845 

1846 

1847def chebgauss(deg): 

1848 """ 

1849 Gauss-Chebyshev quadrature. 

1850 

1851 Computes the sample points and weights for Gauss-Chebyshev quadrature. 

1852 These sample points and weights will correctly integrate polynomials of 

1853 degree :math:`2*deg - 1` or less over the interval :math:`[-1, 1]` with 

1854 the weight function :math:`f(x) = 1/\\sqrt{1 - x^2}`. 

1855 

1856 Parameters 

1857 ---------- 

1858 deg : int 

1859 Number of sample points and weights. It must be >= 1. 

1860 

1861 Returns 

1862 ------- 

1863 x : ndarray 

1864 1-D ndarray containing the sample points. 

1865 y : ndarray 

1866 1-D ndarray containing the weights. 

1867 

1868 Notes 

1869 ----- 

1870 

1871 .. versionadded:: 1.7.0 

1872 

1873 The results have only been tested up to degree 100, higher degrees may 

1874 be problematic. For Gauss-Chebyshev there are closed form solutions for 

1875 the sample points and weights. If n = `deg`, then 

1876 

1877 .. math:: x_i = \\cos(\\pi (2 i - 1) / (2 n)) 

1878 

1879 .. math:: w_i = \\pi / n 

1880 

1881 """ 

1882 ideg = pu._deprecate_as_int(deg, "deg") 

1883 if ideg <= 0: 

1884 raise ValueError("deg must be a positive integer") 

1885 

1886 x = np.cos(np.pi * np.arange(1, 2*ideg, 2) / (2.0*ideg)) 

1887 w = np.ones(ideg)*(np.pi/ideg) 

1888 

1889 return x, w 

1890 

1891 

1892def chebweight(x): 

1893 """ 

1894 The weight function of the Chebyshev polynomials. 

1895 

1896 The weight function is :math:`1/\\sqrt{1 - x^2}` and the interval of 

1897 integration is :math:`[-1, 1]`. The Chebyshev polynomials are 

1898 orthogonal, but not normalized, with respect to this weight function. 

1899 

1900 Parameters 

1901 ---------- 

1902 x : array_like 

1903 Values at which the weight function will be computed. 

1904 

1905 Returns 

1906 ------- 

1907 w : ndarray 

1908 The weight function at `x`. 

1909 

1910 Notes 

1911 ----- 

1912 

1913 .. versionadded:: 1.7.0 

1914 

1915 """ 

1916 w = 1./(np.sqrt(1. + x) * np.sqrt(1. - x)) 

1917 return w 

1918 

1919 

1920def chebpts1(npts): 

1921 """ 

1922 Chebyshev points of the first kind. 

1923 

1924 The Chebyshev points of the first kind are the points ``cos(x)``, 

1925 where ``x = [pi*(k + .5)/npts for k in range(npts)]``. 

1926 

1927 Parameters 

1928 ---------- 

1929 npts : int 

1930 Number of sample points desired. 

1931 

1932 Returns 

1933 ------- 

1934 pts : ndarray 

1935 The Chebyshev points of the first kind. 

1936 

1937 See Also 

1938 -------- 

1939 chebpts2 

1940 

1941 Notes 

1942 ----- 

1943 

1944 .. versionadded:: 1.5.0 

1945 

1946 """ 

1947 _npts = int(npts) 

1948 if _npts != npts: 

1949 raise ValueError("npts must be integer") 

1950 if _npts < 1: 

1951 raise ValueError("npts must be >= 1") 

1952 

1953 x = 0.5 * np.pi / _npts * np.arange(-_npts+1, _npts+1, 2) 

1954 return np.sin(x) 

1955 

1956 

1957def chebpts2(npts): 

1958 """ 

1959 Chebyshev points of the second kind. 

1960 

1961 The Chebyshev points of the second kind are the points ``cos(x)``, 

1962 where ``x = [pi*k/(npts - 1) for k in range(npts)]``. 

1963 

1964 Parameters 

1965 ---------- 

1966 npts : int 

1967 Number of sample points desired. 

1968 

1969 Returns 

1970 ------- 

1971 pts : ndarray 

1972 The Chebyshev points of the second kind. 

1973 

1974 Notes 

1975 ----- 

1976 

1977 .. versionadded:: 1.5.0 

1978 

1979 """ 

1980 _npts = int(npts) 

1981 if _npts != npts: 

1982 raise ValueError("npts must be integer") 

1983 if _npts < 2: 

1984 raise ValueError("npts must be >= 2") 

1985 

1986 x = np.linspace(-np.pi, 0, _npts) 

1987 return np.cos(x) 

1988 

1989 

1990# 

1991# Chebyshev series class 

1992# 

1993 

1994class Chebyshev(ABCPolyBase): 

1995 """A Chebyshev series class. 

1996 

1997 The Chebyshev class provides the standard Python numerical methods 

1998 '+', '-', '*', '//', '%', 'divmod', '**', and '()' as well as the 

1999 methods listed below. 

2000 

2001 Parameters 

2002 ---------- 

2003 coef : array_like 

2004 Chebyshev coefficients in order of increasing degree, i.e., 

2005 ``(1, 2, 3)`` gives ``1*T_0(x) + 2*T_1(x) + 3*T_2(x)``. 

2006 domain : (2,) array_like, optional 

2007 Domain to use. The interval ``[domain[0], domain[1]]`` is mapped 

2008 to the interval ``[window[0], window[1]]`` by shifting and scaling. 

2009 The default value is [-1, 1]. 

2010 window : (2,) array_like, optional 

2011 Window, see `domain` for its use. The default value is [-1, 1]. 

2012 

2013 .. versionadded:: 1.6.0 

2014 

2015 """ 

2016 # Virtual Functions 

2017 _add = staticmethod(chebadd) 

2018 _sub = staticmethod(chebsub) 

2019 _mul = staticmethod(chebmul) 

2020 _div = staticmethod(chebdiv) 

2021 _pow = staticmethod(chebpow) 

2022 _val = staticmethod(chebval) 

2023 _int = staticmethod(chebint) 

2024 _der = staticmethod(chebder) 

2025 _fit = staticmethod(chebfit) 

2026 _line = staticmethod(chebline) 

2027 _roots = staticmethod(chebroots) 

2028 _fromroots = staticmethod(chebfromroots) 

2029 

2030 @classmethod 

2031 def interpolate(cls, func, deg, domain=None, args=()): 

2032 """Interpolate a function at the Chebyshev points of the first kind. 

2033 

2034 Returns the series that interpolates `func` at the Chebyshev points of 

2035 the first kind scaled and shifted to the `domain`. The resulting series 

2036 tends to a minmax approximation of `func` when the function is 

2037 continuous in the domain. 

2038 

2039 .. versionadded:: 1.14.0 

2040 

2041 Parameters 

2042 ---------- 

2043 func : function 

2044 The function to be interpolated. It must be a function of a single 

2045 variable of the form ``f(x, a, b, c...)``, where ``a, b, c...`` are 

2046 extra arguments passed in the `args` parameter. 

2047 deg : int 

2048 Degree of the interpolating polynomial. 

2049 domain : {None, [beg, end]}, optional 

2050 Domain over which `func` is interpolated. The default is None, in 

2051 which case the domain is [-1, 1]. 

2052 args : tuple, optional 

2053 Extra arguments to be used in the function call. Default is no 

2054 extra arguments. 

2055 

2056 Returns 

2057 ------- 

2058 polynomial : Chebyshev instance 

2059 Interpolating Chebyshev instance. 

2060 

2061 Notes 

2062 ----- 

2063 See `numpy.polynomial.chebfromfunction` for more details. 

2064 

2065 """ 

2066 if domain is None: 

2067 domain = cls.domain 

2068 xfunc = lambda x: func(pu.mapdomain(x, cls.window, domain), *args) 

2069 coef = chebinterpolate(xfunc, deg) 

2070 return cls(coef, domain=domain) 

2071 

2072 # Virtual properties 

2073 domain = np.array(chebdomain) 

2074 window = np.array(chebdomain) 

2075 basis_name = 'T'