Coverage for /usr/lib/python3/dist-packages/sympy/polys/densearith.py: 11%
590 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
1"""Arithmetics for dense recursive polynomials in ``K[x]`` or ``K[X]``. """
4from sympy.polys.densebasic import (
5 dup_slice,
6 dup_LC, dmp_LC,
7 dup_degree, dmp_degree,
8 dup_strip, dmp_strip,
9 dmp_zero_p, dmp_zero,
10 dmp_one_p, dmp_one,
11 dmp_ground, dmp_zeros)
12from sympy.polys.polyerrors import (ExactQuotientFailed, PolynomialDivisionFailed)
14def dup_add_term(f, c, i, K):
15 """
16 Add ``c*x**i`` to ``f`` in ``K[x]``.
18 Examples
19 ========
21 >>> from sympy.polys import ring, ZZ
22 >>> R, x = ring("x", ZZ)
24 >>> R.dup_add_term(x**2 - 1, ZZ(2), 4)
25 2*x**4 + x**2 - 1
27 """
28 if not c:
29 return f
31 n = len(f)
32 m = n - i - 1
34 if i == n - 1:
35 return dup_strip([f[0] + c] + f[1:])
36 else:
37 if i >= n:
38 return [c] + [K.zero]*(i - n) + f
39 else:
40 return f[:m] + [f[m] + c] + f[m + 1:]
43def dmp_add_term(f, c, i, u, K):
44 """
45 Add ``c(x_2..x_u)*x_0**i`` to ``f`` in ``K[X]``.
47 Examples
48 ========
50 >>> from sympy.polys import ring, ZZ
51 >>> R, x,y = ring("x,y", ZZ)
53 >>> R.dmp_add_term(x*y + 1, 2, 2)
54 2*x**2 + x*y + 1
56 """
57 if not u:
58 return dup_add_term(f, c, i, K)
60 v = u - 1
62 if dmp_zero_p(c, v):
63 return f
65 n = len(f)
66 m = n - i - 1
68 if i == n - 1:
69 return dmp_strip([dmp_add(f[0], c, v, K)] + f[1:], u)
70 else:
71 if i >= n:
72 return [c] + dmp_zeros(i - n, v, K) + f
73 else:
74 return f[:m] + [dmp_add(f[m], c, v, K)] + f[m + 1:]
77def dup_sub_term(f, c, i, K):
78 """
79 Subtract ``c*x**i`` from ``f`` in ``K[x]``.
81 Examples
82 ========
84 >>> from sympy.polys import ring, ZZ
85 >>> R, x = ring("x", ZZ)
87 >>> R.dup_sub_term(2*x**4 + x**2 - 1, ZZ(2), 4)
88 x**2 - 1
90 """
91 if not c:
92 return f
94 n = len(f)
95 m = n - i - 1
97 if i == n - 1:
98 return dup_strip([f[0] - c] + f[1:])
99 else:
100 if i >= n:
101 return [-c] + [K.zero]*(i - n) + f
102 else:
103 return f[:m] + [f[m] - c] + f[m + 1:]
106def dmp_sub_term(f, c, i, u, K):
107 """
108 Subtract ``c(x_2..x_u)*x_0**i`` from ``f`` in ``K[X]``.
110 Examples
111 ========
113 >>> from sympy.polys import ring, ZZ
114 >>> R, x,y = ring("x,y", ZZ)
116 >>> R.dmp_sub_term(2*x**2 + x*y + 1, 2, 2)
117 x*y + 1
119 """
120 if not u:
121 return dup_add_term(f, -c, i, K)
123 v = u - 1
125 if dmp_zero_p(c, v):
126 return f
128 n = len(f)
129 m = n - i - 1
131 if i == n - 1:
132 return dmp_strip([dmp_sub(f[0], c, v, K)] + f[1:], u)
133 else:
134 if i >= n:
135 return [dmp_neg(c, v, K)] + dmp_zeros(i - n, v, K) + f
136 else:
137 return f[:m] + [dmp_sub(f[m], c, v, K)] + f[m + 1:]
140def dup_mul_term(f, c, i, K):
141 """
142 Multiply ``f`` by ``c*x**i`` in ``K[x]``.
144 Examples
145 ========
147 >>> from sympy.polys import ring, ZZ
148 >>> R, x = ring("x", ZZ)
150 >>> R.dup_mul_term(x**2 - 1, ZZ(3), 2)
151 3*x**4 - 3*x**2
153 """
154 if not c or not f:
155 return []
156 else:
157 return [ cf * c for cf in f ] + [K.zero]*i
160def dmp_mul_term(f, c, i, u, K):
161 """
162 Multiply ``f`` by ``c(x_2..x_u)*x_0**i`` in ``K[X]``.
164 Examples
165 ========
167 >>> from sympy.polys import ring, ZZ
168 >>> R, x,y = ring("x,y", ZZ)
170 >>> R.dmp_mul_term(x**2*y + x, 3*y, 2)
171 3*x**4*y**2 + 3*x**3*y
173 """
174 if not u:
175 return dup_mul_term(f, c, i, K)
177 v = u - 1
179 if dmp_zero_p(f, u):
180 return f
181 if dmp_zero_p(c, v):
182 return dmp_zero(u)
183 else:
184 return [ dmp_mul(cf, c, v, K) for cf in f ] + dmp_zeros(i, v, K)
187def dup_add_ground(f, c, K):
188 """
189 Add an element of the ground domain to ``f``.
191 Examples
192 ========
194 >>> from sympy.polys import ring, ZZ
195 >>> R, x = ring("x", ZZ)
197 >>> R.dup_add_ground(x**3 + 2*x**2 + 3*x + 4, ZZ(4))
198 x**3 + 2*x**2 + 3*x + 8
200 """
201 return dup_add_term(f, c, 0, K)
204def dmp_add_ground(f, c, u, K):
205 """
206 Add an element of the ground domain to ``f``.
208 Examples
209 ========
211 >>> from sympy.polys import ring, ZZ
212 >>> R, x,y = ring("x,y", ZZ)
214 >>> R.dmp_add_ground(x**3 + 2*x**2 + 3*x + 4, ZZ(4))
215 x**3 + 2*x**2 + 3*x + 8
217 """
218 return dmp_add_term(f, dmp_ground(c, u - 1), 0, u, K)
221def dup_sub_ground(f, c, K):
222 """
223 Subtract an element of the ground domain from ``f``.
225 Examples
226 ========
228 >>> from sympy.polys import ring, ZZ
229 >>> R, x = ring("x", ZZ)
231 >>> R.dup_sub_ground(x**3 + 2*x**2 + 3*x + 4, ZZ(4))
232 x**3 + 2*x**2 + 3*x
234 """
235 return dup_sub_term(f, c, 0, K)
238def dmp_sub_ground(f, c, u, K):
239 """
240 Subtract an element of the ground domain from ``f``.
242 Examples
243 ========
245 >>> from sympy.polys import ring, ZZ
246 >>> R, x,y = ring("x,y", ZZ)
248 >>> R.dmp_sub_ground(x**3 + 2*x**2 + 3*x + 4, ZZ(4))
249 x**3 + 2*x**2 + 3*x
251 """
252 return dmp_sub_term(f, dmp_ground(c, u - 1), 0, u, K)
255def dup_mul_ground(f, c, K):
256 """
257 Multiply ``f`` by a constant value in ``K[x]``.
259 Examples
260 ========
262 >>> from sympy.polys import ring, ZZ
263 >>> R, x = ring("x", ZZ)
265 >>> R.dup_mul_ground(x**2 + 2*x - 1, ZZ(3))
266 3*x**2 + 6*x - 3
268 """
269 if not c or not f:
270 return []
271 else:
272 return [ cf * c for cf in f ]
275def dmp_mul_ground(f, c, u, K):
276 """
277 Multiply ``f`` by a constant value in ``K[X]``.
279 Examples
280 ========
282 >>> from sympy.polys import ring, ZZ
283 >>> R, x,y = ring("x,y", ZZ)
285 >>> R.dmp_mul_ground(2*x + 2*y, ZZ(3))
286 6*x + 6*y
288 """
289 if not u:
290 return dup_mul_ground(f, c, K)
292 v = u - 1
294 return [ dmp_mul_ground(cf, c, v, K) for cf in f ]
297def dup_quo_ground(f, c, K):
298 """
299 Quotient by a constant in ``K[x]``.
301 Examples
302 ========
304 >>> from sympy.polys import ring, ZZ, QQ
306 >>> R, x = ring("x", ZZ)
307 >>> R.dup_quo_ground(3*x**2 + 2, ZZ(2))
308 x**2 + 1
310 >>> R, x = ring("x", QQ)
311 >>> R.dup_quo_ground(3*x**2 + 2, QQ(2))
312 3/2*x**2 + 1
314 """
315 if not c:
316 raise ZeroDivisionError('polynomial division')
317 if not f:
318 return f
320 if K.is_Field:
321 return [ K.quo(cf, c) for cf in f ]
322 else:
323 return [ cf // c for cf in f ]
326def dmp_quo_ground(f, c, u, K):
327 """
328 Quotient by a constant in ``K[X]``.
330 Examples
331 ========
333 >>> from sympy.polys import ring, ZZ, QQ
335 >>> R, x,y = ring("x,y", ZZ)
336 >>> R.dmp_quo_ground(2*x**2*y + 3*x, ZZ(2))
337 x**2*y + x
339 >>> R, x,y = ring("x,y", QQ)
340 >>> R.dmp_quo_ground(2*x**2*y + 3*x, QQ(2))
341 x**2*y + 3/2*x
343 """
344 if not u:
345 return dup_quo_ground(f, c, K)
347 v = u - 1
349 return [ dmp_quo_ground(cf, c, v, K) for cf in f ]
352def dup_exquo_ground(f, c, K):
353 """
354 Exact quotient by a constant in ``K[x]``.
356 Examples
357 ========
359 >>> from sympy.polys import ring, QQ
360 >>> R, x = ring("x", QQ)
362 >>> R.dup_exquo_ground(x**2 + 2, QQ(2))
363 1/2*x**2 + 1
365 """
366 if not c:
367 raise ZeroDivisionError('polynomial division')
368 if not f:
369 return f
371 return [ K.exquo(cf, c) for cf in f ]
374def dmp_exquo_ground(f, c, u, K):
375 """
376 Exact quotient by a constant in ``K[X]``.
378 Examples
379 ========
381 >>> from sympy.polys import ring, QQ
382 >>> R, x,y = ring("x,y", QQ)
384 >>> R.dmp_exquo_ground(x**2*y + 2*x, QQ(2))
385 1/2*x**2*y + x
387 """
388 if not u:
389 return dup_exquo_ground(f, c, K)
391 v = u - 1
393 return [ dmp_exquo_ground(cf, c, v, K) for cf in f ]
396def dup_lshift(f, n, K):
397 """
398 Efficiently multiply ``f`` by ``x**n`` in ``K[x]``.
400 Examples
401 ========
403 >>> from sympy.polys import ring, ZZ
404 >>> R, x = ring("x", ZZ)
406 >>> R.dup_lshift(x**2 + 1, 2)
407 x**4 + x**2
409 """
410 if not f:
411 return f
412 else:
413 return f + [K.zero]*n
416def dup_rshift(f, n, K):
417 """
418 Efficiently divide ``f`` by ``x**n`` in ``K[x]``.
420 Examples
421 ========
423 >>> from sympy.polys import ring, ZZ
424 >>> R, x = ring("x", ZZ)
426 >>> R.dup_rshift(x**4 + x**2, 2)
427 x**2 + 1
428 >>> R.dup_rshift(x**4 + x**2 + 2, 2)
429 x**2 + 1
431 """
432 return f[:-n]
435def dup_abs(f, K):
436 """
437 Make all coefficients positive in ``K[x]``.
439 Examples
440 ========
442 >>> from sympy.polys import ring, ZZ
443 >>> R, x = ring("x", ZZ)
445 >>> R.dup_abs(x**2 - 1)
446 x**2 + 1
448 """
449 return [ K.abs(coeff) for coeff in f ]
452def dmp_abs(f, u, K):
453 """
454 Make all coefficients positive in ``K[X]``.
456 Examples
457 ========
459 >>> from sympy.polys import ring, ZZ
460 >>> R, x,y = ring("x,y", ZZ)
462 >>> R.dmp_abs(x**2*y - x)
463 x**2*y + x
465 """
466 if not u:
467 return dup_abs(f, K)
469 v = u - 1
471 return [ dmp_abs(cf, v, K) for cf in f ]
474def dup_neg(f, K):
475 """
476 Negate a polynomial in ``K[x]``.
478 Examples
479 ========
481 >>> from sympy.polys import ring, ZZ
482 >>> R, x = ring("x", ZZ)
484 >>> R.dup_neg(x**2 - 1)
485 -x**2 + 1
487 """
488 return [ -coeff for coeff in f ]
491def dmp_neg(f, u, K):
492 """
493 Negate a polynomial in ``K[X]``.
495 Examples
496 ========
498 >>> from sympy.polys import ring, ZZ
499 >>> R, x,y = ring("x,y", ZZ)
501 >>> R.dmp_neg(x**2*y - x)
502 -x**2*y + x
504 """
505 if not u:
506 return dup_neg(f, K)
508 v = u - 1
510 return [ dmp_neg(cf, v, K) for cf in f ]
513def dup_add(f, g, K):
514 """
515 Add dense polynomials in ``K[x]``.
517 Examples
518 ========
520 >>> from sympy.polys import ring, ZZ
521 >>> R, x = ring("x", ZZ)
523 >>> R.dup_add(x**2 - 1, x - 2)
524 x**2 + x - 3
526 """
527 if not f:
528 return g
529 if not g:
530 return f
532 df = dup_degree(f)
533 dg = dup_degree(g)
535 if df == dg:
536 return dup_strip([ a + b for a, b in zip(f, g) ])
537 else:
538 k = abs(df - dg)
540 if df > dg:
541 h, f = f[:k], f[k:]
542 else:
543 h, g = g[:k], g[k:]
545 return h + [ a + b for a, b in zip(f, g) ]
548def dmp_add(f, g, u, K):
549 """
550 Add dense polynomials in ``K[X]``.
552 Examples
553 ========
555 >>> from sympy.polys import ring, ZZ
556 >>> R, x,y = ring("x,y", ZZ)
558 >>> R.dmp_add(x**2 + y, x**2*y + x)
559 x**2*y + x**2 + x + y
561 """
562 if not u:
563 return dup_add(f, g, K)
565 df = dmp_degree(f, u)
567 if df < 0:
568 return g
570 dg = dmp_degree(g, u)
572 if dg < 0:
573 return f
575 v = u - 1
577 if df == dg:
578 return dmp_strip([ dmp_add(a, b, v, K) for a, b in zip(f, g) ], u)
579 else:
580 k = abs(df - dg)
582 if df > dg:
583 h, f = f[:k], f[k:]
584 else:
585 h, g = g[:k], g[k:]
587 return h + [ dmp_add(a, b, v, K) for a, b in zip(f, g) ]
590def dup_sub(f, g, K):
591 """
592 Subtract dense polynomials in ``K[x]``.
594 Examples
595 ========
597 >>> from sympy.polys import ring, ZZ
598 >>> R, x = ring("x", ZZ)
600 >>> R.dup_sub(x**2 - 1, x - 2)
601 x**2 - x + 1
603 """
604 if not f:
605 return dup_neg(g, K)
606 if not g:
607 return f
609 df = dup_degree(f)
610 dg = dup_degree(g)
612 if df == dg:
613 return dup_strip([ a - b for a, b in zip(f, g) ])
614 else:
615 k = abs(df - dg)
617 if df > dg:
618 h, f = f[:k], f[k:]
619 else:
620 h, g = dup_neg(g[:k], K), g[k:]
622 return h + [ a - b for a, b in zip(f, g) ]
625def dmp_sub(f, g, u, K):
626 """
627 Subtract dense polynomials in ``K[X]``.
629 Examples
630 ========
632 >>> from sympy.polys import ring, ZZ
633 >>> R, x,y = ring("x,y", ZZ)
635 >>> R.dmp_sub(x**2 + y, x**2*y + x)
636 -x**2*y + x**2 - x + y
638 """
639 if not u:
640 return dup_sub(f, g, K)
642 df = dmp_degree(f, u)
644 if df < 0:
645 return dmp_neg(g, u, K)
647 dg = dmp_degree(g, u)
649 if dg < 0:
650 return f
652 v = u - 1
654 if df == dg:
655 return dmp_strip([ dmp_sub(a, b, v, K) for a, b in zip(f, g) ], u)
656 else:
657 k = abs(df - dg)
659 if df > dg:
660 h, f = f[:k], f[k:]
661 else:
662 h, g = dmp_neg(g[:k], u, K), g[k:]
664 return h + [ dmp_sub(a, b, v, K) for a, b in zip(f, g) ]
667def dup_add_mul(f, g, h, K):
668 """
669 Returns ``f + g*h`` where ``f, g, h`` are in ``K[x]``.
671 Examples
672 ========
674 >>> from sympy.polys import ring, ZZ
675 >>> R, x = ring("x", ZZ)
677 >>> R.dup_add_mul(x**2 - 1, x - 2, x + 2)
678 2*x**2 - 5
680 """
681 return dup_add(f, dup_mul(g, h, K), K)
684def dmp_add_mul(f, g, h, u, K):
685 """
686 Returns ``f + g*h`` where ``f, g, h`` are in ``K[X]``.
688 Examples
689 ========
691 >>> from sympy.polys import ring, ZZ
692 >>> R, x,y = ring("x,y", ZZ)
694 >>> R.dmp_add_mul(x**2 + y, x, x + 2)
695 2*x**2 + 2*x + y
697 """
698 return dmp_add(f, dmp_mul(g, h, u, K), u, K)
701def dup_sub_mul(f, g, h, K):
702 """
703 Returns ``f - g*h`` where ``f, g, h`` are in ``K[x]``.
705 Examples
706 ========
708 >>> from sympy.polys import ring, ZZ
709 >>> R, x = ring("x", ZZ)
711 >>> R.dup_sub_mul(x**2 - 1, x - 2, x + 2)
712 3
714 """
715 return dup_sub(f, dup_mul(g, h, K), K)
718def dmp_sub_mul(f, g, h, u, K):
719 """
720 Returns ``f - g*h`` where ``f, g, h`` are in ``K[X]``.
722 Examples
723 ========
725 >>> from sympy.polys import ring, ZZ
726 >>> R, x,y = ring("x,y", ZZ)
728 >>> R.dmp_sub_mul(x**2 + y, x, x + 2)
729 -2*x + y
731 """
732 return dmp_sub(f, dmp_mul(g, h, u, K), u, K)
735def dup_mul(f, g, K):
736 """
737 Multiply dense polynomials in ``K[x]``.
739 Examples
740 ========
742 >>> from sympy.polys import ring, ZZ
743 >>> R, x = ring("x", ZZ)
745 >>> R.dup_mul(x - 2, x + 2)
746 x**2 - 4
748 """
749 if f == g:
750 return dup_sqr(f, K)
752 if not (f and g):
753 return []
755 df = dup_degree(f)
756 dg = dup_degree(g)
758 n = max(df, dg) + 1
760 if n < 100:
761 h = []
763 for i in range(0, df + dg + 1):
764 coeff = K.zero
766 for j in range(max(0, i - dg), min(df, i) + 1):
767 coeff += f[j]*g[i - j]
769 h.append(coeff)
771 return dup_strip(h)
772 else:
773 # Use Karatsuba's algorithm (divide and conquer), see e.g.:
774 # Joris van der Hoeven, Relax But Don't Be Too Lazy,
775 # J. Symbolic Computation, 11 (2002), section 3.1.1.
776 n2 = n//2
778 fl, gl = dup_slice(f, 0, n2, K), dup_slice(g, 0, n2, K)
780 fh = dup_rshift(dup_slice(f, n2, n, K), n2, K)
781 gh = dup_rshift(dup_slice(g, n2, n, K), n2, K)
783 lo, hi = dup_mul(fl, gl, K), dup_mul(fh, gh, K)
785 mid = dup_mul(dup_add(fl, fh, K), dup_add(gl, gh, K), K)
786 mid = dup_sub(mid, dup_add(lo, hi, K), K)
788 return dup_add(dup_add(lo, dup_lshift(mid, n2, K), K),
789 dup_lshift(hi, 2*n2, K), K)
792def dmp_mul(f, g, u, K):
793 """
794 Multiply dense polynomials in ``K[X]``.
796 Examples
797 ========
799 >>> from sympy.polys import ring, ZZ
800 >>> R, x,y = ring("x,y", ZZ)
802 >>> R.dmp_mul(x*y + 1, x)
803 x**2*y + x
805 """
806 if not u:
807 return dup_mul(f, g, K)
809 if f == g:
810 return dmp_sqr(f, u, K)
812 df = dmp_degree(f, u)
814 if df < 0:
815 return f
817 dg = dmp_degree(g, u)
819 if dg < 0:
820 return g
822 h, v = [], u - 1
824 for i in range(0, df + dg + 1):
825 coeff = dmp_zero(v)
827 for j in range(max(0, i - dg), min(df, i) + 1):
828 coeff = dmp_add(coeff, dmp_mul(f[j], g[i - j], v, K), v, K)
830 h.append(coeff)
832 return dmp_strip(h, u)
835def dup_sqr(f, K):
836 """
837 Square dense polynomials in ``K[x]``.
839 Examples
840 ========
842 >>> from sympy.polys import ring, ZZ
843 >>> R, x = ring("x", ZZ)
845 >>> R.dup_sqr(x**2 + 1)
846 x**4 + 2*x**2 + 1
848 """
849 df, h = len(f) - 1, []
851 for i in range(0, 2*df + 1):
852 c = K.zero
854 jmin = max(0, i - df)
855 jmax = min(i, df)
857 n = jmax - jmin + 1
859 jmax = jmin + n // 2 - 1
861 for j in range(jmin, jmax + 1):
862 c += f[j]*f[i - j]
864 c += c
866 if n & 1:
867 elem = f[jmax + 1]
868 c += elem**2
870 h.append(c)
872 return dup_strip(h)
875def dmp_sqr(f, u, K):
876 """
877 Square dense polynomials in ``K[X]``.
879 Examples
880 ========
882 >>> from sympy.polys import ring, ZZ
883 >>> R, x,y = ring("x,y", ZZ)
885 >>> R.dmp_sqr(x**2 + x*y + y**2)
886 x**4 + 2*x**3*y + 3*x**2*y**2 + 2*x*y**3 + y**4
888 """
889 if not u:
890 return dup_sqr(f, K)
892 df = dmp_degree(f, u)
894 if df < 0:
895 return f
897 h, v = [], u - 1
899 for i in range(0, 2*df + 1):
900 c = dmp_zero(v)
902 jmin = max(0, i - df)
903 jmax = min(i, df)
905 n = jmax - jmin + 1
907 jmax = jmin + n // 2 - 1
909 for j in range(jmin, jmax + 1):
910 c = dmp_add(c, dmp_mul(f[j], f[i - j], v, K), v, K)
912 c = dmp_mul_ground(c, K(2), v, K)
914 if n & 1:
915 elem = dmp_sqr(f[jmax + 1], v, K)
916 c = dmp_add(c, elem, v, K)
918 h.append(c)
920 return dmp_strip(h, u)
923def dup_pow(f, n, K):
924 """
925 Raise ``f`` to the ``n``-th power in ``K[x]``.
927 Examples
928 ========
930 >>> from sympy.polys import ring, ZZ
931 >>> R, x = ring("x", ZZ)
933 >>> R.dup_pow(x - 2, 3)
934 x**3 - 6*x**2 + 12*x - 8
936 """
937 if not n:
938 return [K.one]
939 if n < 0:
940 raise ValueError("Cannot raise polynomial to a negative power")
941 if n == 1 or not f or f == [K.one]:
942 return f
944 g = [K.one]
946 while True:
947 n, m = n//2, n
949 if m % 2:
950 g = dup_mul(g, f, K)
952 if not n:
953 break
955 f = dup_sqr(f, K)
957 return g
960def dmp_pow(f, n, u, K):
961 """
962 Raise ``f`` to the ``n``-th power in ``K[X]``.
964 Examples
965 ========
967 >>> from sympy.polys import ring, ZZ
968 >>> R, x,y = ring("x,y", ZZ)
970 >>> R.dmp_pow(x*y + 1, 3)
971 x**3*y**3 + 3*x**2*y**2 + 3*x*y + 1
973 """
974 if not u:
975 return dup_pow(f, n, K)
977 if not n:
978 return dmp_one(u, K)
979 if n < 0:
980 raise ValueError("Cannot raise polynomial to a negative power")
981 if n == 1 or dmp_zero_p(f, u) or dmp_one_p(f, u, K):
982 return f
984 g = dmp_one(u, K)
986 while True:
987 n, m = n//2, n
989 if m & 1:
990 g = dmp_mul(g, f, u, K)
992 if not n:
993 break
995 f = dmp_sqr(f, u, K)
997 return g
1000def dup_pdiv(f, g, K):
1001 """
1002 Polynomial pseudo-division in ``K[x]``.
1004 Examples
1005 ========
1007 >>> from sympy.polys import ring, ZZ
1008 >>> R, x = ring("x", ZZ)
1010 >>> R.dup_pdiv(x**2 + 1, 2*x - 4)
1011 (2*x + 4, 20)
1013 """
1014 df = dup_degree(f)
1015 dg = dup_degree(g)
1017 q, r, dr = [], f, df
1019 if not g:
1020 raise ZeroDivisionError("polynomial division")
1021 elif df < dg:
1022 return q, r
1024 N = df - dg + 1
1025 lc_g = dup_LC(g, K)
1027 while True:
1028 lc_r = dup_LC(r, K)
1029 j, N = dr - dg, N - 1
1031 Q = dup_mul_ground(q, lc_g, K)
1032 q = dup_add_term(Q, lc_r, j, K)
1034 R = dup_mul_ground(r, lc_g, K)
1035 G = dup_mul_term(g, lc_r, j, K)
1036 r = dup_sub(R, G, K)
1038 _dr, dr = dr, dup_degree(r)
1040 if dr < dg:
1041 break
1042 elif not (dr < _dr):
1043 raise PolynomialDivisionFailed(f, g, K)
1045 c = lc_g**N
1047 q = dup_mul_ground(q, c, K)
1048 r = dup_mul_ground(r, c, K)
1050 return q, r
1053def dup_prem(f, g, K):
1054 """
1055 Polynomial pseudo-remainder in ``K[x]``.
1057 Examples
1058 ========
1060 >>> from sympy.polys import ring, ZZ
1061 >>> R, x = ring("x", ZZ)
1063 >>> R.dup_prem(x**2 + 1, 2*x - 4)
1064 20
1066 """
1067 df = dup_degree(f)
1068 dg = dup_degree(g)
1070 r, dr = f, df
1072 if not g:
1073 raise ZeroDivisionError("polynomial division")
1074 elif df < dg:
1075 return r
1077 N = df - dg + 1
1078 lc_g = dup_LC(g, K)
1080 while True:
1081 lc_r = dup_LC(r, K)
1082 j, N = dr - dg, N - 1
1084 R = dup_mul_ground(r, lc_g, K)
1085 G = dup_mul_term(g, lc_r, j, K)
1086 r = dup_sub(R, G, K)
1088 _dr, dr = dr, dup_degree(r)
1090 if dr < dg:
1091 break
1092 elif not (dr < _dr):
1093 raise PolynomialDivisionFailed(f, g, K)
1095 return dup_mul_ground(r, lc_g**N, K)
1098def dup_pquo(f, g, K):
1099 """
1100 Polynomial exact pseudo-quotient in ``K[X]``.
1102 Examples
1103 ========
1105 >>> from sympy.polys import ring, ZZ
1106 >>> R, x = ring("x", ZZ)
1108 >>> R.dup_pquo(x**2 - 1, 2*x - 2)
1109 2*x + 2
1111 >>> R.dup_pquo(x**2 + 1, 2*x - 4)
1112 2*x + 4
1114 """
1115 return dup_pdiv(f, g, K)[0]
1118def dup_pexquo(f, g, K):
1119 """
1120 Polynomial pseudo-quotient in ``K[x]``.
1122 Examples
1123 ========
1125 >>> from sympy.polys import ring, ZZ
1126 >>> R, x = ring("x", ZZ)
1128 >>> R.dup_pexquo(x**2 - 1, 2*x - 2)
1129 2*x + 2
1131 >>> R.dup_pexquo(x**2 + 1, 2*x - 4)
1132 Traceback (most recent call last):
1133 ...
1134 ExactQuotientFailed: [2, -4] does not divide [1, 0, 1]
1136 """
1137 q, r = dup_pdiv(f, g, K)
1139 if not r:
1140 return q
1141 else:
1142 raise ExactQuotientFailed(f, g)
1145def dmp_pdiv(f, g, u, K):
1146 """
1147 Polynomial pseudo-division in ``K[X]``.
1149 Examples
1150 ========
1152 >>> from sympy.polys import ring, ZZ
1153 >>> R, x,y = ring("x,y", ZZ)
1155 >>> R.dmp_pdiv(x**2 + x*y, 2*x + 2)
1156 (2*x + 2*y - 2, -4*y + 4)
1158 """
1159 if not u:
1160 return dup_pdiv(f, g, K)
1162 df = dmp_degree(f, u)
1163 dg = dmp_degree(g, u)
1165 if dg < 0:
1166 raise ZeroDivisionError("polynomial division")
1168 q, r, dr = dmp_zero(u), f, df
1170 if df < dg:
1171 return q, r
1173 N = df - dg + 1
1174 lc_g = dmp_LC(g, K)
1176 while True:
1177 lc_r = dmp_LC(r, K)
1178 j, N = dr - dg, N - 1
1180 Q = dmp_mul_term(q, lc_g, 0, u, K)
1181 q = dmp_add_term(Q, lc_r, j, u, K)
1183 R = dmp_mul_term(r, lc_g, 0, u, K)
1184 G = dmp_mul_term(g, lc_r, j, u, K)
1185 r = dmp_sub(R, G, u, K)
1187 _dr, dr = dr, dmp_degree(r, u)
1189 if dr < dg:
1190 break
1191 elif not (dr < _dr):
1192 raise PolynomialDivisionFailed(f, g, K)
1194 c = dmp_pow(lc_g, N, u - 1, K)
1196 q = dmp_mul_term(q, c, 0, u, K)
1197 r = dmp_mul_term(r, c, 0, u, K)
1199 return q, r
1202def dmp_prem(f, g, u, K):
1203 """
1204 Polynomial pseudo-remainder in ``K[X]``.
1206 Examples
1207 ========
1209 >>> from sympy.polys import ring, ZZ
1210 >>> R, x,y = ring("x,y", ZZ)
1212 >>> R.dmp_prem(x**2 + x*y, 2*x + 2)
1213 -4*y + 4
1215 """
1216 if not u:
1217 return dup_prem(f, g, K)
1219 df = dmp_degree(f, u)
1220 dg = dmp_degree(g, u)
1222 if dg < 0:
1223 raise ZeroDivisionError("polynomial division")
1225 r, dr = f, df
1227 if df < dg:
1228 return r
1230 N = df - dg + 1
1231 lc_g = dmp_LC(g, K)
1233 while True:
1234 lc_r = dmp_LC(r, K)
1235 j, N = dr - dg, N - 1
1237 R = dmp_mul_term(r, lc_g, 0, u, K)
1238 G = dmp_mul_term(g, lc_r, j, u, K)
1239 r = dmp_sub(R, G, u, K)
1241 _dr, dr = dr, dmp_degree(r, u)
1243 if dr < dg:
1244 break
1245 elif not (dr < _dr):
1246 raise PolynomialDivisionFailed(f, g, K)
1248 c = dmp_pow(lc_g, N, u - 1, K)
1250 return dmp_mul_term(r, c, 0, u, K)
1253def dmp_pquo(f, g, u, K):
1254 """
1255 Polynomial exact pseudo-quotient in ``K[X]``.
1257 Examples
1258 ========
1260 >>> from sympy.polys import ring, ZZ
1261 >>> R, x,y = ring("x,y", ZZ)
1263 >>> f = x**2 + x*y
1264 >>> g = 2*x + 2*y
1265 >>> h = 2*x + 2
1267 >>> R.dmp_pquo(f, g)
1268 2*x
1270 >>> R.dmp_pquo(f, h)
1271 2*x + 2*y - 2
1273 """
1274 return dmp_pdiv(f, g, u, K)[0]
1277def dmp_pexquo(f, g, u, K):
1278 """
1279 Polynomial pseudo-quotient in ``K[X]``.
1281 Examples
1282 ========
1284 >>> from sympy.polys import ring, ZZ
1285 >>> R, x,y = ring("x,y", ZZ)
1287 >>> f = x**2 + x*y
1288 >>> g = 2*x + 2*y
1289 >>> h = 2*x + 2
1291 >>> R.dmp_pexquo(f, g)
1292 2*x
1294 >>> R.dmp_pexquo(f, h)
1295 Traceback (most recent call last):
1296 ...
1297 ExactQuotientFailed: [[2], [2]] does not divide [[1], [1, 0], []]
1299 """
1300 q, r = dmp_pdiv(f, g, u, K)
1302 if dmp_zero_p(r, u):
1303 return q
1304 else:
1305 raise ExactQuotientFailed(f, g)
1308def dup_rr_div(f, g, K):
1309 """
1310 Univariate division with remainder over a ring.
1312 Examples
1313 ========
1315 >>> from sympy.polys import ring, ZZ
1316 >>> R, x = ring("x", ZZ)
1318 >>> R.dup_rr_div(x**2 + 1, 2*x - 4)
1319 (0, x**2 + 1)
1321 """
1322 df = dup_degree(f)
1323 dg = dup_degree(g)
1325 q, r, dr = [], f, df
1327 if not g:
1328 raise ZeroDivisionError("polynomial division")
1329 elif df < dg:
1330 return q, r
1332 lc_g = dup_LC(g, K)
1334 while True:
1335 lc_r = dup_LC(r, K)
1337 if lc_r % lc_g:
1338 break
1340 c = K.exquo(lc_r, lc_g)
1341 j = dr - dg
1343 q = dup_add_term(q, c, j, K)
1344 h = dup_mul_term(g, c, j, K)
1345 r = dup_sub(r, h, K)
1347 _dr, dr = dr, dup_degree(r)
1349 if dr < dg:
1350 break
1351 elif not (dr < _dr):
1352 raise PolynomialDivisionFailed(f, g, K)
1354 return q, r
1357def dmp_rr_div(f, g, u, K):
1358 """
1359 Multivariate division with remainder over a ring.
1361 Examples
1362 ========
1364 >>> from sympy.polys import ring, ZZ
1365 >>> R, x,y = ring("x,y", ZZ)
1367 >>> R.dmp_rr_div(x**2 + x*y, 2*x + 2)
1368 (0, x**2 + x*y)
1370 """
1371 if not u:
1372 return dup_rr_div(f, g, K)
1374 df = dmp_degree(f, u)
1375 dg = dmp_degree(g, u)
1377 if dg < 0:
1378 raise ZeroDivisionError("polynomial division")
1380 q, r, dr = dmp_zero(u), f, df
1382 if df < dg:
1383 return q, r
1385 lc_g, v = dmp_LC(g, K), u - 1
1387 while True:
1388 lc_r = dmp_LC(r, K)
1389 c, R = dmp_rr_div(lc_r, lc_g, v, K)
1391 if not dmp_zero_p(R, v):
1392 break
1394 j = dr - dg
1396 q = dmp_add_term(q, c, j, u, K)
1397 h = dmp_mul_term(g, c, j, u, K)
1398 r = dmp_sub(r, h, u, K)
1400 _dr, dr = dr, dmp_degree(r, u)
1402 if dr < dg:
1403 break
1404 elif not (dr < _dr):
1405 raise PolynomialDivisionFailed(f, g, K)
1407 return q, r
1410def dup_ff_div(f, g, K):
1411 """
1412 Polynomial division with remainder over a field.
1414 Examples
1415 ========
1417 >>> from sympy.polys import ring, QQ
1418 >>> R, x = ring("x", QQ)
1420 >>> R.dup_ff_div(x**2 + 1, 2*x - 4)
1421 (1/2*x + 1, 5)
1423 """
1424 df = dup_degree(f)
1425 dg = dup_degree(g)
1427 q, r, dr = [], f, df
1429 if not g:
1430 raise ZeroDivisionError("polynomial division")
1431 elif df < dg:
1432 return q, r
1434 lc_g = dup_LC(g, K)
1436 while True:
1437 lc_r = dup_LC(r, K)
1439 c = K.exquo(lc_r, lc_g)
1440 j = dr - dg
1442 q = dup_add_term(q, c, j, K)
1443 h = dup_mul_term(g, c, j, K)
1444 r = dup_sub(r, h, K)
1446 _dr, dr = dr, dup_degree(r)
1448 if dr < dg:
1449 break
1450 elif dr == _dr and not K.is_Exact:
1451 # remove leading term created by rounding error
1452 r = dup_strip(r[1:])
1453 dr = dup_degree(r)
1454 if dr < dg:
1455 break
1456 elif not (dr < _dr):
1457 raise PolynomialDivisionFailed(f, g, K)
1459 return q, r
1462def dmp_ff_div(f, g, u, K):
1463 """
1464 Polynomial division with remainder over a field.
1466 Examples
1467 ========
1469 >>> from sympy.polys import ring, QQ
1470 >>> R, x,y = ring("x,y", QQ)
1472 >>> R.dmp_ff_div(x**2 + x*y, 2*x + 2)
1473 (1/2*x + 1/2*y - 1/2, -y + 1)
1475 """
1476 if not u:
1477 return dup_ff_div(f, g, K)
1479 df = dmp_degree(f, u)
1480 dg = dmp_degree(g, u)
1482 if dg < 0:
1483 raise ZeroDivisionError("polynomial division")
1485 q, r, dr = dmp_zero(u), f, df
1487 if df < dg:
1488 return q, r
1490 lc_g, v = dmp_LC(g, K), u - 1
1492 while True:
1493 lc_r = dmp_LC(r, K)
1494 c, R = dmp_ff_div(lc_r, lc_g, v, K)
1496 if not dmp_zero_p(R, v):
1497 break
1499 j = dr - dg
1501 q = dmp_add_term(q, c, j, u, K)
1502 h = dmp_mul_term(g, c, j, u, K)
1503 r = dmp_sub(r, h, u, K)
1505 _dr, dr = dr, dmp_degree(r, u)
1507 if dr < dg:
1508 break
1509 elif not (dr < _dr):
1510 raise PolynomialDivisionFailed(f, g, K)
1512 return q, r
1515def dup_div(f, g, K):
1516 """
1517 Polynomial division with remainder in ``K[x]``.
1519 Examples
1520 ========
1522 >>> from sympy.polys import ring, ZZ, QQ
1524 >>> R, x = ring("x", ZZ)
1525 >>> R.dup_div(x**2 + 1, 2*x - 4)
1526 (0, x**2 + 1)
1528 >>> R, x = ring("x", QQ)
1529 >>> R.dup_div(x**2 + 1, 2*x - 4)
1530 (1/2*x + 1, 5)
1532 """
1533 if K.is_Field:
1534 return dup_ff_div(f, g, K)
1535 else:
1536 return dup_rr_div(f, g, K)
1539def dup_rem(f, g, K):
1540 """
1541 Returns polynomial remainder in ``K[x]``.
1543 Examples
1544 ========
1546 >>> from sympy.polys import ring, ZZ, QQ
1548 >>> R, x = ring("x", ZZ)
1549 >>> R.dup_rem(x**2 + 1, 2*x - 4)
1550 x**2 + 1
1552 >>> R, x = ring("x", QQ)
1553 >>> R.dup_rem(x**2 + 1, 2*x - 4)
1554 5
1556 """
1557 return dup_div(f, g, K)[1]
1560def dup_quo(f, g, K):
1561 """
1562 Returns exact polynomial quotient in ``K[x]``.
1564 Examples
1565 ========
1567 >>> from sympy.polys import ring, ZZ, QQ
1569 >>> R, x = ring("x", ZZ)
1570 >>> R.dup_quo(x**2 + 1, 2*x - 4)
1571 0
1573 >>> R, x = ring("x", QQ)
1574 >>> R.dup_quo(x**2 + 1, 2*x - 4)
1575 1/2*x + 1
1577 """
1578 return dup_div(f, g, K)[0]
1581def dup_exquo(f, g, K):
1582 """
1583 Returns polynomial quotient in ``K[x]``.
1585 Examples
1586 ========
1588 >>> from sympy.polys import ring, ZZ
1589 >>> R, x = ring("x", ZZ)
1591 >>> R.dup_exquo(x**2 - 1, x - 1)
1592 x + 1
1594 >>> R.dup_exquo(x**2 + 1, 2*x - 4)
1595 Traceback (most recent call last):
1596 ...
1597 ExactQuotientFailed: [2, -4] does not divide [1, 0, 1]
1599 """
1600 q, r = dup_div(f, g, K)
1602 if not r:
1603 return q
1604 else:
1605 raise ExactQuotientFailed(f, g)
1608def dmp_div(f, g, u, K):
1609 """
1610 Polynomial division with remainder in ``K[X]``.
1612 Examples
1613 ========
1615 >>> from sympy.polys import ring, ZZ, QQ
1617 >>> R, x,y = ring("x,y", ZZ)
1618 >>> R.dmp_div(x**2 + x*y, 2*x + 2)
1619 (0, x**2 + x*y)
1621 >>> R, x,y = ring("x,y", QQ)
1622 >>> R.dmp_div(x**2 + x*y, 2*x + 2)
1623 (1/2*x + 1/2*y - 1/2, -y + 1)
1625 """
1626 if K.is_Field:
1627 return dmp_ff_div(f, g, u, K)
1628 else:
1629 return dmp_rr_div(f, g, u, K)
1632def dmp_rem(f, g, u, K):
1633 """
1634 Returns polynomial remainder in ``K[X]``.
1636 Examples
1637 ========
1639 >>> from sympy.polys import ring, ZZ, QQ
1641 >>> R, x,y = ring("x,y", ZZ)
1642 >>> R.dmp_rem(x**2 + x*y, 2*x + 2)
1643 x**2 + x*y
1645 >>> R, x,y = ring("x,y", QQ)
1646 >>> R.dmp_rem(x**2 + x*y, 2*x + 2)
1647 -y + 1
1649 """
1650 return dmp_div(f, g, u, K)[1]
1653def dmp_quo(f, g, u, K):
1654 """
1655 Returns exact polynomial quotient in ``K[X]``.
1657 Examples
1658 ========
1660 >>> from sympy.polys import ring, ZZ, QQ
1662 >>> R, x,y = ring("x,y", ZZ)
1663 >>> R.dmp_quo(x**2 + x*y, 2*x + 2)
1664 0
1666 >>> R, x,y = ring("x,y", QQ)
1667 >>> R.dmp_quo(x**2 + x*y, 2*x + 2)
1668 1/2*x + 1/2*y - 1/2
1670 """
1671 return dmp_div(f, g, u, K)[0]
1674def dmp_exquo(f, g, u, K):
1675 """
1676 Returns polynomial quotient in ``K[X]``.
1678 Examples
1679 ========
1681 >>> from sympy.polys import ring, ZZ
1682 >>> R, x,y = ring("x,y", ZZ)
1684 >>> f = x**2 + x*y
1685 >>> g = x + y
1686 >>> h = 2*x + 2
1688 >>> R.dmp_exquo(f, g)
1689 x
1691 >>> R.dmp_exquo(f, h)
1692 Traceback (most recent call last):
1693 ...
1694 ExactQuotientFailed: [[2], [2]] does not divide [[1], [1, 0], []]
1696 """
1697 q, r = dmp_div(f, g, u, K)
1699 if dmp_zero_p(r, u):
1700 return q
1701 else:
1702 raise ExactQuotientFailed(f, g)
1705def dup_max_norm(f, K):
1706 """
1707 Returns maximum norm of a polynomial in ``K[x]``.
1709 Examples
1710 ========
1712 >>> from sympy.polys import ring, ZZ
1713 >>> R, x = ring("x", ZZ)
1715 >>> R.dup_max_norm(-x**2 + 2*x - 3)
1716 3
1718 """
1719 if not f:
1720 return K.zero
1721 else:
1722 return max(dup_abs(f, K))
1725def dmp_max_norm(f, u, K):
1726 """
1727 Returns maximum norm of a polynomial in ``K[X]``.
1729 Examples
1730 ========
1732 >>> from sympy.polys import ring, ZZ
1733 >>> R, x,y = ring("x,y", ZZ)
1735 >>> R.dmp_max_norm(2*x*y - x - 3)
1736 3
1738 """
1739 if not u:
1740 return dup_max_norm(f, K)
1742 v = u - 1
1744 return max([ dmp_max_norm(c, v, K) for c in f ])
1747def dup_l1_norm(f, K):
1748 """
1749 Returns l1 norm of a polynomial in ``K[x]``.
1751 Examples
1752 ========
1754 >>> from sympy.polys import ring, ZZ
1755 >>> R, x = ring("x", ZZ)
1757 >>> R.dup_l1_norm(2*x**3 - 3*x**2 + 1)
1758 6
1760 """
1761 if not f:
1762 return K.zero
1763 else:
1764 return sum(dup_abs(f, K))
1767def dmp_l1_norm(f, u, K):
1768 """
1769 Returns l1 norm of a polynomial in ``K[X]``.
1771 Examples
1772 ========
1774 >>> from sympy.polys import ring, ZZ
1775 >>> R, x,y = ring("x,y", ZZ)
1777 >>> R.dmp_l1_norm(2*x*y - x - 3)
1778 6
1780 """
1781 if not u:
1782 return dup_l1_norm(f, K)
1784 v = u - 1
1786 return sum([ dmp_l1_norm(c, v, K) for c in f ])
1789def dup_l2_norm_squared(f, K):
1790 """
1791 Returns squared l2 norm of a polynomial in ``K[x]``.
1793 Examples
1794 ========
1796 >>> from sympy.polys import ring, ZZ
1797 >>> R, x = ring("x", ZZ)
1799 >>> R.dup_l2_norm_squared(2*x**3 - 3*x**2 + 1)
1800 14
1802 """
1803 return sum([coeff**2 for coeff in f], K.zero)
1806def dmp_l2_norm_squared(f, u, K):
1807 """
1808 Returns squared l2 norm of a polynomial in ``K[X]``.
1810 Examples
1811 ========
1813 >>> from sympy.polys import ring, ZZ
1814 >>> R, x,y = ring("x,y", ZZ)
1816 >>> R.dmp_l2_norm_squared(2*x*y - x - 3)
1817 14
1819 """
1820 if not u:
1821 return dup_l2_norm_squared(f, K)
1823 v = u - 1
1825 return sum([ dmp_l2_norm_squared(c, v, K) for c in f ])
1828def dup_expand(polys, K):
1829 """
1830 Multiply together several polynomials in ``K[x]``.
1832 Examples
1833 ========
1835 >>> from sympy.polys import ring, ZZ
1836 >>> R, x = ring("x", ZZ)
1838 >>> R.dup_expand([x**2 - 1, x, 2])
1839 2*x**3 - 2*x
1841 """
1842 if not polys:
1843 return [K.one]
1845 f = polys[0]
1847 for g in polys[1:]:
1848 f = dup_mul(f, g, K)
1850 return f
1853def dmp_expand(polys, u, K):
1854 """
1855 Multiply together several polynomials in ``K[X]``.
1857 Examples
1858 ========
1860 >>> from sympy.polys import ring, ZZ
1861 >>> R, x,y = ring("x,y", ZZ)
1863 >>> R.dmp_expand([x**2 + y**2, x + 1])
1864 x**3 + x**2 + x*y**2 + y**2
1866 """
1867 if not polys:
1868 return dmp_one(u, K)
1870 f = polys[0]
1872 for g in polys[1:]:
1873 f = dmp_mul(f, g, u, K)
1875 return f