Coverage for /usr/lib/python3/dist-packages/sympy/polys/densebasic.py: 14%

568 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1"""Basic tools for dense recursive polynomials in ``K[x]`` or ``K[X]``. """ 

2 

3 

4from sympy.core.numbers import oo 

5from sympy.core import igcd 

6from sympy.polys.monomials import monomial_min, monomial_div 

7from sympy.polys.orderings import monomial_key 

8 

9import random 

10 

11def poly_LC(f, K): 

12 """ 

13 Return leading coefficient of ``f``. 

14 

15 Examples 

16 ======== 

17 

18 >>> from sympy.polys.domains import ZZ 

19 >>> from sympy.polys.densebasic import poly_LC 

20 

21 >>> poly_LC([], ZZ) 

22 0 

23 >>> poly_LC([ZZ(1), ZZ(2), ZZ(3)], ZZ) 

24 1 

25 

26 """ 

27 if not f: 

28 return K.zero 

29 else: 

30 return f[0] 

31 

32 

33def poly_TC(f, K): 

34 """ 

35 Return trailing coefficient of ``f``. 

36 

37 Examples 

38 ======== 

39 

40 >>> from sympy.polys.domains import ZZ 

41 >>> from sympy.polys.densebasic import poly_TC 

42 

43 >>> poly_TC([], ZZ) 

44 0 

45 >>> poly_TC([ZZ(1), ZZ(2), ZZ(3)], ZZ) 

46 3 

47 

48 """ 

49 if not f: 

50 return K.zero 

51 else: 

52 return f[-1] 

53 

54dup_LC = dmp_LC = poly_LC 

55dup_TC = dmp_TC = poly_TC 

56 

57 

58def dmp_ground_LC(f, u, K): 

59 """ 

60 Return the ground leading coefficient. 

61 

62 Examples 

63 ======== 

64 

65 >>> from sympy.polys.domains import ZZ 

66 >>> from sympy.polys.densebasic import dmp_ground_LC 

67 

68 >>> f = ZZ.map([[[1], [2, 3]]]) 

69 

70 >>> dmp_ground_LC(f, 2, ZZ) 

71 1 

72 

73 """ 

74 while u: 

75 f = dmp_LC(f, K) 

76 u -= 1 

77 

78 return dup_LC(f, K) 

79 

80 

81def dmp_ground_TC(f, u, K): 

82 """ 

83 Return the ground trailing coefficient. 

84 

85 Examples 

86 ======== 

87 

88 >>> from sympy.polys.domains import ZZ 

89 >>> from sympy.polys.densebasic import dmp_ground_TC 

90 

91 >>> f = ZZ.map([[[1], [2, 3]]]) 

92 

93 >>> dmp_ground_TC(f, 2, ZZ) 

94 3 

95 

96 """ 

97 while u: 

98 f = dmp_TC(f, K) 

99 u -= 1 

100 

101 return dup_TC(f, K) 

102 

103 

104def dmp_true_LT(f, u, K): 

105 """ 

106 Return the leading term ``c * x_1**n_1 ... x_k**n_k``. 

107 

108 Examples 

109 ======== 

110 

111 >>> from sympy.polys.domains import ZZ 

112 >>> from sympy.polys.densebasic import dmp_true_LT 

113 

114 >>> f = ZZ.map([[4], [2, 0], [3, 0, 0]]) 

115 

116 >>> dmp_true_LT(f, 1, ZZ) 

117 ((2, 0), 4) 

118 

119 """ 

120 monom = [] 

121 

122 while u: 

123 monom.append(len(f) - 1) 

124 f, u = f[0], u - 1 

125 

126 if not f: 

127 monom.append(0) 

128 else: 

129 monom.append(len(f) - 1) 

130 

131 return tuple(monom), dup_LC(f, K) 

132 

133 

134def dup_degree(f): 

135 """ 

136 Return the leading degree of ``f`` in ``K[x]``. 

137 

138 Note that the degree of 0 is negative infinity (the SymPy object -oo). 

139 

140 Examples 

141 ======== 

142 

143 >>> from sympy.polys.domains import ZZ 

144 >>> from sympy.polys.densebasic import dup_degree 

145 

146 >>> f = ZZ.map([1, 2, 0, 3]) 

147 

148 >>> dup_degree(f) 

149 3 

150 

151 """ 

152 if not f: 

153 return -oo 

154 return len(f) - 1 

155 

156 

157def dmp_degree(f, u): 

158 """ 

159 Return the leading degree of ``f`` in ``x_0`` in ``K[X]``. 

160 

161 Note that the degree of 0 is negative infinity (the SymPy object -oo). 

162 

163 Examples 

164 ======== 

165 

166 >>> from sympy.polys.domains import ZZ 

167 >>> from sympy.polys.densebasic import dmp_degree 

168 

169 >>> dmp_degree([[[]]], 2) 

170 -oo 

171 

172 >>> f = ZZ.map([[2], [1, 2, 3]]) 

173 

174 >>> dmp_degree(f, 1) 

175 1 

176 

177 """ 

178 if dmp_zero_p(f, u): 

179 return -oo 

180 else: 

181 return len(f) - 1 

182 

183 

184def _rec_degree_in(g, v, i, j): 

185 """Recursive helper function for :func:`dmp_degree_in`.""" 

186 if i == j: 

187 return dmp_degree(g, v) 

188 

189 v, i = v - 1, i + 1 

190 

191 return max([ _rec_degree_in(c, v, i, j) for c in g ]) 

192 

193 

194def dmp_degree_in(f, j, u): 

195 """ 

196 Return the leading degree of ``f`` in ``x_j`` in ``K[X]``. 

197 

198 Examples 

199 ======== 

200 

201 >>> from sympy.polys.domains import ZZ 

202 >>> from sympy.polys.densebasic import dmp_degree_in 

203 

204 >>> f = ZZ.map([[2], [1, 2, 3]]) 

205 

206 >>> dmp_degree_in(f, 0, 1) 

207 1 

208 >>> dmp_degree_in(f, 1, 1) 

209 2 

210 

211 """ 

212 if not j: 

213 return dmp_degree(f, u) 

214 if j < 0 or j > u: 

215 raise IndexError("0 <= j <= %s expected, got %s" % (u, j)) 

216 

217 return _rec_degree_in(f, u, 0, j) 

218 

219 

220def _rec_degree_list(g, v, i, degs): 

221 """Recursive helper for :func:`dmp_degree_list`.""" 

222 degs[i] = max(degs[i], dmp_degree(g, v)) 

223 

224 if v > 0: 

225 v, i = v - 1, i + 1 

226 

227 for c in g: 

228 _rec_degree_list(c, v, i, degs) 

229 

230 

231def dmp_degree_list(f, u): 

232 """ 

233 Return a list of degrees of ``f`` in ``K[X]``. 

234 

235 Examples 

236 ======== 

237 

238 >>> from sympy.polys.domains import ZZ 

239 >>> from sympy.polys.densebasic import dmp_degree_list 

240 

241 >>> f = ZZ.map([[1], [1, 2, 3]]) 

242 

243 >>> dmp_degree_list(f, 1) 

244 (1, 2) 

245 

246 """ 

247 degs = [-oo]*(u + 1) 

248 _rec_degree_list(f, u, 0, degs) 

249 return tuple(degs) 

250 

251 

252def dup_strip(f): 

253 """ 

254 Remove leading zeros from ``f`` in ``K[x]``. 

255 

256 Examples 

257 ======== 

258 

259 >>> from sympy.polys.densebasic import dup_strip 

260 

261 >>> dup_strip([0, 0, 1, 2, 3, 0]) 

262 [1, 2, 3, 0] 

263 

264 """ 

265 if not f or f[0]: 

266 return f 

267 

268 i = 0 

269 

270 for cf in f: 

271 if cf: 

272 break 

273 else: 

274 i += 1 

275 

276 return f[i:] 

277 

278 

279def dmp_strip(f, u): 

280 """ 

281 Remove leading zeros from ``f`` in ``K[X]``. 

282 

283 Examples 

284 ======== 

285 

286 >>> from sympy.polys.densebasic import dmp_strip 

287 

288 >>> dmp_strip([[], [0, 1, 2], [1]], 1) 

289 [[0, 1, 2], [1]] 

290 

291 """ 

292 if not u: 

293 return dup_strip(f) 

294 

295 if dmp_zero_p(f, u): 

296 return f 

297 

298 i, v = 0, u - 1 

299 

300 for c in f: 

301 if not dmp_zero_p(c, v): 

302 break 

303 else: 

304 i += 1 

305 

306 if i == len(f): 

307 return dmp_zero(u) 

308 else: 

309 return f[i:] 

310 

311 

312def _rec_validate(f, g, i, K): 

313 """Recursive helper for :func:`dmp_validate`.""" 

314 if not isinstance(g, list): 

315 if K is not None and not K.of_type(g): 

316 raise TypeError("%s in %s in not of type %s" % (g, f, K.dtype)) 

317 

318 return {i - 1} 

319 elif not g: 

320 return {i} 

321 else: 

322 levels = set() 

323 

324 for c in g: 

325 levels |= _rec_validate(f, c, i + 1, K) 

326 

327 return levels 

328 

329 

330def _rec_strip(g, v): 

331 """Recursive helper for :func:`_rec_strip`.""" 

332 if not v: 

333 return dup_strip(g) 

334 

335 w = v - 1 

336 

337 return dmp_strip([ _rec_strip(c, w) for c in g ], v) 

338 

339 

340def dmp_validate(f, K=None): 

341 """ 

342 Return the number of levels in ``f`` and recursively strip it. 

343 

344 Examples 

345 ======== 

346 

347 >>> from sympy.polys.densebasic import dmp_validate 

348 

349 >>> dmp_validate([[], [0, 1, 2], [1]]) 

350 ([[1, 2], [1]], 1) 

351 

352 >>> dmp_validate([[1], 1]) 

353 Traceback (most recent call last): 

354 ... 

355 ValueError: invalid data structure for a multivariate polynomial 

356 

357 """ 

358 levels = _rec_validate(f, f, 0, K) 

359 

360 u = levels.pop() 

361 

362 if not levels: 

363 return _rec_strip(f, u), u 

364 else: 

365 raise ValueError( 

366 "invalid data structure for a multivariate polynomial") 

367 

368 

369def dup_reverse(f): 

370 """ 

371 Compute ``x**n * f(1/x)``, i.e.: reverse ``f`` in ``K[x]``. 

372 

373 Examples 

374 ======== 

375 

376 >>> from sympy.polys.domains import ZZ 

377 >>> from sympy.polys.densebasic import dup_reverse 

378 

379 >>> f = ZZ.map([1, 2, 3, 0]) 

380 

381 >>> dup_reverse(f) 

382 [3, 2, 1] 

383 

384 """ 

385 return dup_strip(list(reversed(f))) 

386 

387 

388def dup_copy(f): 

389 """ 

390 Create a new copy of a polynomial ``f`` in ``K[x]``. 

391 

392 Examples 

393 ======== 

394 

395 >>> from sympy.polys.domains import ZZ 

396 >>> from sympy.polys.densebasic import dup_copy 

397 

398 >>> f = ZZ.map([1, 2, 3, 0]) 

399 

400 >>> dup_copy([1, 2, 3, 0]) 

401 [1, 2, 3, 0] 

402 

403 """ 

404 return list(f) 

405 

406 

407def dmp_copy(f, u): 

408 """ 

409 Create a new copy of a polynomial ``f`` in ``K[X]``. 

410 

411 Examples 

412 ======== 

413 

414 >>> from sympy.polys.domains import ZZ 

415 >>> from sympy.polys.densebasic import dmp_copy 

416 

417 >>> f = ZZ.map([[1], [1, 2]]) 

418 

419 >>> dmp_copy(f, 1) 

420 [[1], [1, 2]] 

421 

422 """ 

423 if not u: 

424 return list(f) 

425 

426 v = u - 1 

427 

428 return [ dmp_copy(c, v) for c in f ] 

429 

430 

431def dup_to_tuple(f): 

432 """ 

433 Convert `f` into a tuple. 

434 

435 This is needed for hashing. This is similar to dup_copy(). 

436 

437 Examples 

438 ======== 

439 

440 >>> from sympy.polys.domains import ZZ 

441 >>> from sympy.polys.densebasic import dup_copy 

442 

443 >>> f = ZZ.map([1, 2, 3, 0]) 

444 

445 >>> dup_copy([1, 2, 3, 0]) 

446 [1, 2, 3, 0] 

447 

448 """ 

449 return tuple(f) 

450 

451 

452def dmp_to_tuple(f, u): 

453 """ 

454 Convert `f` into a nested tuple of tuples. 

455 

456 This is needed for hashing. This is similar to dmp_copy(). 

457 

458 Examples 

459 ======== 

460 

461 >>> from sympy.polys.domains import ZZ 

462 >>> from sympy.polys.densebasic import dmp_to_tuple 

463 

464 >>> f = ZZ.map([[1], [1, 2]]) 

465 

466 >>> dmp_to_tuple(f, 1) 

467 ((1,), (1, 2)) 

468 

469 """ 

470 if not u: 

471 return tuple(f) 

472 v = u - 1 

473 

474 return tuple(dmp_to_tuple(c, v) for c in f) 

475 

476 

477def dup_normal(f, K): 

478 """ 

479 Normalize univariate polynomial in the given domain. 

480 

481 Examples 

482 ======== 

483 

484 >>> from sympy.polys.domains import ZZ 

485 >>> from sympy.polys.densebasic import dup_normal 

486 

487 >>> dup_normal([0, 1.5, 2, 3], ZZ) 

488 [1, 2, 3] 

489 

490 """ 

491 return dup_strip([ K.normal(c) for c in f ]) 

492 

493 

494def dmp_normal(f, u, K): 

495 """ 

496 Normalize a multivariate polynomial in the given domain. 

497 

498 Examples 

499 ======== 

500 

501 >>> from sympy.polys.domains import ZZ 

502 >>> from sympy.polys.densebasic import dmp_normal 

503 

504 >>> dmp_normal([[], [0, 1.5, 2]], 1, ZZ) 

505 [[1, 2]] 

506 

507 """ 

508 if not u: 

509 return dup_normal(f, K) 

510 

511 v = u - 1 

512 

513 return dmp_strip([ dmp_normal(c, v, K) for c in f ], u) 

514 

515 

516def dup_convert(f, K0, K1): 

517 """ 

518 Convert the ground domain of ``f`` from ``K0`` to ``K1``. 

519 

520 Examples 

521 ======== 

522 

523 >>> from sympy.polys.rings import ring 

524 >>> from sympy.polys.domains import ZZ 

525 >>> from sympy.polys.densebasic import dup_convert 

526 

527 >>> R, x = ring("x", ZZ) 

528 

529 >>> dup_convert([R(1), R(2)], R.to_domain(), ZZ) 

530 [1, 2] 

531 >>> dup_convert([ZZ(1), ZZ(2)], ZZ, R.to_domain()) 

532 [1, 2] 

533 

534 """ 

535 if K0 is not None and K0 == K1: 

536 return f 

537 else: 

538 return dup_strip([ K1.convert(c, K0) for c in f ]) 

539 

540 

541def dmp_convert(f, u, K0, K1): 

542 """ 

543 Convert the ground domain of ``f`` from ``K0`` to ``K1``. 

544 

545 Examples 

546 ======== 

547 

548 >>> from sympy.polys.rings import ring 

549 >>> from sympy.polys.domains import ZZ 

550 >>> from sympy.polys.densebasic import dmp_convert 

551 

552 >>> R, x = ring("x", ZZ) 

553 

554 >>> dmp_convert([[R(1)], [R(2)]], 1, R.to_domain(), ZZ) 

555 [[1], [2]] 

556 >>> dmp_convert([[ZZ(1)], [ZZ(2)]], 1, ZZ, R.to_domain()) 

557 [[1], [2]] 

558 

559 """ 

560 if not u: 

561 return dup_convert(f, K0, K1) 

562 if K0 is not None and K0 == K1: 

563 return f 

564 

565 v = u - 1 

566 

567 return dmp_strip([ dmp_convert(c, v, K0, K1) for c in f ], u) 

568 

569 

570def dup_from_sympy(f, K): 

571 """ 

572 Convert the ground domain of ``f`` from SymPy to ``K``. 

573 

574 Examples 

575 ======== 

576 

577 >>> from sympy import S 

578 >>> from sympy.polys.domains import ZZ 

579 >>> from sympy.polys.densebasic import dup_from_sympy 

580 

581 >>> dup_from_sympy([S(1), S(2)], ZZ) == [ZZ(1), ZZ(2)] 

582 True 

583 

584 """ 

585 return dup_strip([ K.from_sympy(c) for c in f ]) 

586 

587 

588def dmp_from_sympy(f, u, K): 

589 """ 

590 Convert the ground domain of ``f`` from SymPy to ``K``. 

591 

592 Examples 

593 ======== 

594 

595 >>> from sympy import S 

596 >>> from sympy.polys.domains import ZZ 

597 >>> from sympy.polys.densebasic import dmp_from_sympy 

598 

599 >>> dmp_from_sympy([[S(1)], [S(2)]], 1, ZZ) == [[ZZ(1)], [ZZ(2)]] 

600 True 

601 

602 """ 

603 if not u: 

604 return dup_from_sympy(f, K) 

605 

606 v = u - 1 

607 

608 return dmp_strip([ dmp_from_sympy(c, v, K) for c in f ], u) 

609 

610 

611def dup_nth(f, n, K): 

612 """ 

613 Return the ``n``-th coefficient of ``f`` in ``K[x]``. 

614 

615 Examples 

616 ======== 

617 

618 >>> from sympy.polys.domains import ZZ 

619 >>> from sympy.polys.densebasic import dup_nth 

620 

621 >>> f = ZZ.map([1, 2, 3]) 

622 

623 >>> dup_nth(f, 0, ZZ) 

624 3 

625 >>> dup_nth(f, 4, ZZ) 

626 0 

627 

628 """ 

629 if n < 0: 

630 raise IndexError("'n' must be non-negative, got %i" % n) 

631 elif n >= len(f): 

632 return K.zero 

633 else: 

634 return f[dup_degree(f) - n] 

635 

636 

637def dmp_nth(f, n, u, K): 

638 """ 

639 Return the ``n``-th coefficient of ``f`` in ``K[x]``. 

640 

641 Examples 

642 ======== 

643 

644 >>> from sympy.polys.domains import ZZ 

645 >>> from sympy.polys.densebasic import dmp_nth 

646 

647 >>> f = ZZ.map([[1], [2], [3]]) 

648 

649 >>> dmp_nth(f, 0, 1, ZZ) 

650 [3] 

651 >>> dmp_nth(f, 4, 1, ZZ) 

652 [] 

653 

654 """ 

655 if n < 0: 

656 raise IndexError("'n' must be non-negative, got %i" % n) 

657 elif n >= len(f): 

658 return dmp_zero(u - 1) 

659 else: 

660 return f[dmp_degree(f, u) - n] 

661 

662 

663def dmp_ground_nth(f, N, u, K): 

664 """ 

665 Return the ground ``n``-th coefficient of ``f`` in ``K[x]``. 

666 

667 Examples 

668 ======== 

669 

670 >>> from sympy.polys.domains import ZZ 

671 >>> from sympy.polys.densebasic import dmp_ground_nth 

672 

673 >>> f = ZZ.map([[1], [2, 3]]) 

674 

675 >>> dmp_ground_nth(f, (0, 1), 1, ZZ) 

676 2 

677 

678 """ 

679 v = u 

680 

681 for n in N: 

682 if n < 0: 

683 raise IndexError("`n` must be non-negative, got %i" % n) 

684 elif n >= len(f): 

685 return K.zero 

686 else: 

687 d = dmp_degree(f, v) 

688 if d == -oo: 

689 d = -1 

690 f, v = f[d - n], v - 1 

691 

692 return f 

693 

694 

695def dmp_zero_p(f, u): 

696 """ 

697 Return ``True`` if ``f`` is zero in ``K[X]``. 

698 

699 Examples 

700 ======== 

701 

702 >>> from sympy.polys.densebasic import dmp_zero_p 

703 

704 >>> dmp_zero_p([[[[[]]]]], 4) 

705 True 

706 >>> dmp_zero_p([[[[[1]]]]], 4) 

707 False 

708 

709 """ 

710 while u: 

711 if len(f) != 1: 

712 return False 

713 

714 f = f[0] 

715 u -= 1 

716 

717 return not f 

718 

719 

720def dmp_zero(u): 

721 """ 

722 Return a multivariate zero. 

723 

724 Examples 

725 ======== 

726 

727 >>> from sympy.polys.densebasic import dmp_zero 

728 

729 >>> dmp_zero(4) 

730 [[[[[]]]]] 

731 

732 """ 

733 r = [] 

734 

735 for i in range(u): 

736 r = [r] 

737 

738 return r 

739 

740 

741def dmp_one_p(f, u, K): 

742 """ 

743 Return ``True`` if ``f`` is one in ``K[X]``. 

744 

745 Examples 

746 ======== 

747 

748 >>> from sympy.polys.domains import ZZ 

749 >>> from sympy.polys.densebasic import dmp_one_p 

750 

751 >>> dmp_one_p([[[ZZ(1)]]], 2, ZZ) 

752 True 

753 

754 """ 

755 return dmp_ground_p(f, K.one, u) 

756 

757 

758def dmp_one(u, K): 

759 """ 

760 Return a multivariate one over ``K``. 

761 

762 Examples 

763 ======== 

764 

765 >>> from sympy.polys.domains import ZZ 

766 >>> from sympy.polys.densebasic import dmp_one 

767 

768 >>> dmp_one(2, ZZ) 

769 [[[1]]] 

770 

771 """ 

772 return dmp_ground(K.one, u) 

773 

774 

775def dmp_ground_p(f, c, u): 

776 """ 

777 Return True if ``f`` is constant in ``K[X]``. 

778 

779 Examples 

780 ======== 

781 

782 >>> from sympy.polys.densebasic import dmp_ground_p 

783 

784 >>> dmp_ground_p([[[3]]], 3, 2) 

785 True 

786 >>> dmp_ground_p([[[4]]], None, 2) 

787 True 

788 

789 """ 

790 if c is not None and not c: 

791 return dmp_zero_p(f, u) 

792 

793 while u: 

794 if len(f) != 1: 

795 return False 

796 f = f[0] 

797 u -= 1 

798 

799 if c is None: 

800 return len(f) <= 1 

801 else: 

802 return f == [c] 

803 

804 

805def dmp_ground(c, u): 

806 """ 

807 Return a multivariate constant. 

808 

809 Examples 

810 ======== 

811 

812 >>> from sympy.polys.densebasic import dmp_ground 

813 

814 >>> dmp_ground(3, 5) 

815 [[[[[[3]]]]]] 

816 >>> dmp_ground(1, -1) 

817 1 

818 

819 """ 

820 if not c: 

821 return dmp_zero(u) 

822 

823 for i in range(u + 1): 

824 c = [c] 

825 

826 return c 

827 

828 

829def dmp_zeros(n, u, K): 

830 """ 

831 Return a list of multivariate zeros. 

832 

833 Examples 

834 ======== 

835 

836 >>> from sympy.polys.domains import ZZ 

837 >>> from sympy.polys.densebasic import dmp_zeros 

838 

839 >>> dmp_zeros(3, 2, ZZ) 

840 [[[[]]], [[[]]], [[[]]]] 

841 >>> dmp_zeros(3, -1, ZZ) 

842 [0, 0, 0] 

843 

844 """ 

845 if not n: 

846 return [] 

847 

848 if u < 0: 

849 return [K.zero]*n 

850 else: 

851 return [ dmp_zero(u) for i in range(n) ] 

852 

853 

854def dmp_grounds(c, n, u): 

855 """ 

856 Return a list of multivariate constants. 

857 

858 Examples 

859 ======== 

860 

861 >>> from sympy.polys.domains import ZZ 

862 >>> from sympy.polys.densebasic import dmp_grounds 

863 

864 >>> dmp_grounds(ZZ(4), 3, 2) 

865 [[[[4]]], [[[4]]], [[[4]]]] 

866 >>> dmp_grounds(ZZ(4), 3, -1) 

867 [4, 4, 4] 

868 

869 """ 

870 if not n: 

871 return [] 

872 

873 if u < 0: 

874 return [c]*n 

875 else: 

876 return [ dmp_ground(c, u) for i in range(n) ] 

877 

878 

879def dmp_negative_p(f, u, K): 

880 """ 

881 Return ``True`` if ``LC(f)`` is negative. 

882 

883 Examples 

884 ======== 

885 

886 >>> from sympy.polys.domains import ZZ 

887 >>> from sympy.polys.densebasic import dmp_negative_p 

888 

889 >>> dmp_negative_p([[ZZ(1)], [-ZZ(1)]], 1, ZZ) 

890 False 

891 >>> dmp_negative_p([[-ZZ(1)], [ZZ(1)]], 1, ZZ) 

892 True 

893 

894 """ 

895 return K.is_negative(dmp_ground_LC(f, u, K)) 

896 

897 

898def dmp_positive_p(f, u, K): 

899 """ 

900 Return ``True`` if ``LC(f)`` is positive. 

901 

902 Examples 

903 ======== 

904 

905 >>> from sympy.polys.domains import ZZ 

906 >>> from sympy.polys.densebasic import dmp_positive_p 

907 

908 >>> dmp_positive_p([[ZZ(1)], [-ZZ(1)]], 1, ZZ) 

909 True 

910 >>> dmp_positive_p([[-ZZ(1)], [ZZ(1)]], 1, ZZ) 

911 False 

912 

913 """ 

914 return K.is_positive(dmp_ground_LC(f, u, K)) 

915 

916 

917def dup_from_dict(f, K): 

918 """ 

919 Create a ``K[x]`` polynomial from a ``dict``. 

920 

921 Examples 

922 ======== 

923 

924 >>> from sympy.polys.domains import ZZ 

925 >>> from sympy.polys.densebasic import dup_from_dict 

926 

927 >>> dup_from_dict({(0,): ZZ(7), (2,): ZZ(5), (4,): ZZ(1)}, ZZ) 

928 [1, 0, 5, 0, 7] 

929 >>> dup_from_dict({}, ZZ) 

930 [] 

931 

932 """ 

933 if not f: 

934 return [] 

935 

936 n, h = max(f.keys()), [] 

937 

938 if isinstance(n, int): 

939 for k in range(n, -1, -1): 

940 h.append(f.get(k, K.zero)) 

941 else: 

942 (n,) = n 

943 

944 for k in range(n, -1, -1): 

945 h.append(f.get((k,), K.zero)) 

946 

947 return dup_strip(h) 

948 

949 

950def dup_from_raw_dict(f, K): 

951 """ 

952 Create a ``K[x]`` polynomial from a raw ``dict``. 

953 

954 Examples 

955 ======== 

956 

957 >>> from sympy.polys.domains import ZZ 

958 >>> from sympy.polys.densebasic import dup_from_raw_dict 

959 

960 >>> dup_from_raw_dict({0: ZZ(7), 2: ZZ(5), 4: ZZ(1)}, ZZ) 

961 [1, 0, 5, 0, 7] 

962 

963 """ 

964 if not f: 

965 return [] 

966 

967 n, h = max(f.keys()), [] 

968 

969 for k in range(n, -1, -1): 

970 h.append(f.get(k, K.zero)) 

971 

972 return dup_strip(h) 

973 

974 

975def dmp_from_dict(f, u, K): 

976 """ 

977 Create a ``K[X]`` polynomial from a ``dict``. 

978 

979 Examples 

980 ======== 

981 

982 >>> from sympy.polys.domains import ZZ 

983 >>> from sympy.polys.densebasic import dmp_from_dict 

984 

985 >>> dmp_from_dict({(0, 0): ZZ(3), (0, 1): ZZ(2), (2, 1): ZZ(1)}, 1, ZZ) 

986 [[1, 0], [], [2, 3]] 

987 >>> dmp_from_dict({}, 0, ZZ) 

988 [] 

989 

990 """ 

991 if not u: 

992 return dup_from_dict(f, K) 

993 if not f: 

994 return dmp_zero(u) 

995 

996 coeffs = {} 

997 

998 for monom, coeff in f.items(): 

999 head, tail = monom[0], monom[1:] 

1000 

1001 if head in coeffs: 

1002 coeffs[head][tail] = coeff 

1003 else: 

1004 coeffs[head] = { tail: coeff } 

1005 

1006 n, v, h = max(coeffs.keys()), u - 1, [] 

1007 

1008 for k in range(n, -1, -1): 

1009 coeff = coeffs.get(k) 

1010 

1011 if coeff is not None: 

1012 h.append(dmp_from_dict(coeff, v, K)) 

1013 else: 

1014 h.append(dmp_zero(v)) 

1015 

1016 return dmp_strip(h, u) 

1017 

1018 

1019def dup_to_dict(f, K=None, zero=False): 

1020 """ 

1021 Convert ``K[x]`` polynomial to a ``dict``. 

1022 

1023 Examples 

1024 ======== 

1025 

1026 >>> from sympy.polys.densebasic import dup_to_dict 

1027 

1028 >>> dup_to_dict([1, 0, 5, 0, 7]) 

1029 {(0,): 7, (2,): 5, (4,): 1} 

1030 >>> dup_to_dict([]) 

1031 {} 

1032 

1033 """ 

1034 if not f and zero: 

1035 return {(0,): K.zero} 

1036 

1037 n, result = len(f) - 1, {} 

1038 

1039 for k in range(0, n + 1): 

1040 if f[n - k]: 

1041 result[(k,)] = f[n - k] 

1042 

1043 return result 

1044 

1045 

1046def dup_to_raw_dict(f, K=None, zero=False): 

1047 """ 

1048 Convert a ``K[x]`` polynomial to a raw ``dict``. 

1049 

1050 Examples 

1051 ======== 

1052 

1053 >>> from sympy.polys.densebasic import dup_to_raw_dict 

1054 

1055 >>> dup_to_raw_dict([1, 0, 5, 0, 7]) 

1056 {0: 7, 2: 5, 4: 1} 

1057 

1058 """ 

1059 if not f and zero: 

1060 return {0: K.zero} 

1061 

1062 n, result = len(f) - 1, {} 

1063 

1064 for k in range(0, n + 1): 

1065 if f[n - k]: 

1066 result[k] = f[n - k] 

1067 

1068 return result 

1069 

1070 

1071def dmp_to_dict(f, u, K=None, zero=False): 

1072 """ 

1073 Convert a ``K[X]`` polynomial to a ``dict````. 

1074 

1075 Examples 

1076 ======== 

1077 

1078 >>> from sympy.polys.densebasic import dmp_to_dict 

1079 

1080 >>> dmp_to_dict([[1, 0], [], [2, 3]], 1) 

1081 {(0, 0): 3, (0, 1): 2, (2, 1): 1} 

1082 >>> dmp_to_dict([], 0) 

1083 {} 

1084 

1085 """ 

1086 if not u: 

1087 return dup_to_dict(f, K, zero=zero) 

1088 

1089 if dmp_zero_p(f, u) and zero: 

1090 return {(0,)*(u + 1): K.zero} 

1091 

1092 n, v, result = dmp_degree(f, u), u - 1, {} 

1093 

1094 if n == -oo: 

1095 n = -1 

1096 

1097 for k in range(0, n + 1): 

1098 h = dmp_to_dict(f[n - k], v) 

1099 

1100 for exp, coeff in h.items(): 

1101 result[(k,) + exp] = coeff 

1102 

1103 return result 

1104 

1105 

1106def dmp_swap(f, i, j, u, K): 

1107 """ 

1108 Transform ``K[..x_i..x_j..]`` to ``K[..x_j..x_i..]``. 

1109 

1110 Examples 

1111 ======== 

1112 

1113 >>> from sympy.polys.domains import ZZ 

1114 >>> from sympy.polys.densebasic import dmp_swap 

1115 

1116 >>> f = ZZ.map([[[2], [1, 0]], []]) 

1117 

1118 >>> dmp_swap(f, 0, 1, 2, ZZ) 

1119 [[[2], []], [[1, 0], []]] 

1120 >>> dmp_swap(f, 1, 2, 2, ZZ) 

1121 [[[1], [2, 0]], [[]]] 

1122 >>> dmp_swap(f, 0, 2, 2, ZZ) 

1123 [[[1, 0]], [[2, 0], []]] 

1124 

1125 """ 

1126 if i < 0 or j < 0 or i > u or j > u: 

1127 raise IndexError("0 <= i < j <= %s expected" % u) 

1128 elif i == j: 

1129 return f 

1130 

1131 F, H = dmp_to_dict(f, u), {} 

1132 

1133 for exp, coeff in F.items(): 

1134 H[exp[:i] + (exp[j],) + 

1135 exp[i + 1:j] + 

1136 (exp[i],) + exp[j + 1:]] = coeff 

1137 

1138 return dmp_from_dict(H, u, K) 

1139 

1140 

1141def dmp_permute(f, P, u, K): 

1142 """ 

1143 Return a polynomial in ``K[x_{P(1)},..,x_{P(n)}]``. 

1144 

1145 Examples 

1146 ======== 

1147 

1148 >>> from sympy.polys.domains import ZZ 

1149 >>> from sympy.polys.densebasic import dmp_permute 

1150 

1151 >>> f = ZZ.map([[[2], [1, 0]], []]) 

1152 

1153 >>> dmp_permute(f, [1, 0, 2], 2, ZZ) 

1154 [[[2], []], [[1, 0], []]] 

1155 >>> dmp_permute(f, [1, 2, 0], 2, ZZ) 

1156 [[[1], []], [[2, 0], []]] 

1157 

1158 """ 

1159 F, H = dmp_to_dict(f, u), {} 

1160 

1161 for exp, coeff in F.items(): 

1162 new_exp = [0]*len(exp) 

1163 

1164 for e, p in zip(exp, P): 

1165 new_exp[p] = e 

1166 

1167 H[tuple(new_exp)] = coeff 

1168 

1169 return dmp_from_dict(H, u, K) 

1170 

1171 

1172def dmp_nest(f, l, K): 

1173 """ 

1174 Return a multivariate value nested ``l``-levels. 

1175 

1176 Examples 

1177 ======== 

1178 

1179 >>> from sympy.polys.domains import ZZ 

1180 >>> from sympy.polys.densebasic import dmp_nest 

1181 

1182 >>> dmp_nest([[ZZ(1)]], 2, ZZ) 

1183 [[[[1]]]] 

1184 

1185 """ 

1186 if not isinstance(f, list): 

1187 return dmp_ground(f, l) 

1188 

1189 for i in range(l): 

1190 f = [f] 

1191 

1192 return f 

1193 

1194 

1195def dmp_raise(f, l, u, K): 

1196 """ 

1197 Return a multivariate polynomial raised ``l``-levels. 

1198 

1199 Examples 

1200 ======== 

1201 

1202 >>> from sympy.polys.domains import ZZ 

1203 >>> from sympy.polys.densebasic import dmp_raise 

1204 

1205 >>> f = ZZ.map([[], [1, 2]]) 

1206 

1207 >>> dmp_raise(f, 2, 1, ZZ) 

1208 [[[[]]], [[[1]], [[2]]]] 

1209 

1210 """ 

1211 if not l: 

1212 return f 

1213 

1214 if not u: 

1215 if not f: 

1216 return dmp_zero(l) 

1217 

1218 k = l - 1 

1219 

1220 return [ dmp_ground(c, k) for c in f ] 

1221 

1222 v = u - 1 

1223 

1224 return [ dmp_raise(c, l, v, K) for c in f ] 

1225 

1226 

1227def dup_deflate(f, K): 

1228 """ 

1229 Map ``x**m`` to ``y`` in a polynomial in ``K[x]``. 

1230 

1231 Examples 

1232 ======== 

1233 

1234 >>> from sympy.polys.domains import ZZ 

1235 >>> from sympy.polys.densebasic import dup_deflate 

1236 

1237 >>> f = ZZ.map([1, 0, 0, 1, 0, 0, 1]) 

1238 

1239 >>> dup_deflate(f, ZZ) 

1240 (3, [1, 1, 1]) 

1241 

1242 """ 

1243 if dup_degree(f) <= 0: 

1244 return 1, f 

1245 

1246 g = 0 

1247 

1248 for i in range(len(f)): 

1249 if not f[-i - 1]: 

1250 continue 

1251 

1252 g = igcd(g, i) 

1253 

1254 if g == 1: 

1255 return 1, f 

1256 

1257 return g, f[::g] 

1258 

1259 

1260def dmp_deflate(f, u, K): 

1261 """ 

1262 Map ``x_i**m_i`` to ``y_i`` in a polynomial in ``K[X]``. 

1263 

1264 Examples 

1265 ======== 

1266 

1267 >>> from sympy.polys.domains import ZZ 

1268 >>> from sympy.polys.densebasic import dmp_deflate 

1269 

1270 >>> f = ZZ.map([[1, 0, 0, 2], [], [3, 0, 0, 4]]) 

1271 

1272 >>> dmp_deflate(f, 1, ZZ) 

1273 ((2, 3), [[1, 2], [3, 4]]) 

1274 

1275 """ 

1276 if dmp_zero_p(f, u): 

1277 return (1,)*(u + 1), f 

1278 

1279 F = dmp_to_dict(f, u) 

1280 B = [0]*(u + 1) 

1281 

1282 for M in F.keys(): 

1283 for i, m in enumerate(M): 

1284 B[i] = igcd(B[i], m) 

1285 

1286 for i, b in enumerate(B): 

1287 if not b: 

1288 B[i] = 1 

1289 

1290 B = tuple(B) 

1291 

1292 if all(b == 1 for b in B): 

1293 return B, f 

1294 

1295 H = {} 

1296 

1297 for A, coeff in F.items(): 

1298 N = [ a // b for a, b in zip(A, B) ] 

1299 H[tuple(N)] = coeff 

1300 

1301 return B, dmp_from_dict(H, u, K) 

1302 

1303 

1304def dup_multi_deflate(polys, K): 

1305 """ 

1306 Map ``x**m`` to ``y`` in a set of polynomials in ``K[x]``. 

1307 

1308 Examples 

1309 ======== 

1310 

1311 >>> from sympy.polys.domains import ZZ 

1312 >>> from sympy.polys.densebasic import dup_multi_deflate 

1313 

1314 >>> f = ZZ.map([1, 0, 2, 0, 3]) 

1315 >>> g = ZZ.map([4, 0, 0]) 

1316 

1317 >>> dup_multi_deflate((f, g), ZZ) 

1318 (2, ([1, 2, 3], [4, 0])) 

1319 

1320 """ 

1321 G = 0 

1322 

1323 for p in polys: 

1324 if dup_degree(p) <= 0: 

1325 return 1, polys 

1326 

1327 g = 0 

1328 

1329 for i in range(len(p)): 

1330 if not p[-i - 1]: 

1331 continue 

1332 

1333 g = igcd(g, i) 

1334 

1335 if g == 1: 

1336 return 1, polys 

1337 

1338 G = igcd(G, g) 

1339 

1340 return G, tuple([ p[::G] for p in polys ]) 

1341 

1342 

1343def dmp_multi_deflate(polys, u, K): 

1344 """ 

1345 Map ``x_i**m_i`` to ``y_i`` in a set of polynomials in ``K[X]``. 

1346 

1347 Examples 

1348 ======== 

1349 

1350 >>> from sympy.polys.domains import ZZ 

1351 >>> from sympy.polys.densebasic import dmp_multi_deflate 

1352 

1353 >>> f = ZZ.map([[1, 0, 0, 2], [], [3, 0, 0, 4]]) 

1354 >>> g = ZZ.map([[1, 0, 2], [], [3, 0, 4]]) 

1355 

1356 >>> dmp_multi_deflate((f, g), 1, ZZ) 

1357 ((2, 1), ([[1, 0, 0, 2], [3, 0, 0, 4]], [[1, 0, 2], [3, 0, 4]])) 

1358 

1359 """ 

1360 if not u: 

1361 M, H = dup_multi_deflate(polys, K) 

1362 return (M,), H 

1363 

1364 F, B = [], [0]*(u + 1) 

1365 

1366 for p in polys: 

1367 f = dmp_to_dict(p, u) 

1368 

1369 if not dmp_zero_p(p, u): 

1370 for M in f.keys(): 

1371 for i, m in enumerate(M): 

1372 B[i] = igcd(B[i], m) 

1373 

1374 F.append(f) 

1375 

1376 for i, b in enumerate(B): 

1377 if not b: 

1378 B[i] = 1 

1379 

1380 B = tuple(B) 

1381 

1382 if all(b == 1 for b in B): 

1383 return B, polys 

1384 

1385 H = [] 

1386 

1387 for f in F: 

1388 h = {} 

1389 

1390 for A, coeff in f.items(): 

1391 N = [ a // b for a, b in zip(A, B) ] 

1392 h[tuple(N)] = coeff 

1393 

1394 H.append(dmp_from_dict(h, u, K)) 

1395 

1396 return B, tuple(H) 

1397 

1398 

1399def dup_inflate(f, m, K): 

1400 """ 

1401 Map ``y`` to ``x**m`` in a polynomial in ``K[x]``. 

1402 

1403 Examples 

1404 ======== 

1405 

1406 >>> from sympy.polys.domains import ZZ 

1407 >>> from sympy.polys.densebasic import dup_inflate 

1408 

1409 >>> f = ZZ.map([1, 1, 1]) 

1410 

1411 >>> dup_inflate(f, 3, ZZ) 

1412 [1, 0, 0, 1, 0, 0, 1] 

1413 

1414 """ 

1415 if m <= 0: 

1416 raise IndexError("'m' must be positive, got %s" % m) 

1417 if m == 1 or not f: 

1418 return f 

1419 

1420 result = [f[0]] 

1421 

1422 for coeff in f[1:]: 

1423 result.extend([K.zero]*(m - 1)) 

1424 result.append(coeff) 

1425 

1426 return result 

1427 

1428 

1429def _rec_inflate(g, M, v, i, K): 

1430 """Recursive helper for :func:`dmp_inflate`.""" 

1431 if not v: 

1432 return dup_inflate(g, M[i], K) 

1433 if M[i] <= 0: 

1434 raise IndexError("all M[i] must be positive, got %s" % M[i]) 

1435 

1436 w, j = v - 1, i + 1 

1437 

1438 g = [ _rec_inflate(c, M, w, j, K) for c in g ] 

1439 

1440 result = [g[0]] 

1441 

1442 for coeff in g[1:]: 

1443 for _ in range(1, M[i]): 

1444 result.append(dmp_zero(w)) 

1445 

1446 result.append(coeff) 

1447 

1448 return result 

1449 

1450 

1451def dmp_inflate(f, M, u, K): 

1452 """ 

1453 Map ``y_i`` to ``x_i**k_i`` in a polynomial in ``K[X]``. 

1454 

1455 Examples 

1456 ======== 

1457 

1458 >>> from sympy.polys.domains import ZZ 

1459 >>> from sympy.polys.densebasic import dmp_inflate 

1460 

1461 >>> f = ZZ.map([[1, 2], [3, 4]]) 

1462 

1463 >>> dmp_inflate(f, (2, 3), 1, ZZ) 

1464 [[1, 0, 0, 2], [], [3, 0, 0, 4]] 

1465 

1466 """ 

1467 if not u: 

1468 return dup_inflate(f, M[0], K) 

1469 

1470 if all(m == 1 for m in M): 

1471 return f 

1472 else: 

1473 return _rec_inflate(f, M, u, 0, K) 

1474 

1475 

1476def dmp_exclude(f, u, K): 

1477 """ 

1478 Exclude useless levels from ``f``. 

1479 

1480 Return the levels excluded, the new excluded ``f``, and the new ``u``. 

1481 

1482 Examples 

1483 ======== 

1484 

1485 >>> from sympy.polys.domains import ZZ 

1486 >>> from sympy.polys.densebasic import dmp_exclude 

1487 

1488 >>> f = ZZ.map([[[1]], [[1], [2]]]) 

1489 

1490 >>> dmp_exclude(f, 2, ZZ) 

1491 ([2], [[1], [1, 2]], 1) 

1492 

1493 """ 

1494 if not u or dmp_ground_p(f, None, u): 

1495 return [], f, u 

1496 

1497 J, F = [], dmp_to_dict(f, u) 

1498 

1499 for j in range(0, u + 1): 

1500 for monom in F.keys(): 

1501 if monom[j]: 

1502 break 

1503 else: 

1504 J.append(j) 

1505 

1506 if not J: 

1507 return [], f, u 

1508 

1509 f = {} 

1510 

1511 for monom, coeff in F.items(): 

1512 monom = list(monom) 

1513 

1514 for j in reversed(J): 

1515 del monom[j] 

1516 

1517 f[tuple(monom)] = coeff 

1518 

1519 u -= len(J) 

1520 

1521 return J, dmp_from_dict(f, u, K), u 

1522 

1523 

1524def dmp_include(f, J, u, K): 

1525 """ 

1526 Include useless levels in ``f``. 

1527 

1528 Examples 

1529 ======== 

1530 

1531 >>> from sympy.polys.domains import ZZ 

1532 >>> from sympy.polys.densebasic import dmp_include 

1533 

1534 >>> f = ZZ.map([[1], [1, 2]]) 

1535 

1536 >>> dmp_include(f, [2], 1, ZZ) 

1537 [[[1]], [[1], [2]]] 

1538 

1539 """ 

1540 if not J: 

1541 return f 

1542 

1543 F, f = dmp_to_dict(f, u), {} 

1544 

1545 for monom, coeff in F.items(): 

1546 monom = list(monom) 

1547 

1548 for j in J: 

1549 monom.insert(j, 0) 

1550 

1551 f[tuple(monom)] = coeff 

1552 

1553 u += len(J) 

1554 

1555 return dmp_from_dict(f, u, K) 

1556 

1557 

1558def dmp_inject(f, u, K, front=False): 

1559 """ 

1560 Convert ``f`` from ``K[X][Y]`` to ``K[X,Y]``. 

1561 

1562 Examples 

1563 ======== 

1564 

1565 >>> from sympy.polys.rings import ring 

1566 >>> from sympy.polys.domains import ZZ 

1567 >>> from sympy.polys.densebasic import dmp_inject 

1568 

1569 >>> R, x,y = ring("x,y", ZZ) 

1570 

1571 >>> dmp_inject([R(1), x + 2], 0, R.to_domain()) 

1572 ([[[1]], [[1], [2]]], 2) 

1573 >>> dmp_inject([R(1), x + 2], 0, R.to_domain(), front=True) 

1574 ([[[1]], [[1, 2]]], 2) 

1575 

1576 """ 

1577 f, h = dmp_to_dict(f, u), {} 

1578 

1579 v = K.ngens - 1 

1580 

1581 for f_monom, g in f.items(): 

1582 g = g.to_dict() 

1583 

1584 for g_monom, c in g.items(): 

1585 if front: 

1586 h[g_monom + f_monom] = c 

1587 else: 

1588 h[f_monom + g_monom] = c 

1589 

1590 w = u + v + 1 

1591 

1592 return dmp_from_dict(h, w, K.dom), w 

1593 

1594 

1595def dmp_eject(f, u, K, front=False): 

1596 """ 

1597 Convert ``f`` from ``K[X,Y]`` to ``K[X][Y]``. 

1598 

1599 Examples 

1600 ======== 

1601 

1602 >>> from sympy.polys.domains import ZZ 

1603 >>> from sympy.polys.densebasic import dmp_eject 

1604 

1605 >>> dmp_eject([[[1]], [[1], [2]]], 2, ZZ['x', 'y']) 

1606 [1, x + 2] 

1607 

1608 """ 

1609 f, h = dmp_to_dict(f, u), {} 

1610 

1611 n = K.ngens 

1612 v = u - K.ngens + 1 

1613 

1614 for monom, c in f.items(): 

1615 if front: 

1616 g_monom, f_monom = monom[:n], monom[n:] 

1617 else: 

1618 g_monom, f_monom = monom[-n:], monom[:-n] 

1619 

1620 if f_monom in h: 

1621 h[f_monom][g_monom] = c 

1622 else: 

1623 h[f_monom] = {g_monom: c} 

1624 

1625 for monom, c in h.items(): 

1626 h[monom] = K(c) 

1627 

1628 return dmp_from_dict(h, v - 1, K) 

1629 

1630 

1631def dup_terms_gcd(f, K): 

1632 """ 

1633 Remove GCD of terms from ``f`` in ``K[x]``. 

1634 

1635 Examples 

1636 ======== 

1637 

1638 >>> from sympy.polys.domains import ZZ 

1639 >>> from sympy.polys.densebasic import dup_terms_gcd 

1640 

1641 >>> f = ZZ.map([1, 0, 1, 0, 0]) 

1642 

1643 >>> dup_terms_gcd(f, ZZ) 

1644 (2, [1, 0, 1]) 

1645 

1646 """ 

1647 if dup_TC(f, K) or not f: 

1648 return 0, f 

1649 

1650 i = 0 

1651 

1652 for c in reversed(f): 

1653 if not c: 

1654 i += 1 

1655 else: 

1656 break 

1657 

1658 return i, f[:-i] 

1659 

1660 

1661def dmp_terms_gcd(f, u, K): 

1662 """ 

1663 Remove GCD of terms from ``f`` in ``K[X]``. 

1664 

1665 Examples 

1666 ======== 

1667 

1668 >>> from sympy.polys.domains import ZZ 

1669 >>> from sympy.polys.densebasic import dmp_terms_gcd 

1670 

1671 >>> f = ZZ.map([[1, 0], [1, 0, 0], [], []]) 

1672 

1673 >>> dmp_terms_gcd(f, 1, ZZ) 

1674 ((2, 1), [[1], [1, 0]]) 

1675 

1676 """ 

1677 if dmp_ground_TC(f, u, K) or dmp_zero_p(f, u): 

1678 return (0,)*(u + 1), f 

1679 

1680 F = dmp_to_dict(f, u) 

1681 G = monomial_min(*list(F.keys())) 

1682 

1683 if all(g == 0 for g in G): 

1684 return G, f 

1685 

1686 f = {} 

1687 

1688 for monom, coeff in F.items(): 

1689 f[monomial_div(monom, G)] = coeff 

1690 

1691 return G, dmp_from_dict(f, u, K) 

1692 

1693 

1694def _rec_list_terms(g, v, monom): 

1695 """Recursive helper for :func:`dmp_list_terms`.""" 

1696 d, terms = dmp_degree(g, v), [] 

1697 

1698 if not v: 

1699 for i, c in enumerate(g): 

1700 if not c: 

1701 continue 

1702 

1703 terms.append((monom + (d - i,), c)) 

1704 else: 

1705 w = v - 1 

1706 

1707 for i, c in enumerate(g): 

1708 terms.extend(_rec_list_terms(c, w, monom + (d - i,))) 

1709 

1710 return terms 

1711 

1712 

1713def dmp_list_terms(f, u, K, order=None): 

1714 """ 

1715 List all non-zero terms from ``f`` in the given order ``order``. 

1716 

1717 Examples 

1718 ======== 

1719 

1720 >>> from sympy.polys.domains import ZZ 

1721 >>> from sympy.polys.densebasic import dmp_list_terms 

1722 

1723 >>> f = ZZ.map([[1, 1], [2, 3]]) 

1724 

1725 >>> dmp_list_terms(f, 1, ZZ) 

1726 [((1, 1), 1), ((1, 0), 1), ((0, 1), 2), ((0, 0), 3)] 

1727 >>> dmp_list_terms(f, 1, ZZ, order='grevlex') 

1728 [((1, 1), 1), ((1, 0), 1), ((0, 1), 2), ((0, 0), 3)] 

1729 

1730 """ 

1731 def sort(terms, O): 

1732 return sorted(terms, key=lambda term: O(term[0]), reverse=True) 

1733 

1734 terms = _rec_list_terms(f, u, ()) 

1735 

1736 if not terms: 

1737 return [((0,)*(u + 1), K.zero)] 

1738 

1739 if order is None: 

1740 return terms 

1741 else: 

1742 return sort(terms, monomial_key(order)) 

1743 

1744 

1745def dup_apply_pairs(f, g, h, args, K): 

1746 """ 

1747 Apply ``h`` to pairs of coefficients of ``f`` and ``g``. 

1748 

1749 Examples 

1750 ======== 

1751 

1752 >>> from sympy.polys.domains import ZZ 

1753 >>> from sympy.polys.densebasic import dup_apply_pairs 

1754 

1755 >>> h = lambda x, y, z: 2*x + y - z 

1756 

1757 >>> dup_apply_pairs([1, 2, 3], [3, 2, 1], h, (1,), ZZ) 

1758 [4, 5, 6] 

1759 

1760 """ 

1761 n, m = len(f), len(g) 

1762 

1763 if n != m: 

1764 if n > m: 

1765 g = [K.zero]*(n - m) + g 

1766 else: 

1767 f = [K.zero]*(m - n) + f 

1768 

1769 result = [] 

1770 

1771 for a, b in zip(f, g): 

1772 result.append(h(a, b, *args)) 

1773 

1774 return dup_strip(result) 

1775 

1776 

1777def dmp_apply_pairs(f, g, h, args, u, K): 

1778 """ 

1779 Apply ``h`` to pairs of coefficients of ``f`` and ``g``. 

1780 

1781 Examples 

1782 ======== 

1783 

1784 >>> from sympy.polys.domains import ZZ 

1785 >>> from sympy.polys.densebasic import dmp_apply_pairs 

1786 

1787 >>> h = lambda x, y, z: 2*x + y - z 

1788 

1789 >>> dmp_apply_pairs([[1], [2, 3]], [[3], [2, 1]], h, (1,), 1, ZZ) 

1790 [[4], [5, 6]] 

1791 

1792 """ 

1793 if not u: 

1794 return dup_apply_pairs(f, g, h, args, K) 

1795 

1796 n, m, v = len(f), len(g), u - 1 

1797 

1798 if n != m: 

1799 if n > m: 

1800 g = dmp_zeros(n - m, v, K) + g 

1801 else: 

1802 f = dmp_zeros(m - n, v, K) + f 

1803 

1804 result = [] 

1805 

1806 for a, b in zip(f, g): 

1807 result.append(dmp_apply_pairs(a, b, h, args, v, K)) 

1808 

1809 return dmp_strip(result, u) 

1810 

1811 

1812def dup_slice(f, m, n, K): 

1813 """Take a continuous subsequence of terms of ``f`` in ``K[x]``. """ 

1814 k = len(f) 

1815 

1816 if k >= m: 

1817 M = k - m 

1818 else: 

1819 M = 0 

1820 if k >= n: 

1821 N = k - n 

1822 else: 

1823 N = 0 

1824 

1825 f = f[N:M] 

1826 

1827 if not f: 

1828 return [] 

1829 else: 

1830 return f + [K.zero]*m 

1831 

1832 

1833def dmp_slice(f, m, n, u, K): 

1834 """Take a continuous subsequence of terms of ``f`` in ``K[X]``. """ 

1835 return dmp_slice_in(f, m, n, 0, u, K) 

1836 

1837 

1838def dmp_slice_in(f, m, n, j, u, K): 

1839 """Take a continuous subsequence of terms of ``f`` in ``x_j`` in ``K[X]``. """ 

1840 if j < 0 or j > u: 

1841 raise IndexError("-%s <= j < %s expected, got %s" % (u, u, j)) 

1842 

1843 if not u: 

1844 return dup_slice(f, m, n, K) 

1845 

1846 f, g = dmp_to_dict(f, u), {} 

1847 

1848 for monom, coeff in f.items(): 

1849 k = monom[j] 

1850 

1851 if k < m or k >= n: 

1852 monom = monom[:j] + (0,) + monom[j + 1:] 

1853 

1854 if monom in g: 

1855 g[monom] += coeff 

1856 else: 

1857 g[monom] = coeff 

1858 

1859 return dmp_from_dict(g, u, K) 

1860 

1861 

1862def dup_random(n, a, b, K): 

1863 """ 

1864 Return a polynomial of degree ``n`` with coefficients in ``[a, b]``. 

1865 

1866 Examples 

1867 ======== 

1868 

1869 >>> from sympy.polys.domains import ZZ 

1870 >>> from sympy.polys.densebasic import dup_random 

1871 

1872 >>> dup_random(3, -10, 10, ZZ) #doctest: +SKIP 

1873 [-2, -8, 9, -4] 

1874 

1875 """ 

1876 f = [ K.convert(random.randint(a, b)) for _ in range(0, n + 1) ] 

1877 

1878 while not f[0]: 

1879 f[0] = K.convert(random.randint(a, b)) 

1880 

1881 return f