Exemple #1
0
    def check(self, f):
        # reciprocal version of Dimitrov's first comment in https://mathoverflow.net/questions/214962/criteria-for-irreducibility-using-the-location-of-complex-roots
        import mpmath
        import sympy

        const_coeff = f.TC()
        if const_coeff == 0:
            return REDUCIBLE, None

        # constant coeff needs to be in form +-p^d
        primes = sympy.ntheory.factorint(abs(const_coeff))
        if len(primes) != 1:
            return UNKNOWN, None

        # extract p
        p = next(iter(primes.keys()))

        # linear coefficients must not be divisible by p
        a1 = get_coeff(f, 1)
        if a1 % p == 0:
            return UNKNOWN, None

        if self.max_p and abs(const_coeff) >= self.max_p:
            return UNKNOWN, None

        # check if there are roots inside as well as outside of unit circle
        try:
            all = mpmath.polyroots(f.all_coeffs(), maxsteps=100)
            inside_unit_circle = 0
            outside_unit_circle = 0
            on_unit_circle = 0
            for root in all:
                root_size = abs(root)
                if root_size == 1:
                    on_unit_circle += 1
                elif root_size < 1:
                    inside_unit_circle += 1
                else:
                    outside_unit_circle += 1

            if (inside_unit_circle + on_unit_circle == 0):
                return IRREDUCIBLE, {
                    "inside/on": inside_unit_circle + on_unit_circle,
                    "outside": outside_unit_circle,
                    "p": p
                }
        except Exception as e:
            # could not get complex roots, too bad
            pass

        return UNKNOWN, None
Exemple #2
0
 def check(self, f):
     const_coeff = f.TC()
     if const_coeff == 0:
         return REDUCIBLE, None
     lead_coeff = f.LC()
     if lead_coeff != 1:
         return UNKNOWN, None
     a_nm1 = abs(get_coeff(f, f.degree() - 1))
     s = 1
     for exp, coeff in poly_non_zero_exps(f):
         if exp < f.degree() - 1:
             s += abs(coeff)
     if a_nm1 > s:
         return IRREDUCIBLE, None
     return UNKNOWN, None
Exemple #3
0
    def check(self, f):
        # http://www.math.uconn.edu/~kconrad/blurbs/gradnumthy/schurtheorem.pdf
        # Theorem 1, multiplied to get Z[x]
        n = f.degree()
        lead_coeff = f.LC()
        if abs(lead_coeff) != 1:
            return UNKNOWN, None
        fact = n
        for exp in reversed(range(1, n)):
            coeff = get_coeff(f, exp)
            if coeff % fact != 0:
                return UNKNOWN, None
            fact *= exp
        # fact now contains n!
        const_coeff = f.TC()
        if const_coeff != fact:
            return UNKNOWN, None

        return IRREDUCIBLE, None
    def check(self, f):
        # see https://www.lehigh.edu/~shw2/preprints/eisenstein.pdf,
        # and https://math.stackexchange.com/questions/3589657/prove-polynomial-is-irreducible/3590300#3590300
        const_coeff = f.TC()
        if const_coeff == 0:
            return REDUCIBLE, None
        linear_coeff = get_coeff(f, 1)
        if linear_coeff == 0:
            return UNKNOWN, None
        primes = sympy.ntheory.factorint(linear_coeff)
        for p in primes:
            power = primes[p]
            if power == 1:
                # good candidate, it must not divide leading term
                lead_coeff = f.LC()
                if lead_coeff % p == 0:
                    # bad luck
                    continue
                # it must divide or other terms
                for exp, coeff in poly_non_zero_exps(f):
                    if exp != f.degree():
                        if coeff % p != 0:
                            # bad luck...
                            return UNKNOWN, None

                # finally the polynomial must not have rational roots
                numerators = sympy.ntheory.factorint(const_coeff)
                denominators = sympy.ntheory.factorint(lead_coeff)
                for num in numerators:
                    for denom in denominators:
                        for sign in (-1, 1):
                            if f.eval(sympy.Rational(sign * num, denom)) == 0:
                                # rational root...
                                return UNKNOWN, None

                return IRREDUCIBLE, {"p": p}
        return UNKNOWN, None