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

252 statements  

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

1""" 

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

3Laguerre Series (:mod:`numpy.polynomial.laguerre`) 

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

5 

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

7dealing with Laguerre series, including a `Laguerre` 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.. autosummary:: 

15 :toctree: generated/ 

16 

17 Laguerre 

18 

19Constants 

20--------- 

21.. autosummary:: 

22 :toctree: generated/ 

23 

24 lagdomain 

25 lagzero 

26 lagone 

27 lagx 

28 

29Arithmetic 

30---------- 

31.. autosummary:: 

32 :toctree: generated/ 

33 

34 lagadd 

35 lagsub 

36 lagmulx 

37 lagmul 

38 lagdiv 

39 lagpow 

40 lagval 

41 lagval2d 

42 lagval3d 

43 laggrid2d 

44 laggrid3d 

45 

46Calculus 

47-------- 

48.. autosummary:: 

49 :toctree: generated/ 

50 

51 lagder 

52 lagint 

53 

54Misc Functions 

55-------------- 

56.. autosummary:: 

57 :toctree: generated/ 

58 

59 lagfromroots 

60 lagroots 

61 lagvander 

62 lagvander2d 

63 lagvander3d 

64 laggauss 

65 lagweight 

66 lagcompanion 

67 lagfit 

68 lagtrim 

69 lagline 

70 lag2poly 

71 poly2lag 

72 

73See also 

74-------- 

75`numpy.polynomial` 

76 

77""" 

78import numpy as np 

79import numpy.linalg as la 

80from numpy.core.multiarray import normalize_axis_index 

81 

82from . import polyutils as pu 

83from ._polybase import ABCPolyBase 

84 

85__all__ = [ 

86 'lagzero', 'lagone', 'lagx', 'lagdomain', 'lagline', 'lagadd', 

87 'lagsub', 'lagmulx', 'lagmul', 'lagdiv', 'lagpow', 'lagval', 'lagder', 

88 'lagint', 'lag2poly', 'poly2lag', 'lagfromroots', 'lagvander', 

89 'lagfit', 'lagtrim', 'lagroots', 'Laguerre', 'lagval2d', 'lagval3d', 

90 'laggrid2d', 'laggrid3d', 'lagvander2d', 'lagvander3d', 'lagcompanion', 

91 'laggauss', 'lagweight'] 

92 

93lagtrim = pu.trimcoef 

94 

95 

96def poly2lag(pol): 

97 """ 

98 poly2lag(pol) 

99 

100 Convert a polynomial to a Laguerre series. 

101 

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

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

104 array of the coefficients of the equivalent Laguerre series, ordered 

105 from lowest to highest degree. 

106 

107 Parameters 

108 ---------- 

109 pol : array_like 

110 1-D array containing the polynomial coefficients 

111 

112 Returns 

113 ------- 

114 c : ndarray 

115 1-D array containing the coefficients of the equivalent Laguerre 

116 series. 

117 

118 See Also 

119 -------- 

120 lag2poly 

121 

122 Notes 

123 ----- 

124 The easy way to do conversions between polynomial basis sets 

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

126 

127 Examples 

128 -------- 

129 >>> from numpy.polynomial.laguerre import poly2lag 

130 >>> poly2lag(np.arange(4)) 

131 array([ 23., -63., 58., -18.]) 

132 

133 """ 

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

135 res = 0 

136 for p in pol[::-1]: 

137 res = lagadd(lagmulx(res), p) 

138 return res 

139 

140 

141def lag2poly(c): 

142 """ 

143 Convert a Laguerre series to a polynomial. 

144 

145 Convert an array representing the coefficients of a Laguerre series, 

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

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

148 from lowest to highest degree. 

149 

150 Parameters 

151 ---------- 

152 c : array_like 

153 1-D array containing the Laguerre series coefficients, ordered 

154 from lowest order term to highest. 

155 

156 Returns 

157 ------- 

158 pol : ndarray 

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

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

161 to highest. 

162 

163 See Also 

164 -------- 

165 poly2lag 

166 

167 Notes 

168 ----- 

169 The easy way to do conversions between polynomial basis sets 

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

171 

172 Examples 

173 -------- 

174 >>> from numpy.polynomial.laguerre import lag2poly 

175 >>> lag2poly([ 23., -63., 58., -18.]) 

176 array([0., 1., 2., 3.]) 

177 

178 """ 

179 from .polynomial import polyadd, polysub, polymulx 

180 

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

182 n = len(c) 

183 if n == 1: 

184 return c 

185 else: 

186 c0 = c[-2] 

187 c1 = c[-1] 

188 # i is the current degree of c1 

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

190 tmp = c0 

191 c0 = polysub(c[i - 2], (c1*(i - 1))/i) 

192 c1 = polyadd(tmp, polysub((2*i - 1)*c1, polymulx(c1))/i) 

193 return polyadd(c0, polysub(c1, polymulx(c1))) 

194 

195# 

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

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

198# 

199 

200# Laguerre 

201lagdomain = np.array([0, 1]) 

202 

203# Laguerre coefficients representing zero. 

204lagzero = np.array([0]) 

205 

206# Laguerre coefficients representing one. 

207lagone = np.array([1]) 

208 

209# Laguerre coefficients representing the identity x. 

210lagx = np.array([1, -1]) 

211 

212 

213def lagline(off, scl): 

214 """ 

215 Laguerre series whose graph is a straight line. 

216 

217 Parameters 

218 ---------- 

219 off, scl : scalars 

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

221 

222 Returns 

223 ------- 

224 y : ndarray 

225 This module's representation of the Laguerre series for 

226 ``off + scl*x``. 

227 

228 See Also 

229 -------- 

230 numpy.polynomial.polynomial.polyline 

231 numpy.polynomial.chebyshev.chebline 

232 numpy.polynomial.legendre.legline 

233 numpy.polynomial.hermite.hermline 

234 numpy.polynomial.hermite_e.hermeline 

235 

236 Examples 

237 -------- 

238 >>> from numpy.polynomial.laguerre import lagline, lagval 

239 >>> lagval(0,lagline(3, 2)) 

240 3.0 

241 >>> lagval(1,lagline(3, 2)) 

242 5.0 

243 

244 """ 

245 if scl != 0: 

246 return np.array([off + scl, -scl]) 

247 else: 

248 return np.array([off]) 

249 

250 

251def lagfromroots(roots): 

252 """ 

253 Generate a Laguerre series with given roots. 

254 

255 The function returns the coefficients of the polynomial 

256 

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

258 

259 in Laguerre form, where the `r_n` are the roots specified in `roots`. 

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

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

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

263 roots can appear in any order. 

264 

265 If the returned coefficients are `c`, then 

266 

267 .. math:: p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x) 

268 

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

270 polynomials in Laguerre form. 

271 

272 Parameters 

273 ---------- 

274 roots : array_like 

275 Sequence containing the roots. 

276 

277 Returns 

278 ------- 

279 out : ndarray 

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

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

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

283 below). 

284 

285 See Also 

286 -------- 

287 numpy.polynomial.polynomial.polyfromroots 

288 numpy.polynomial.legendre.legfromroots 

289 numpy.polynomial.chebyshev.chebfromroots 

290 numpy.polynomial.hermite.hermfromroots 

291 numpy.polynomial.hermite_e.hermefromroots 

292 

293 Examples 

294 -------- 

295 >>> from numpy.polynomial.laguerre import lagfromroots, lagval 

296 >>> coef = lagfromroots((-1, 0, 1)) 

297 >>> lagval((-1, 0, 1), coef) 

298 array([0., 0., 0.]) 

299 >>> coef = lagfromroots((-1j, 1j)) 

300 >>> lagval((-1j, 1j), coef) 

301 array([0.+0.j, 0.+0.j]) 

302 

303 """ 

304 return pu._fromroots(lagline, lagmul, roots) 

305 

306 

307def lagadd(c1, c2): 

308 """ 

309 Add one Laguerre series to another. 

310 

311 Returns the sum of two Laguerre series `c1` + `c2`. The arguments 

312 are sequences of coefficients ordered from lowest order term to 

313 highest, i.e., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. 

314 

315 Parameters 

316 ---------- 

317 c1, c2 : array_like 

318 1-D arrays of Laguerre series coefficients ordered from low to 

319 high. 

320 

321 Returns 

322 ------- 

323 out : ndarray 

324 Array representing the Laguerre series of their sum. 

325 

326 See Also 

327 -------- 

328 lagsub, lagmulx, lagmul, lagdiv, lagpow 

329 

330 Notes 

331 ----- 

332 Unlike multiplication, division, etc., the sum of two Laguerre series 

333 is a Laguerre series (without having to "reproject" the result onto 

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

335 is simply "component-wise." 

336 

337 Examples 

338 -------- 

339 >>> from numpy.polynomial.laguerre import lagadd 

340 >>> lagadd([1, 2, 3], [1, 2, 3, 4]) 

341 array([2., 4., 6., 4.]) 

342 

343 

344 """ 

345 return pu._add(c1, c2) 

346 

347 

348def lagsub(c1, c2): 

349 """ 

350 Subtract one Laguerre series from another. 

351 

352 Returns the difference of two Laguerre series `c1` - `c2`. The 

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

354 [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. 

355 

356 Parameters 

357 ---------- 

358 c1, c2 : array_like 

359 1-D arrays of Laguerre series coefficients ordered from low to 

360 high. 

361 

362 Returns 

363 ------- 

364 out : ndarray 

365 Of Laguerre series coefficients representing their difference. 

366 

367 See Also 

368 -------- 

369 lagadd, lagmulx, lagmul, lagdiv, lagpow 

370 

371 Notes 

372 ----- 

373 Unlike multiplication, division, etc., the difference of two Laguerre 

374 series is a Laguerre series (without having to "reproject" the result 

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

376 polynomials, is simply "component-wise." 

377 

378 Examples 

379 -------- 

380 >>> from numpy.polynomial.laguerre import lagsub 

381 >>> lagsub([1, 2, 3, 4], [1, 2, 3]) 

382 array([0., 0., 0., 4.]) 

383 

384 """ 

385 return pu._sub(c1, c2) 

386 

387 

388def lagmulx(c): 

389 """Multiply a Laguerre series by x. 

390 

391 Multiply the Laguerre series `c` by x, where x is the independent 

392 variable. 

393 

394 

395 Parameters 

396 ---------- 

397 c : array_like 

398 1-D array of Laguerre series coefficients ordered from low to 

399 high. 

400 

401 Returns 

402 ------- 

403 out : ndarray 

404 Array representing the result of the multiplication. 

405 

406 See Also 

407 -------- 

408 lagadd, lagsub, lagmul, lagdiv, lagpow 

409 

410 Notes 

411 ----- 

412 The multiplication uses the recursion relationship for Laguerre 

413 polynomials in the form 

414 

415 .. math:: 

416 

417 xP_i(x) = (-(i + 1)*P_{i + 1}(x) + (2i + 1)P_{i}(x) - iP_{i - 1}(x)) 

418 

419 Examples 

420 -------- 

421 >>> from numpy.polynomial.laguerre import lagmulx 

422 >>> lagmulx([1, 2, 3]) 

423 array([-1., -1., 11., -9.]) 

424 

425 """ 

426 # c is a trimmed copy 

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

428 # The zero series needs special treatment 

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

430 return c 

431 

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

433 prd[0] = c[0] 

434 prd[1] = -c[0] 

435 for i in range(1, len(c)): 

436 prd[i + 1] = -c[i]*(i + 1) 

437 prd[i] += c[i]*(2*i + 1) 

438 prd[i - 1] -= c[i]*i 

439 return prd 

440 

441 

442def lagmul(c1, c2): 

443 """ 

444 Multiply one Laguerre series by another. 

445 

446 Returns the product of two Laguerre series `c1` * `c2`. The arguments 

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

448 e.g., [1,2,3] represents the series ``P_0 + 2*P_1 + 3*P_2``. 

449 

450 Parameters 

451 ---------- 

452 c1, c2 : array_like 

453 1-D arrays of Laguerre series coefficients ordered from low to 

454 high. 

455 

456 Returns 

457 ------- 

458 out : ndarray 

459 Of Laguerre series coefficients representing their product. 

460 

461 See Also 

462 -------- 

463 lagadd, lagsub, lagmulx, lagdiv, lagpow 

464 

465 Notes 

466 ----- 

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

468 that are not in the Laguerre polynomial basis set. Thus, to express 

469 the product as a Laguerre series, it is necessary to "reproject" the 

470 product onto said basis set, which may produce "unintuitive" (but 

471 correct) results; see Examples section below. 

472 

473 Examples 

474 -------- 

475 >>> from numpy.polynomial.laguerre import lagmul 

476 >>> lagmul([1, 2, 3], [0, 1, 2]) 

477 array([ 8., -13., 38., -51., 36.]) 

478 

479 """ 

480 # s1, s2 are trimmed copies 

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

482 

483 if len(c1) > len(c2): 

484 c = c2 

485 xs = c1 

486 else: 

487 c = c1 

488 xs = c2 

489 

490 if len(c) == 1: 

491 c0 = c[0]*xs 

492 c1 = 0 

493 elif len(c) == 2: 

494 c0 = c[0]*xs 

495 c1 = c[1]*xs 

496 else: 

497 nd = len(c) 

498 c0 = c[-2]*xs 

499 c1 = c[-1]*xs 

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

501 tmp = c0 

502 nd = nd - 1 

503 c0 = lagsub(c[-i]*xs, (c1*(nd - 1))/nd) 

504 c1 = lagadd(tmp, lagsub((2*nd - 1)*c1, lagmulx(c1))/nd) 

505 return lagadd(c0, lagsub(c1, lagmulx(c1))) 

506 

507 

508def lagdiv(c1, c2): 

509 """ 

510 Divide one Laguerre series by another. 

511 

512 Returns the quotient-with-remainder of two Laguerre series 

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

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

515 ``P_0 + 2*P_1 + 3*P_2``. 

516 

517 Parameters 

518 ---------- 

519 c1, c2 : array_like 

520 1-D arrays of Laguerre series coefficients ordered from low to 

521 high. 

522 

523 Returns 

524 ------- 

525 [quo, rem] : ndarrays 

526 Of Laguerre series coefficients representing the quotient and 

527 remainder. 

528 

529 See Also 

530 -------- 

531 lagadd, lagsub, lagmulx, lagmul, lagpow 

532 

533 Notes 

534 ----- 

535 In general, the (polynomial) division of one Laguerre series by another 

536 results in quotient and remainder terms that are not in the Laguerre 

537 polynomial basis set. Thus, to express these results as a Laguerre 

538 series, it is necessary to "reproject" the results onto the Laguerre 

539 basis set, which may produce "unintuitive" (but correct) results; see 

540 Examples section below. 

541 

542 Examples 

543 -------- 

544 >>> from numpy.polynomial.laguerre import lagdiv 

545 >>> lagdiv([ 8., -13., 38., -51., 36.], [0, 1, 2]) 

546 (array([1., 2., 3.]), array([0.])) 

547 >>> lagdiv([ 9., -12., 38., -51., 36.], [0, 1, 2]) 

548 (array([1., 2., 3.]), array([1., 1.])) 

549 

550 """ 

551 return pu._div(lagmul, c1, c2) 

552 

553 

554def lagpow(c, pow, maxpower=16): 

555 """Raise a Laguerre series to a power. 

556 

557 Returns the Laguerre series `c` raised to the power `pow`. The 

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

559 i.e., [1,2,3] is the series ``P_0 + 2*P_1 + 3*P_2.`` 

560 

561 Parameters 

562 ---------- 

563 c : array_like 

564 1-D array of Laguerre series coefficients ordered from low to 

565 high. 

566 pow : integer 

567 Power to which the series will be raised 

568 maxpower : integer, optional 

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

570 to unmanageable size. Default is 16 

571 

572 Returns 

573 ------- 

574 coef : ndarray 

575 Laguerre series of power. 

576 

577 See Also 

578 -------- 

579 lagadd, lagsub, lagmulx, lagmul, lagdiv 

580 

581 Examples 

582 -------- 

583 >>> from numpy.polynomial.laguerre import lagpow 

584 >>> lagpow([1, 2, 3], 2) 

585 array([ 14., -16., 56., -72., 54.]) 

586 

587 """ 

588 return pu._pow(lagmul, c, pow, maxpower) 

589 

590 

591def lagder(c, m=1, scl=1, axis=0): 

592 """ 

593 Differentiate a Laguerre series. 

594 

595 Returns the Laguerre series coefficients `c` differentiated `m` times 

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

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

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

599 axis, e.g., [1,2,3] represents the series ``1*L_0 + 2*L_1 + 3*L_2`` 

600 while [[1,2],[1,2]] represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) + 

601 2*L_0(x)*L_1(y) + 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is 

602 ``y``. 

603 

604 Parameters 

605 ---------- 

606 c : array_like 

607 Array of Laguerre series coefficients. If `c` is multidimensional 

608 the different axis correspond to different variables with the 

609 degree in each axis given by the corresponding index. 

610 m : int, optional 

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

612 scl : scalar, optional 

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

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

615 variable. (Default: 1) 

616 axis : int, optional 

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

618 

619 .. versionadded:: 1.7.0 

620 

621 Returns 

622 ------- 

623 der : ndarray 

624 Laguerre series of the derivative. 

625 

626 See Also 

627 -------- 

628 lagint 

629 

630 Notes 

631 ----- 

632 In general, the result of differentiating a Laguerre series does not 

633 resemble the same operation on a power series. Thus the result of this 

634 function may be "unintuitive," albeit correct; see Examples section 

635 below. 

636 

637 Examples 

638 -------- 

639 >>> from numpy.polynomial.laguerre import lagder 

640 >>> lagder([ 1., 1., 1., -3.]) 

641 array([1., 2., 3.]) 

642 >>> lagder([ 1., 0., 0., -4., 3.], m=2) 

643 array([1., 2., 3.]) 

644 

645 """ 

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

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

648 c = c.astype(np.double) 

649 

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

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

652 if cnt < 0: 

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

654 iaxis = normalize_axis_index(iaxis, c.ndim) 

655 

656 if cnt == 0: 

657 return c 

658 

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

660 n = len(c) 

661 if cnt >= n: 

662 c = c[:1]*0 

663 else: 

664 for i in range(cnt): 

665 n = n - 1 

666 c *= scl 

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

668 for j in range(n, 1, -1): 

669 der[j - 1] = -c[j] 

670 c[j - 1] += c[j] 

671 der[0] = -c[1] 

672 c = der 

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

674 return c 

675 

676 

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

678 """ 

679 Integrate a Laguerre series. 

680 

681 Returns the Laguerre series coefficients `c` integrated `m` times from 

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

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

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

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

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

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

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

689 represents the series ``L_0 + 2*L_1 + 3*L_2`` while [[1,2],[1,2]] 

690 represents ``1*L_0(x)*L_0(y) + 1*L_1(x)*L_0(y) + 2*L_0(x)*L_1(y) + 

691 2*L_1(x)*L_1(y)`` if axis=0 is ``x`` and axis=1 is ``y``. 

692 

693 

694 Parameters 

695 ---------- 

696 c : array_like 

697 Array of Laguerre series coefficients. If `c` is multidimensional 

698 the different axis correspond to different variables with the 

699 degree in each axis given by the corresponding index. 

700 m : int, optional 

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

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

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

704 ``lbnd`` is the first value in the list, the value of the second 

705 integral at ``lbnd`` is the second value, etc. If ``k == []`` (the 

706 default), all constants are set to zero. If ``m == 1``, a single 

707 scalar can be given instead of a list. 

708 lbnd : scalar, optional 

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

710 scl : scalar, optional 

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

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

713 axis : int, optional 

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

715 

716 .. versionadded:: 1.7.0 

717 

718 Returns 

719 ------- 

720 S : ndarray 

721 Laguerre series coefficients of the integral. 

722 

723 Raises 

724 ------ 

725 ValueError 

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

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

728 

729 See Also 

730 -------- 

731 lagder 

732 

733 Notes 

734 ----- 

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

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

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

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

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

740 

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

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

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

744 Examples section below. 

745 

746 Examples 

747 -------- 

748 >>> from numpy.polynomial.laguerre import lagint 

749 >>> lagint([1,2,3]) 

750 array([ 1., 1., 1., -3.]) 

751 >>> lagint([1,2,3], m=2) 

752 array([ 1., 0., 0., -4., 3.]) 

753 >>> lagint([1,2,3], k=1) 

754 array([ 2., 1., 1., -3.]) 

755 >>> lagint([1,2,3], lbnd=-1) 

756 array([11.5, 1. , 1. , -3. ]) 

757 >>> lagint([1,2], m=2, k=[1,2], lbnd=-1) 

758 array([ 11.16666667, -5. , -3. , 2. ]) # may vary 

759 

760 """ 

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

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

763 c = c.astype(np.double) 

764 if not np.iterable(k): 

765 k = [k] 

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

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

768 if cnt < 0: 

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

770 if len(k) > cnt: 

771 raise ValueError("Too many integration constants") 

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

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

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

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

776 iaxis = normalize_axis_index(iaxis, c.ndim) 

777 

778 if cnt == 0: 

779 return c 

780 

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

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

783 for i in range(cnt): 

784 n = len(c) 

785 c *= scl 

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

787 c[0] += k[i] 

788 else: 

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

790 tmp[0] = c[0] 

791 tmp[1] = -c[0] 

792 for j in range(1, n): 

793 tmp[j] += c[j] 

794 tmp[j + 1] = -c[j] 

795 tmp[0] += k[i] - lagval(lbnd, tmp) 

796 c = tmp 

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

798 return c 

799 

800 

801def lagval(x, c, tensor=True): 

802 """ 

803 Evaluate a Laguerre series at points x. 

804 

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

806 

807 .. math:: p(x) = c_0 * L_0(x) + c_1 * L_1(x) + ... + c_n * L_n(x) 

808 

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

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

811 or its elements must support multiplication and addition both with 

812 themselves and with the elements of `c`. 

813 

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

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

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

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

818 scalars have shape (,). 

819 

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

821 they should be avoided if efficiency is a concern. 

822 

823 Parameters 

824 ---------- 

825 x : array_like, compatible object 

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

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

828 or its elements must support addition and multiplication with 

829 themselves and with the elements of `c`. 

830 c : array_like 

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

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

833 remaining indices enumerate multiple polynomials. In the two 

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

835 the columns of `c`. 

836 tensor : boolean, optional 

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

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

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

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

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

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

843 

844 .. versionadded:: 1.7.0 

845 

846 Returns 

847 ------- 

848 values : ndarray, algebra_like 

849 The shape of the return value is described above. 

850 

851 See Also 

852 -------- 

853 lagval2d, laggrid2d, lagval3d, laggrid3d 

854 

855 Notes 

856 ----- 

857 The evaluation uses Clenshaw recursion, aka synthetic division. 

858 

859 Examples 

860 -------- 

861 >>> from numpy.polynomial.laguerre import lagval 

862 >>> coef = [1,2,3] 

863 >>> lagval(1, coef) 

864 -0.5 

865 >>> lagval([[1,2],[3,4]], coef) 

866 array([[-0.5, -4. ], 

867 [-4.5, -2. ]]) 

868 

869 """ 

870 c = np.array(c, ndmin=1, copy=False) 

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

872 c = c.astype(np.double) 

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

874 x = np.asarray(x) 

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

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

877 

878 if len(c) == 1: 

879 c0 = c[0] 

880 c1 = 0 

881 elif len(c) == 2: 

882 c0 = c[0] 

883 c1 = c[1] 

884 else: 

885 nd = len(c) 

886 c0 = c[-2] 

887 c1 = c[-1] 

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

889 tmp = c0 

890 nd = nd - 1 

891 c0 = c[-i] - (c1*(nd - 1))/nd 

892 c1 = tmp + (c1*((2*nd - 1) - x))/nd 

893 return c0 + c1*(1 - x) 

894 

895 

896def lagval2d(x, y, c): 

897 """ 

898 Evaluate a 2-D Laguerre series at points (x, y). 

899 

900 This function returns the values: 

901 

902 .. math:: p(x,y) = \\sum_{i,j} c_{i,j} * L_i(x) * L_j(y) 

903 

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

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

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

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

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

909 

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

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

912 

913 Parameters 

914 ---------- 

915 x, y : array_like, compatible objects 

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

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

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

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

920 c : array_like 

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

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

923 dimension greater than two the remaining indices enumerate multiple 

924 sets of coefficients. 

925 

926 Returns 

927 ------- 

928 values : ndarray, compatible object 

929 The values of the two dimensional polynomial at points formed with 

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

931 

932 See Also 

933 -------- 

934 lagval, laggrid2d, lagval3d, laggrid3d 

935 

936 Notes 

937 ----- 

938 

939 .. versionadded:: 1.7.0 

940 

941 """ 

942 return pu._valnd(lagval, c, x, y) 

943 

944 

945def laggrid2d(x, y, c): 

946 """ 

947 Evaluate a 2-D Laguerre series on the Cartesian product of x and y. 

948 

949 This function returns the values: 

950 

951 .. math:: p(a,b) = \\sum_{i,j} c_{i,j} * L_i(a) * L_j(b) 

952 

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

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

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

956 

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

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

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

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

961 

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

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

964 x.shape + y.shape. 

965 

966 Parameters 

967 ---------- 

968 x, y : array_like, compatible objects 

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

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

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

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

973 c : array_like 

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

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

976 greater than two the remaining indices enumerate multiple sets of 

977 coefficients. 

978 

979 Returns 

980 ------- 

981 values : ndarray, compatible object 

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

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

984 

985 See Also 

986 -------- 

987 lagval, lagval2d, lagval3d, laggrid3d 

988 

989 Notes 

990 ----- 

991 

992 .. versionadded:: 1.7.0 

993 

994 """ 

995 return pu._gridnd(lagval, c, x, y) 

996 

997 

998def lagval3d(x, y, z, c): 

999 """ 

1000 Evaluate a 3-D Laguerre series at points (x, y, z). 

1001 

1002 This function returns the values: 

1003 

1004 .. math:: p(x,y,z) = \\sum_{i,j,k} c_{i,j,k} * L_i(x) * L_j(y) * L_k(z) 

1005 

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

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

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

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

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

1011 

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

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

1014 x.shape. 

1015 

1016 Parameters 

1017 ---------- 

1018 x, y, z : array_like, compatible object 

1019 The three dimensional series is evaluated at the points 

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

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

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

1023 ndarray it is treated as a scalar. 

1024 c : array_like 

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

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

1027 greater than 3 the remaining indices enumerate multiple sets of 

1028 coefficients. 

1029 

1030 Returns 

1031 ------- 

1032 values : ndarray, compatible object 

1033 The values of the multidimensional polynomial on points formed with 

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

1035 

1036 See Also 

1037 -------- 

1038 lagval, lagval2d, laggrid2d, laggrid3d 

1039 

1040 Notes 

1041 ----- 

1042 

1043 .. versionadded:: 1.7.0 

1044 

1045 """ 

1046 return pu._valnd(lagval, c, x, y, z) 

1047 

1048 

1049def laggrid3d(x, y, z, c): 

1050 """ 

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

1052 

1053 This function returns the values: 

1054 

1055 .. math:: p(a,b,c) = \\sum_{i,j,k} c_{i,j,k} * L_i(a) * L_j(b) * L_k(c) 

1056 

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

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

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

1060 the third. 

1061 

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

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

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

1065 multiplication and addition both with themselves and with the elements 

1066 of `c`. 

1067 

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

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

1070 x.shape + y.shape + z.shape. 

1071 

1072 Parameters 

1073 ---------- 

1074 x, y, z : array_like, compatible objects 

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

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

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

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

1079 scalar. 

1080 c : array_like 

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

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

1083 greater than two the remaining indices enumerate multiple sets of 

1084 coefficients. 

1085 

1086 Returns 

1087 ------- 

1088 values : ndarray, compatible object 

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

1090 product of `x` and `y`. 

1091 

1092 See Also 

1093 -------- 

1094 lagval, lagval2d, laggrid2d, lagval3d 

1095 

1096 Notes 

1097 ----- 

1098 

1099 .. versionadded:: 1.7.0 

1100 

1101 """ 

1102 return pu._gridnd(lagval, c, x, y, z) 

1103 

1104 

1105def lagvander(x, deg): 

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

1107 

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

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

1110 

1111 .. math:: V[..., i] = L_i(x) 

1112 

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

1114 `x` and the last index is the degree of the Laguerre polynomial. 

1115 

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

1117 array ``V = lagvander(x, n)``, then ``np.dot(V, c)`` and 

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

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

1120 number of Laguerre series of the same degree and sample points. 

1121 

1122 Parameters 

1123 ---------- 

1124 x : array_like 

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

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

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

1128 deg : int 

1129 Degree of the resulting matrix. 

1130 

1131 Returns 

1132 ------- 

1133 vander : ndarray 

1134 The pseudo-Vandermonde matrix. The shape of the returned matrix is 

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

1136 corresponding Laguerre polynomial. The dtype will be the same as 

1137 the converted `x`. 

1138 

1139 Examples 

1140 -------- 

1141 >>> from numpy.polynomial.laguerre import lagvander 

1142 >>> x = np.array([0, 1, 2]) 

1143 >>> lagvander(x, 3) 

1144 array([[ 1. , 1. , 1. , 1. ], 

1145 [ 1. , 0. , -0.5 , -0.66666667], 

1146 [ 1. , -1. , -1. , -0.33333333]]) 

1147 

1148 """ 

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

1150 if ideg < 0: 

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

1152 

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

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

1155 dtyp = x.dtype 

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

1157 v[0] = x*0 + 1 

1158 if ideg > 0: 

1159 v[1] = 1 - x 

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

1161 v[i] = (v[i-1]*(2*i - 1 - x) - v[i-2]*(i - 1))/i 

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

1163 

1164 

1165def lagvander2d(x, y, deg): 

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

1167 

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

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

1170 

1171 .. math:: V[..., (deg[1] + 1)*i + j] = L_i(x) * L_j(y), 

1172 

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

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

1175 the Laguerre polynomials. 

1176 

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

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

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

1180 

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

1182 

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

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

1185 fitting and for the evaluation of a large number of 2-D Laguerre 

1186 series of the same degrees and sample points. 

1187 

1188 Parameters 

1189 ---------- 

1190 x, y : array_like 

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

1192 will be converted to either float64 or complex128 depending on 

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

1194 1-D arrays. 

1195 deg : list of ints 

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

1197 

1198 Returns 

1199 ------- 

1200 vander2d : ndarray 

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

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

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

1204 

1205 See Also 

1206 -------- 

1207 lagvander, lagvander3d, lagval2d, lagval3d 

1208 

1209 Notes 

1210 ----- 

1211 

1212 .. versionadded:: 1.7.0 

1213 

1214 """ 

1215 return pu._vander_nd_flat((lagvander, lagvander), (x, y), deg) 

1216 

1217 

1218def lagvander3d(x, y, z, deg): 

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

1220 

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

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

1223 then The pseudo-Vandermonde matrix is defined by 

1224 

1225 .. math:: V[..., (m+1)(n+1)i + (n+1)j + k] = L_i(x)*L_j(y)*L_k(z), 

1226 

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

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

1229 the degrees of the Laguerre polynomials. 

1230 

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

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

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

1234 

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

1236 

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

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

1239 fitting and for the evaluation of a large number of 3-D Laguerre 

1240 series of the same degrees and sample points. 

1241 

1242 Parameters 

1243 ---------- 

1244 x, y, z : array_like 

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

1246 be converted to either float64 or complex128 depending on whether 

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

1248 arrays. 

1249 deg : list of ints 

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

1251 

1252 Returns 

1253 ------- 

1254 vander3d : ndarray 

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

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

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

1258 

1259 See Also 

1260 -------- 

1261 lagvander, lagvander3d, lagval2d, lagval3d 

1262 

1263 Notes 

1264 ----- 

1265 

1266 .. versionadded:: 1.7.0 

1267 

1268 """ 

1269 return pu._vander_nd_flat((lagvander, lagvander, lagvander), (x, y, z), deg) 

1270 

1271 

1272def lagfit(x, y, deg, rcond=None, full=False, w=None): 

1273 """ 

1274 Least squares fit of Laguerre series to data. 

1275 

1276 Return the coefficients of a Laguerre series of degree `deg` that is the 

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

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

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

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

1281 The fitted polynomial(s) are in the form 

1282 

1283 .. math:: p(x) = c_0 + c_1 * L_1(x) + ... + c_n * L_n(x), 

1284 

1285 where `n` is `deg`. 

1286 

1287 Parameters 

1288 ---------- 

1289 x : array_like, shape (M,) 

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

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

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

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

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

1295 deg : int or 1-D array_like 

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

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

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

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

1300 rcond : float, optional 

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

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

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

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

1305 full : bool, optional 

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

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

1308 information from the singular value decomposition is also returned. 

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

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

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

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

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

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

1315 

1316 Returns 

1317 ------- 

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

1319 Laguerre coefficients ordered from low to high. If `y` was 2-D, 

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

1321 `k`. 

1322 

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

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

1325 

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

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

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

1329 - rcond -- value of `rcond`. 

1330 

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

1332 

1333 Warns 

1334 ----- 

1335 RankWarning 

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

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

1338 warnings can be turned off by 

1339 

1340 >>> import warnings 

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

1342 

1343 See Also 

1344 -------- 

1345 numpy.polynomial.polynomial.polyfit 

1346 numpy.polynomial.legendre.legfit 

1347 numpy.polynomial.chebyshev.chebfit 

1348 numpy.polynomial.hermite.hermfit 

1349 numpy.polynomial.hermite_e.hermefit 

1350 lagval : Evaluates a Laguerre series. 

1351 lagvander : pseudo Vandermonde matrix of Laguerre series. 

1352 lagweight : Laguerre weight function. 

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

1354 scipy.interpolate.UnivariateSpline : Computes spline fits. 

1355 

1356 Notes 

1357 ----- 

1358 The solution is the coefficients of the Laguerre series `p` that 

1359 minimizes the sum of the weighted squared errors 

1360 

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

1362 

1363 where the :math:`w_j` are the weights. This problem is solved by 

1364 setting up as the (typically) overdetermined matrix equation 

1365 

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

1367 

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

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

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

1371 decomposition of `V`. 

1372 

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

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

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

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

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

1378 spurious and have large contributions from roundoff error. 

1379 

1380 Fits using Laguerre series are probably most useful when the data can 

1381 be approximated by ``sqrt(w(x)) * p(x)``, where `w(x)` is the Laguerre 

1382 weight. In that case the weight ``sqrt(w(x[i]))`` should be used 

1383 together with data values ``y[i]/sqrt(w(x[i]))``. The weight function is 

1384 available as `lagweight`. 

1385 

1386 References 

1387 ---------- 

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

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

1390 

1391 Examples 

1392 -------- 

1393 >>> from numpy.polynomial.laguerre import lagfit, lagval 

1394 >>> x = np.linspace(0, 10) 

1395 >>> err = np.random.randn(len(x))/10 

1396 >>> y = lagval(x, [1, 2, 3]) + err 

1397 >>> lagfit(x, y, 2) 

1398 array([ 0.96971004, 2.00193749, 3.00288744]) # may vary 

1399 

1400 """ 

1401 return pu._fit(lagvander, x, y, deg, rcond, full, w) 

1402 

1403 

1404def lagcompanion(c): 

1405 """ 

1406 Return the companion matrix of c. 

1407 

1408 The usual companion matrix of the Laguerre polynomials is already 

1409 symmetric when `c` is a basis Laguerre polynomial, so no scaling is 

1410 applied. 

1411 

1412 Parameters 

1413 ---------- 

1414 c : array_like 

1415 1-D array of Laguerre series coefficients ordered from low to high 

1416 degree. 

1417 

1418 Returns 

1419 ------- 

1420 mat : ndarray 

1421 Companion matrix of dimensions (deg, deg). 

1422 

1423 Notes 

1424 ----- 

1425 

1426 .. versionadded:: 1.7.0 

1427 

1428 """ 

1429 # c is a trimmed copy 

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

1431 if len(c) < 2: 

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

1433 if len(c) == 2: 

1434 return np.array([[1 + c[0]/c[1]]]) 

1435 

1436 n = len(c) - 1 

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

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

1439 mid = mat.reshape(-1)[0::n+1] 

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

1441 top[...] = -np.arange(1, n) 

1442 mid[...] = 2.*np.arange(n) + 1. 

1443 bot[...] = top 

1444 mat[:, -1] += (c[:-1]/c[-1])*n 

1445 return mat 

1446 

1447 

1448def lagroots(c): 

1449 """ 

1450 Compute the roots of a Laguerre series. 

1451 

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

1453 

1454 .. math:: p(x) = \\sum_i c[i] * L_i(x). 

1455 

1456 Parameters 

1457 ---------- 

1458 c : 1-D array_like 

1459 1-D array of coefficients. 

1460 

1461 Returns 

1462 ------- 

1463 out : ndarray 

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

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

1466 

1467 See Also 

1468 -------- 

1469 numpy.polynomial.polynomial.polyroots 

1470 numpy.polynomial.legendre.legroots 

1471 numpy.polynomial.chebyshev.chebroots 

1472 numpy.polynomial.hermite.hermroots 

1473 numpy.polynomial.hermite_e.hermeroots 

1474 

1475 Notes 

1476 ----- 

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

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

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

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

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

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

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

1484 

1485 The Laguerre series basis polynomials aren't powers of `x` so the 

1486 results of this function may seem unintuitive. 

1487 

1488 Examples 

1489 -------- 

1490 >>> from numpy.polynomial.laguerre import lagroots, lagfromroots 

1491 >>> coef = lagfromroots([0, 1, 2]) 

1492 >>> coef 

1493 array([ 2., -8., 12., -6.]) 

1494 >>> lagroots(coef) 

1495 array([-4.4408921e-16, 1.0000000e+00, 2.0000000e+00]) 

1496 

1497 """ 

1498 # c is a trimmed copy 

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

1500 if len(c) <= 1: 

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

1502 if len(c) == 2: 

1503 return np.array([1 + c[0]/c[1]]) 

1504 

1505 # rotated companion matrix reduces error 

1506 m = lagcompanion(c)[::-1,::-1] 

1507 r = la.eigvals(m) 

1508 r.sort() 

1509 return r 

1510 

1511 

1512def laggauss(deg): 

1513 """ 

1514 Gauss-Laguerre quadrature. 

1515 

1516 Computes the sample points and weights for Gauss-Laguerre quadrature. 

1517 These sample points and weights will correctly integrate polynomials of 

1518 degree :math:`2*deg - 1` or less over the interval :math:`[0, \\inf]` 

1519 with the weight function :math:`f(x) = \\exp(-x)`. 

1520 

1521 Parameters 

1522 ---------- 

1523 deg : int 

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

1525 

1526 Returns 

1527 ------- 

1528 x : ndarray 

1529 1-D ndarray containing the sample points. 

1530 y : ndarray 

1531 1-D ndarray containing the weights. 

1532 

1533 Notes 

1534 ----- 

1535 

1536 .. versionadded:: 1.7.0 

1537 

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

1539 be problematic. The weights are determined by using the fact that 

1540 

1541 .. math:: w_k = c / (L'_n(x_k) * L_{n-1}(x_k)) 

1542 

1543 where :math:`c` is a constant independent of :math:`k` and :math:`x_k` 

1544 is the k'th root of :math:`L_n`, and then scaling the results to get 

1545 the right value when integrating 1. 

1546 

1547 """ 

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

1549 if ideg <= 0: 

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

1551 

1552 # first approximation of roots. We use the fact that the companion 

1553 # matrix is symmetric in this case in order to obtain better zeros. 

1554 c = np.array([0]*deg + [1]) 

1555 m = lagcompanion(c) 

1556 x = la.eigvalsh(m) 

1557 

1558 # improve roots by one application of Newton 

1559 dy = lagval(x, c) 

1560 df = lagval(x, lagder(c)) 

1561 x -= dy/df 

1562 

1563 # compute the weights. We scale the factor to avoid possible numerical 

1564 # overflow. 

1565 fm = lagval(x, c[1:]) 

1566 fm /= np.abs(fm).max() 

1567 df /= np.abs(df).max() 

1568 w = 1/(fm * df) 

1569 

1570 # scale w to get the right value, 1 in this case 

1571 w /= w.sum() 

1572 

1573 return x, w 

1574 

1575 

1576def lagweight(x): 

1577 """Weight function of the Laguerre polynomials. 

1578 

1579 The weight function is :math:`exp(-x)` and the interval of integration 

1580 is :math:`[0, \\inf]`. The Laguerre polynomials are orthogonal, but not 

1581 normalized, with respect to this weight function. 

1582 

1583 Parameters 

1584 ---------- 

1585 x : array_like 

1586 Values at which the weight function will be computed. 

1587 

1588 Returns 

1589 ------- 

1590 w : ndarray 

1591 The weight function at `x`. 

1592 

1593 Notes 

1594 ----- 

1595 

1596 .. versionadded:: 1.7.0 

1597 

1598 """ 

1599 w = np.exp(-x) 

1600 return w 

1601 

1602# 

1603# Laguerre series class 

1604# 

1605 

1606class Laguerre(ABCPolyBase): 

1607 """A Laguerre series class. 

1608 

1609 The Laguerre class provides the standard Python numerical methods 

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

1611 attributes and methods listed in the `ABCPolyBase` documentation. 

1612 

1613 Parameters 

1614 ---------- 

1615 coef : array_like 

1616 Laguerre coefficients in order of increasing degree, i.e, 

1617 ``(1, 2, 3)`` gives ``1*L_0(x) + 2*L_1(X) + 3*L_2(x)``. 

1618 domain : (2,) array_like, optional 

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

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

1621 The default value is [0, 1]. 

1622 window : (2,) array_like, optional 

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

1624 

1625 .. versionadded:: 1.6.0 

1626 

1627 """ 

1628 # Virtual Functions 

1629 _add = staticmethod(lagadd) 

1630 _sub = staticmethod(lagsub) 

1631 _mul = staticmethod(lagmul) 

1632 _div = staticmethod(lagdiv) 

1633 _pow = staticmethod(lagpow) 

1634 _val = staticmethod(lagval) 

1635 _int = staticmethod(lagint) 

1636 _der = staticmethod(lagder) 

1637 _fit = staticmethod(lagfit) 

1638 _line = staticmethod(lagline) 

1639 _roots = staticmethod(lagroots) 

1640 _fromroots = staticmethod(lagfromroots) 

1641 

1642 # Virtual properties 

1643 domain = np.array(lagdomain) 

1644 window = np.array(lagdomain) 

1645 basis_name = 'L'