def symmetric_poly(n, *gens, **args): """Generates symmetric polynomial of order `n`. """ gens = _analyze_gens(gens) if n < 0 or n > len(gens) or not gens: raise ValueError("can't generate symmetric polynomial of order %s for %s" % (n, gens)) elif not n: poly = S.One else: poly = Add(*[ Mul(*s) for s in subsets(gens, int(n)) ]) if not args.get('polys', False): return poly else: return Poly(poly, *gens)
def symmetric_poly(n, *gens, **args): """Generates symmetric polynomial of order `n`. Returns a Poly object when ``polys=True``, otherwise (default) returns an expression. """ # TODO: use an explicit keyword argument when Python 2 support is dropped gens = _analyze_gens(gens) if n < 0 or n > len(gens) or not gens: raise ValueError("can't generate symmetric polynomial of order %s for %s" % (n, gens)) elif not n: poly = S.One else: poly = Add(*[Mul(*s) for s in subsets(gens, int(n))]) if not args.get('polys', False): return poly else: return Poly(poly, *gens)
def symmetric_poly(n, *gens, **args): """Generates symmetric polynomial of order `n`. Returns a Poly object when ``polys=True``, otherwise (default) returns an expression. """ # TODO: use an explicit keyword argument when Python 2 support is dropped gens = _analyze_gens(gens) if n < 0 or n > len(gens) or not gens: raise ValueError("can't generate symmetric polynomial of order %s for %s" % (n, gens)) elif not n: poly = S.One else: poly = Add(*[ Mul(*s) for s in subsets(gens, int(n)) ]) if not args.get('polys', False): return poly else: return Poly(poly, *gens)
def dup_zz_zassenhaus(f, K): """Factor primitive square-free polynomials in `Z[x]`. """ n = dup_degree(f) if n == 1: return [f] A = dup_max_norm(f, K) b = dup_LC(f, K) B = int(abs(K.sqrt(K(n + 1)) * 2**n * A * b)) C = int((n + 1)**(2 * n) * A**(2 * n - 1)) gamma = int(_ceil(2 * _log(C, 2))) bound = int(2 * gamma * _log(gamma)) for p in xrange(3, bound + 1): if not isprime(p) or b % p == 0: continue p = K.convert(p) F = gf_from_int_poly(f, p) if gf_sqf_p(F, p, K): break l = int(_ceil(_log(2 * B + 1, p))) modular = [] for ff in gf_factor_sqf(F, p, K)[1]: modular.append(gf_to_int_poly(ff, p)) g = dup_zz_hensel_lift(p, f, modular, l, K) T = set(range(len(g))) factors, s = [], 1 while 2 * s <= len(T): for S in subsets(T, s): G, H = [b], [b] S = set(S) for i in S: G = dup_mul(G, g[i], K) for i in T - S: H = dup_mul(H, g[i], K) G = dup_trunc(G, p**l, K) H = dup_trunc(H, p**l, K) G_norm = dup_l1_norm(G, K) H_norm = dup_l1_norm(H, K) if G_norm * H_norm <= B: T = T - S G = dup_primitive(G, K)[1] f = dup_primitive(H, K)[1] factors.append(G) b = dup_LC(f, K) break else: s += 1 return factors + [f]
def _eval_powerset(self): return self.func(*[self.func(*s) for s in subsets(self.args)])
def dup_zz_zassenhaus(f, K): """Factor primitive square-free polynomials in `Z[x]`. """ n = dup_degree(f) if n == 1: return [f] fc = f[-1] A = dup_max_norm(f, K) b = dup_LC(f, K) B = int(abs(K.sqrt(K(n + 1)) * 2**n * A * b)) C = int((n + 1)**(2 * n) * A**(2 * n - 1)) gamma = int(_ceil(2 * _log(C, 2))) bound = int(2 * gamma * _log(gamma)) a = [] # choose a prime number `p` such that `f` be square free in Z_p # if there are many factors in Z_p, choose among a few different `p` # the one with fewer factors for px in xrange(3, bound + 1): if not isprime(px) or b % px == 0: continue px = K.convert(px) F = gf_from_int_poly(f, px) if not gf_sqf_p(F, px, K): continue fsqfx = gf_factor_sqf(F, px, K)[1] a.append((px, fsqfx)) if len(fsqfx) < 15 or len(a) > 4: break p, fsqf = min(a, key=lambda x: len(x[1])) l = int(_ceil(_log(2 * B + 1, p))) modular = [gf_to_int_poly(ff, p) for ff in fsqf] g = dup_zz_hensel_lift(p, f, modular, l, K) sorted_T = range(len(g)) T = set(sorted_T) factors, s = [], 1 pl = p**l while 2 * s <= len(T): for S in subsets(sorted_T, s): # lift the constant coefficient of the product `G` of the factors # in the subset `S`; if it is does not divide `fc`, `G` does # not divide the input polynomial if b == 1: q = 1 for i in S: q = q * g[i][-1] q = q % pl if not _test_pl(fc, q, pl): continue else: G = [b] for i in S: G = dup_mul(G, g[i], K) G = dup_trunc(G, pl, K) G1 = dup_primitive(G, K)[1] q = G1[-1] if q and fc % q != 0: continue H = [b] S = set(S) T_S = T - S if b == 1: G = [b] for i in S: G = dup_mul(G, g[i], K) G = dup_trunc(G, pl, K) for i in T_S: H = dup_mul(H, g[i], K) H = dup_trunc(H, pl, K) G_norm = dup_l1_norm(G, K) H_norm = dup_l1_norm(H, K) if G_norm * H_norm <= B: T = T_S sorted_T = [i for i in sorted_T if i not in S] G = dup_primitive(G, K)[1] f = dup_primitive(H, K)[1] factors.append(G) b = dup_LC(f, K) break else: s += 1 return factors + [f]
def dup_zz_zassenhaus(f, K): """Factor primitive square-free polynomials in `Z[x]`. """ n = dup_degree(f) if n == 1: return [f] A = dup_max_norm(f, K) b = dup_LC(f, K) B = int(abs(K.sqrt(K(n+1))*2**n*A*b)) C = int((n+1)**(2*n)*A**(2*n-1)) gamma = int(ceil(2*log(C, 2))) bound = int(2*gamma*log(gamma)) for p in xrange(3, bound+1): if not isprime(p) or b % p == 0: continue p = K.convert(p) F = gf_from_int_poly(f, p) if gf_sqf_p(F, p, K): break l = int(ceil(log(2*B + 1, p))) modular = [] for ff in gf_factor_sqf(F, p, K)[1]: modular.append(gf_to_int_poly(ff, p)) g = dup_zz_hensel_lift(p, f, modular, l, K) T = set(range(len(g))) factors, s = [], 1 while 2*s <= len(T): for S in subsets(T, s): G, H = [b], [b] S = set(S) for i in S: G = dup_mul(G, g[i], K) for i in T-S: H = dup_mul(H, g[i], K) G = dup_trunc(G, p**l, K) H = dup_trunc(H, p**l, K) G_norm = dup_l1_norm(G, K) H_norm = dup_l1_norm(H, K) if G_norm*H_norm <= B: T = T - S G = dup_primitive(G, K)[1] f = dup_primitive(H, K)[1] factors.append(G) b = dup_LC(f, K) break else: s += 1 return factors + [f]
def dup_zz_zassenhaus(f, K): """Factor primitive square-free polynomials in `Z[x]`. """ n = dup_degree(f) if n == 1: return [f] fc = f[-1] A = dup_max_norm(f, K) b = dup_LC(f, K) B = int(abs(K.sqrt(K(n + 1))*2**n*A*b)) C = int((n + 1)**(2*n)*A**(2*n - 1)) gamma = int(_ceil(2*_log(C, 2))) bound = int(2*gamma*_log(gamma)) a = [] # choose a prime number `p` such that `f` be square free in Z_p # if there are many factors in Z_p, choose among a few different `p` # the one with fewer factors for px in range(3, bound + 1): if not isprime(px) or b % px == 0: continue px = K.convert(px) F = gf_from_int_poly(f, px) if not gf_sqf_p(F, px, K): continue fsqfx = gf_factor_sqf(F, px, K)[1] a.append((px, fsqfx)) if len(fsqfx) < 15 or len(a) > 4: break p, fsqf = min(a, key=lambda x: len(x[1])) l = int(_ceil(_log(2*B + 1, p))) modular = [gf_to_int_poly(ff, p) for ff in fsqf] g = dup_zz_hensel_lift(p, f, modular, l, K) sorted_T = range(len(g)) T = set(sorted_T) factors, s = [], 1 pl = p**l while 2*s <= len(T): for S in subsets(sorted_T, s): # lift the constant coefficient of the product `G` of the factors # in the subset `S`; if it is does not divide `fc`, `G` does # not divide the input polynomial if b == 1: q = 1 for i in S: q = q*g[i][-1] q = q % pl if not _test_pl(fc, q, pl): continue else: G = [b] for i in S: G = dup_mul(G, g[i], K) G = dup_trunc(G, pl, K) G = dup_primitive(G, K)[1] q = G[-1] if q and fc % q != 0: continue H = [b] S = set(S) T_S = T - S if b == 1: G = [b] for i in S: G = dup_mul(G, g[i], K) G = dup_trunc(G, pl, K) for i in T_S: H = dup_mul(H, g[i], K) H = dup_trunc(H, pl, K) G_norm = dup_l1_norm(G, K) H_norm = dup_l1_norm(H, K) if G_norm*H_norm <= B: T = T_S sorted_T = [i for i in sorted_T if i not in S] G = dup_primitive(G, K)[1] f = dup_primitive(H, K)[1] factors.append(G) b = dup_LC(f, K) break else: s += 1 return factors + [f]