def generate(R, P, G, B): while R: h = normal(f[R.pop()], G | P) if h is not None: k, LM = h G0 = set(g for g in G if monomial_div(f[g].LM, LM)) P0 = set(p for p in P if monomial_div(f[p].LM, LM)) G, P, R = G - G0, P - P0 | set([k]), R | G0 | P0 for i, j in set(B): if i in G0 or j in G0: del B[(i, j)] G |= P for i in G: for j in P: if i == j: continue if i < j: k = (i, j) else: k = (j, i) if k not in B: B[k] = monomial_lcm(f[i].LM, f[j].LM) G = set([normal(f[g], G - set([g]))[0] for g in G]) return R, P, G, B
def generate(R, P, G, B): while R: h = normal(f[R.pop()], G | P) if h is not None: k, LM = h G0 = set(g for g in G if monomial_div(f[g].LM, LM)) P0 = set(p for p in P if monomial_div(f[p].LM, LM)) G, P, R = G - G0, P - P0 | set([k]), R | G0 | P0 for i, j in set(B): if i in G0 or j in G0: del B[(i, j)] G |= P for i in G: for j in P: if i == j: continue if i < j: k = (i, j) else: k = (j, i) if not B.has_key(k): B[k] = monomial_lcm(f[i].LM, f[j].LM) G = set([ normal(f[g], G - set([g]))[0] for g in G ]) return R, P, G, B
def poly_lcm(f, g, *symbols): """Computes least common multiple of two polynomials. Given two univariate polynomials, the LCM is computed via f*g = gcd(f, g)*lcm(f, g) formula. In multivariate case, we compute the unique generator of the intersection of the two ideals, generated by f and g. This is done by computing a Groebner basis, with respect to any lexicographic ordering, of t*f and (1 - t)*g, where t is an unrelated symbol and filtering out solution that does not contain t. For more information on the implemented algorithm refer to: [1] D. Cox, J. Little, D. O'Shea, Ideals, Varieties and Algorithms, Springer, Second Edition, 1997, pp. 187 """ if not isinstance(f, Poly): f = Poly(f, *symbols) elif symbols: raise SymbolsError("Redundant symbols were given") f, g = f.unify_with(g) symbols, flags = f.symbols, f.flags if f.is_monomial and g.is_monomial: monom = monomial_lcm(f.LM, g.LM) fc, gc = f.LC, g.LC if fc.is_Rational and gc.is_Rational: coeff = Integer(ilcm(fc.p, gc.p)) else: coeff = S.One return Poly((coeff, monom), *symbols, **flags) fc, f = f.as_primitive() gc, g = g.as_primitive() lcm = ilcm(int(fc), int(gc)) if f.is_multivariate: t = Symbol('t', dummy=True) lex = {'order': 'lex'} f_monoms = [(1, ) + monom for monom in f.monoms] F = Poly((f.coeffs, f_monoms), t, *symbols, **lex) g_monoms = [ (0,) + monom for monom in g.monoms ] + \ [ (1,) + monom for monom in g.monoms ] g_coeffs = list(g.coeffs) + [-coeff for coeff in g.coeffs] G = Poly(dict(zip(g_monoms, g_coeffs)), t, *symbols, **lex) def independent(h): return all(not monom[0] for monom in h.monoms) H = [h for h in poly_groebner((F, G)) if independent(h)] if lcm != 1: h_coeffs = [coeff * lcm for coeff in H[0].coeffs] else: h_coeffs = H[0].coeffs h_monoms = [monom[1:] for monom in H[0].monoms] return Poly(dict(zip(h_monoms, h_coeffs)), *symbols, **flags) else: h = poly_div(f * g, poly_gcd(f, g))[0] if lcm != 1: return h.mul_term(lcm / h.LC) else: return h.as_monic()
def poly_lcm(f, g, *symbols): """Computes least common multiple of two polynomials. Given two univariate polynomials, the LCM is computed via f*g = gcd(f, g)*lcm(f, g) formula. In multivariate case, we compute the unique generator of the intersection of the two ideals, generated by f and g. This is done by computing a Groebner basis, with respect to any lexicographic ordering, of t*f and (1 - t)*g, where t is an unrelated symbol and filtering out solution that does not contain t. For more information on the implemented algorithm refer to: [1] D. Cox, J. Little, D. O'Shea, Ideals, Varieties and Algorithms, Springer, Second Edition, 1997, pp. 187 """ if not isinstance(f, Poly): f = Poly(f, *symbols) elif symbols: raise SymbolsError("Redundant symbols were given") f, g = f.unify_with(g) symbols, flags = f.symbols, f.flags if f.is_monomial and g.is_monomial: monom = monomial_lcm(f.LM, g.LM) fc, gc = f.LC, g.LC if fc.is_Rational and gc.is_Rational: coeff = Integer(ilcm(fc.p, gc.p)) else: coeff = S.One return Poly((coeff, monom), *symbols, **flags) fc, f = f.as_primitive() gc, g = g.as_primitive() lcm = ilcm(int(fc), int(gc)) if f.is_multivariate: t = Symbol('t', dummy=True) lex = { 'order' : 'lex' } f_monoms = [ (1,) + monom for monom in f.monoms ] F = Poly((f.coeffs, f_monoms), t, *symbols, **lex) g_monoms = [ (0,) + monom for monom in g.monoms ] + \ [ (1,) + monom for monom in g.monoms ] g_coeffs = list(g.coeffs) + [ -coeff for coeff in g.coeffs ] G = Poly(dict(zip(g_monoms, g_coeffs)), t, *symbols, **lex) def independent(h): return all(not monom[0] for monom in h.monoms) H = [ h for h in poly_groebner((F, G)) if independent(h) ] if lcm != 1: h_coeffs = [ coeff*lcm for coeff in H[0].coeffs ] else: h_coeffs = H[0].coeffs h_monoms = [ monom[1:] for monom in H[0].monoms ] return Poly(dict(zip(h_monoms, h_coeffs)), *symbols, **flags) else: h = poly_div(f * g, poly_gcd(f, g))[0] if lcm != 1: return h.mul_term(lcm / h.LC) else: return h.as_monic()