Example #1
0
def dup_ext_factor(f, K):
    """Factor polynomials over algebraic number fields. """
    n, lc = dup_degree(f), dup_LC(f, K)

    f = dup_monic(f, K)

    if n <= 0:
        return lc, []
    if n == 1:
        return lc, [(f, 1)]

    f, F = dup_sqf_part(f, K), f
    s, g, r = dup_sqf_norm(f, K)

    factors = dup_factor_list(r, K.dom, include=True)

    if len(factors) == 1:
        return lc, [(f, n // dup_degree(f))]

    H = s * K.unit

    for i, (factor, _) in enumerate(factors):
        h = dup_convert(factor, K.dom, K)
        h, _, g = dup_inner_gcd(h, g, K)
        h = dup_taylor(h, H, K)
        factors[i] = h

    factors = dup_trial_division(F, factors, K)

    return lc, factors
Example #2
0
def dup_ext_factor(f, K):
    """Factor polynomials over algebraic number fields. """
    n, lc = dup_degree(f), dup_LC(f, K)

    f = dup_monic(f, K)

    if n <= 0:
        return lc, []
    if n == 1:
        return lc, [(f, 1)]

    f, F = dup_sqf_part(f, K), f
    s, g, r = dup_sqf_norm(f, K)

    factors = dup_factor_list(r, K.dom, include=True)

    if len(factors) == 1:
        return lc, [(f, n//dup_degree(f))]

    H = s*K.unit

    for i, (factor, _) in enumerate(factors):
        h = dup_convert(factor, K.dom, K)
        h, _, g = dup_inner_gcd(h, g, K)
        h = dup_taylor(h, H, K)
        factors[i] = h

    factors = dup_trial_division(F, factors, K)

    return lc, factors
Example #3
0
def dup_zz_factor(f, K, **args):
    """Factor (non square-free) polynomials in `Z[x]`.

       Given a univariate polynomial `f` in `Z[x]` computes its complete
       factorization `f_1, ..., f_n` into irreducibles over integers::

                   f = content(f) f_1**k_1 ... f_n**k_n

       The factorization is computed by reducing the input polynomial
       into a primitive square-free polynomial and factoring it using
       Zassenhaus algorithm. Trial division is used to recover the
       multiplicities of factors.

       The result is returned as a tuple consisting of::

                 (content(f), [(f_1, k_1), ..., (f_n, k_n))

       Consider polynomial `f = 2*x**4 - 2`::

           >>> from sympy.polys.factortools import dup_zz_factor
           >>> from sympy.polys.algebratools import ZZ

           >>> dup_zz_factor([2, 0, 0, 0, -2], ZZ)
           (2, [([1, -1], 1), ([1, 1], 1), ([1, 0, 1], 1)])

       In result we got the following factorization::

                    f = 2 (x - 1) (x + 1) (x**2 + 1)

       Note that this is a complete factorization over integers,
       however over Gaussian integers we can factor the last term.

       By default, polynomials `x**n - 1` and `x**n + 1` are factored
       using cyclotomic decomposition to speedup computations. To
       disable this behaviour set cyclotomic=False.

       References
       ==========

       .. [Gathen99] J. von zur Gathen, J. Gerhard, Modern Computer Algebra,
           First Edition, Cambridge University Press, 1999, pp. 427
    """
    cont, g = dup_primitive(f, K)

    n = dup_degree(g)

    if dup_LC(g, K) < 0:
        cont, g = -cont, dup_neg(g, K)

    if n <= 0:
        return cont, []

    if n == 1 or dup_zz_irreducible_p(g, K):
        return cont, [(g, 1)]

    g = dup_sqf_part(g, K)
    H, factors = None, []

    if args.get('cyclotomic', True):
        H = dup_zz_cyclotomic_factor(g, K)

    if H is None:
        H = dup_zz_zassenhaus(g, K)

    for h in H:
        k = 0

        while True:
            q, r = dup_div(f, h, K)

            if not r:
                f, k = q, k + 1
            else:
                break

        factors.append((h, k))

    return cont, _sort_factors(factors)
Example #4
0
def dup_zz_factor(f, K, **args):
    """Factor (non square-free) polynomials in `Z[x]`.

       Given a univariate polynomial `f` in `Z[x]` computes its complete
       factorization `f_1, ..., f_n` into irreducibles over integers::

                   f = content(f) f_1**k_1 ... f_n**k_n

       The factorization is computed by reducing the input polynomial
       into a primitive square-free polynomial and factoring it using
       Zassenhaus algorithm. Trial division is used to recover the
       multiplicities of factors.

       The result is returned as a tuple consisting of::

                 (content(f), [(f_1, k_1), ..., (f_n, k_n))

       Consider polynomial `f = 2*x**4 - 2`::

           >>> from sympy.polys.factortools import dup_zz_factor
           >>> from sympy.polys.algebratools import ZZ

           >>> dup_zz_factor([2, 0, 0, 0, -2], ZZ)
           (2, [([1, -1], 1), ([1, 1], 1), ([1, 0, 1], 1)])

       In result we got the following factorization::

                    f = 2 (x - 1) (x + 1) (x**2 + 1)

       Note that this is a complete factorization over integers,
       however over Gaussian integers we can factor the last term.

       By default, polynomials `x**n - 1` and `x**n + 1` are factored
       using cyclotomic decomposition to speedup computations. To
       disable this behaviour set cyclotomic=False.

       References
       ==========

       .. [Gathen99] J. von zur Gathen, J. Gerhard, Modern Computer Algebra,
           First Edition, Cambridge University Press, 1999, pp. 427
    """
    cont, g = dup_primitive(f, K)

    n = dup_degree(g)

    if dup_LC(g, K) < 0:
        cont, g = -cont, dup_neg(g, K)

    if n <= 0:
        return cont, []

    if n == 1 or dup_zz_irreducible_p(g, K):
        return cont, [(g, 1)]

    g = dup_sqf_part(g, K)
    H, factors = None, []

    if args.get('cyclotomic', True):
        H = dup_zz_cyclotomic_factor(g, K)

    if H is None:
        H = dup_zz_zassenhaus(g, K)

    for h in H:
        k = 0

        while True:
            q, r = dup_div(f, h, K)

            if not r:
                f, k = q, k+1
            else:
                break

        factors.append((h, k))

    return cont, _sort_factors(factors)