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
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
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