Skip to content

Commit

Permalink
Merge pull request #26515 from oscarbenjamin/pr_dmp_ext_factor
Browse files Browse the repository at this point in the history
fix(polys): fix multi factorisation over QQ<a>
  • Loading branch information
oscarbenjamin committed May 8, 2024
2 parents 999fd9b + 82c1557 commit 2658461
Show file tree
Hide file tree
Showing 15 changed files with 704 additions and 78 deletions.
35 changes: 35 additions & 0 deletions doc/src/modules/polys/internals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,9 @@ Polynomial factorization in characteristic zero:

.. currentmodule:: sympy.polys.factortools

.. autofunction:: dup_trial_division
.. autofunction:: dmp_trial_division
.. autofunction:: dup_zz_mignotte_bound
.. autofunction:: dmp_zz_mignotte_bound
.. autofunction:: dup_zz_hensel_step
.. autofunction:: dup_zz_hensel_lift
Expand All @@ -559,16 +561,49 @@ Polynomial factorization in characteristic zero:
.. autofunction:: dmp_zz_wang_non_divisors
.. autofunction:: dmp_zz_wang_test_points
.. autofunction:: dmp_zz_wang_lead_coeffs
.. autofunction:: dup_zz_diophantine
.. autofunction:: dmp_zz_diophantine
.. autofunction:: dmp_zz_wang_hensel_lifting
.. autofunction:: dmp_zz_wang
.. autofunction:: dmp_zz_factor
.. autofunction:: dup_qq_i_factor
.. autofunction:: dup_zz_i_factor
.. autofunction:: dmp_qq_i_factor
.. autofunction:: dmp_zz_i_factor
.. autofunction:: dup_ext_factor
.. autofunction:: dmp_ext_factor
.. autofunction:: dup_gf_factor
.. autofunction:: dmp_gf_factor
.. autofunction:: dup_factor_list
.. autofunction:: dup_factor_list_include
.. autofunction:: dmp_factor_list
.. autofunction:: dmp_factor_list_include
.. autofunction:: dup_irreducible_p
.. autofunction:: dmp_irreducible_p

Square-free factorization:

.. currentmodule:: sympy.polys.sqfreetools

.. autofunction:: dup_sqf_p
.. autofunction:: dmp_sqf_p
.. autofunction:: dup_sqf_norm
.. autofunction:: dmp_sqf_norm
.. autofunction:: dmp_norm
.. autofunction:: dup_gf_sqf_part
.. autofunction:: dmp_gf_sqf_part
.. autofunction:: dup_sqf_part
.. autofunction:: dmp_sqf_part
.. autofunction:: dup_gf_sqf_list
.. autofunction:: dmp_gf_sqf_list
.. autofunction:: dup_sqf_list
.. autofunction:: dup_sqf_list_include
.. autofunction:: dmp_sqf_list
.. autofunction:: dmp_sqf_list_include
.. autofunction:: dup_gff_list
.. autofunction:: dmp_gff_list


Groebner basis algorithms
*************************

Expand Down
14 changes: 13 additions & 1 deletion doc/src/modules/polys/literature.rst
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,16 @@ a theoretical foundation for implementing polynomials manipulation module.
https://isc.tamu.edu/resources/preprints/1996/1996-02.pdf
.. [Cohen93] Henri Cohen. "A Course in Computational Algebraic Number Theory",
Springer, 1993.
Springer, 1993.
.. [Trager76] Barry M. Trager. "Algebraic factoriing and rational function
integration", Proceedings of SYMSAC 1976, pp. 219-226, ACM, 1976.
https://dl.acm.org/doi/abs/10.1145/800205.806338
.. [Yun76] David Y.Y. Yun. "On square-free decomposition algorithms",
Proceedings of SYMSAC 1976, pp. 219-226, ACM, 1976.
https://dl.acm.org/doi/10.1145/800205.806320
.. [Abbott13] John Abbott. "Bounds on factors in Z[x]".
Journal of Symbolic Computation 50 (2013), pp. 532-563
https://doi.org/10.1016/j.jsc.2012.09.004
14 changes: 11 additions & 3 deletions sympy/polys/compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
from sympy.polys.densetools import dup_mirror
from sympy.polys.densetools import dup_scale
from sympy.polys.densetools import dup_shift
from sympy.polys.densetools import dmp_shift
from sympy.polys.densetools import dup_transform
from sympy.polys.densetools import dup_compose
from sympy.polys.densetools import dmp_compose
Expand Down Expand Up @@ -209,9 +210,10 @@
from sympy.polys.rootisolation import dup_isolate_all_roots

from sympy.polys.sqfreetools import (
dup_sqf_p, dmp_sqf_p, dup_sqf_norm, dmp_sqf_norm, dup_gf_sqf_part, dmp_gf_sqf_part,
dup_sqf_part, dmp_sqf_part, dup_gf_sqf_list, dmp_gf_sqf_list, dup_sqf_list,
dup_sqf_list_include, dmp_sqf_list, dmp_sqf_list_include, dup_gff_list, dmp_gff_list)
dup_sqf_p, dmp_sqf_p, dmp_norm, dup_sqf_norm, dmp_sqf_norm,
dup_gf_sqf_part, dmp_gf_sqf_part, dup_sqf_part, dmp_sqf_part,
dup_gf_sqf_list, dmp_gf_sqf_list, dup_sqf_list, dup_sqf_list_include,
dmp_sqf_list, dmp_sqf_list_include, dup_gff_list, dmp_gff_list)

from sympy.polys.galoistools import (
gf_degree, gf_LC, gf_TC, gf_strip, gf_from_dict,
Expand Down Expand Up @@ -515,6 +517,8 @@ def dup_scale(self, f, a):
return self.from_dense(dup_scale(self.to_dense(f), a, self.domain))
def dup_shift(self, f, a):
return self.from_dense(dup_shift(self.to_dense(f), a, self.domain))
def dmp_shift(self, f, a):
return self.from_dense(dmp_shift(self.to_dense(f), a, self.ngens-1, self.domain))
def dup_transform(self, f, p, q):
return self.from_dense(dup_transform(self.to_dense(f), self.to_dense(p), self.to_dense(q), self.domain))

Expand Down Expand Up @@ -877,6 +881,10 @@ def dup_sqf_p(self, f):
def dmp_sqf_p(self, f):
return dmp_sqf_p(self.to_dense(f), self.ngens-1, self.domain)

def dmp_norm(self, f):
n = dmp_norm(self.to_dense(f), self.ngens-1, self.domain)
return self.to_ground().from_dense(n)

def dup_sqf_norm(self, f):
s, F, R = dup_sqf_norm(self.to_dense(f), self.domain)
return (s, self.from_dense(F), self.to_ground().from_dense(R))
Expand Down
45 changes: 44 additions & 1 deletion sympy/polys/densetools.py
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ def dmp_ground_extract(f, g, u, K):

def dup_real_imag(f, K):
"""
Return bivariate polynomials ``f1`` and ``f2``, such that ``f = f1 + f2*I``.
Find ``f1`` and ``f2``, such that ``f(x+I*y) = f1(x,y) + f2(x,y)*I``.
Examples
========
Expand All @@ -793,6 +793,11 @@ def dup_real_imag(f, K):
>>> R.dup_real_imag(x**3 + x**2 + x + 1)
(x**3 + x**2 - 3*x*y**2 + x - y**2 + 1, 3*x**2*y + 2*x*y - y**3 + y)
>>> from sympy.abc import x, y, z
>>> from sympy import I
>>> (z**3 + z**2 + z + 1).subs(z, x+I*y).expand().collect(I)
x**3 + x**2 - 3*x*y**2 + x - y**2 + I*(3*x**2*y + 2*x*y - y**3 + y) + 1
"""
if not K.is_ZZ and not K.is_QQ:
raise DomainError("computing real and imaginary parts is not supported over %s" % K)
Expand Down Expand Up @@ -894,6 +899,44 @@ def dup_shift(f, a, K):
return f


def dmp_shift(f, a, u, K):
"""
Evaluate efficiently Taylor shift ``f(X + A)`` in ``K[X]``.
Examples
========
>>> from sympy import symbols, ring, ZZ
>>> x, y = symbols('x y')
>>> R, _, _ = ring([x, y], ZZ)
>>> p = x**2*y + 2*x*y + 3*x + 4*y + 5
>>> R.dmp_shift(R(p), [ZZ(1), ZZ(2)])
x**2*y + 2*x**2 + 4*x*y + 11*x + 7*y + 22
>>> p.subs({x: x + 1, y: y + 2}).expand()
x**2*y + 2*x**2 + 4*x*y + 11*x + 7*y + 22
"""
if not u:
return dup_shift(f, a[0], K)

if dmp_zero_p(f, u):
return f

a0, a1 = a[0], a[1:]

f = [ dmp_shift(c, a1, u-1, K) for c in f ]
n = len(f) - 1

for i in range(n, 0, -1):
for j in range(0, i):
afj = dmp_mul_ground(f[j], a0, u-1, K)
f[j + 1] = dmp_add(f[j + 1], afj, u-1, K)

return f


def dup_transform(f, p, q, K):
"""
Evaluate functional transformation ``q**n * f(p/q)`` in ``K[x]``.
Expand Down

0 comments on commit 2658461

Please sign in to comment.