def monomial_lcm(self, f, g): """ LCM for monomials. Coefficients are ignored. INPUT: - ``f`` - monomial - ``g`` - monomial EXAMPLE:: sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain sage: P.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex') sage: P.monomial_lcm(3/2*x*y,x) x*y TESTS:: sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain sage: R.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex') sage: P.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex') sage: P.monomial_lcm(x*y,R.gen()) x*y :: sage: P.monomial_lcm(P(3/2),P(2/3)) 1 :: sage: P.monomial_lcm(x,P(1)) x """ one = self.base_ring()(1) f=f.dict().keys()[0] g=g.dict().keys()[0] length = len(f) res = {} for i in f.common_nonzero_positions(g): res[i] = max([f[i],g[i]]) res = self(PolyDict({ETuple(res,length):one},\ force_int_exponents=False,force_etuples=False)) return res
def monomial_all_divisors(self, t): r""" Return a list of all monomials that divide ``t``, coefficients are ignored. INPUT: - ``t`` - a monomial. OUTPUT: a list of monomials. EXAMPLES:: sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain sage: P.<x,y,z> = MPolynomialRing_polydict_domain(QQ,3, order='degrevlex') sage: P.monomial_all_divisors(x^2*z^3) [x, x^2, z, x*z, x^2*z, z^2, x*z^2, x^2*z^2, z^3, x*z^3, x^2*z^3] ALGORITHM: addwithcarry idea by Toon Segers """ def addwithcarry(tempvector, maxvector, pos): if tempvector[pos] < maxvector[pos]: tempvector[pos] += 1 else: tempvector[pos] = 0 tempvector = addwithcarry(tempvector, maxvector, pos + 1) return tempvector if not t.is_monomial(): raise TypeError("only monomials are supported") R = self one = self.base_ring().one() M = list() v, = t.dict() maxvector = list(v) tempvector = [ 0, ] * len(maxvector) pos = 0 while tempvector != maxvector: tempvector = addwithcarry(list(tempvector), maxvector, pos) M.append( R( PolyDict({ETuple(tempvector): one}, force_int_exponents=False, force_etuples=False))) return M
def monomial_quotient(self, f, g, coeff=False): r""" Return ``f/g``, where both ``f`` and ``g`` are treated as monomials. Coefficients are ignored by default. INPUT: - ``f`` - monomial. - ``g`` - monomial. - ``coeff`` - divide coefficients as well (default: False). OUTPUT: monomial. EXAMPLE:: sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain sage: P.<x,y,z> = MPolynomialRing_polydict_domain(QQ, 3, order='degrevlex') sage: P.monomial_quotient(3/2*x*y, x) y :: sage: P.monomial_quotient(3/2*x*y, 2*x, coeff=True) 3/4*y TESTS:: sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain sage: R.<x,y,z> = MPolynomialRing_polydict_domain(QQ,3, order='degrevlex') sage: P.<x,y,z> = MPolynomialRing_polydict_domain(QQ,3, order='degrevlex') sage: P.monomial_quotient(x*y, x) y :: sage: P.monomial_quotient(x*y, R.gen()) y :: sage: P.monomial_quotient(P(0), P(1)) 0 :: sage: P.monomial_quotient(P(1), P(0)) Traceback (most recent call last): ... ZeroDivisionError :: sage: P.monomial_quotient(P(3/2), P(2/3), coeff=True) 9/4 :: sage: P.monomial_quotient(x, y) # Note the wrong result x*y^-1 :: sage: P.monomial_quotient(x, P(1)) x .. note:: Assumes that the head term of f is a multiple of the head term of g and return the multiplicant m. If this rule is violated, funny things may happen. """ from sage.rings.polynomial.multi_polynomial_element import MPolynomial_polydict if not f: return f if not g: raise ZeroDivisionError if not coeff: coeff = self.base_ring()(1) else: coeff = self.base_ring()(f.dict().values()[0] / g.dict().values()[0]) f = f.dict().keys()[0] g = g.dict().keys()[0] res = f.esub(g) return MPolynomial_polydict(self, PolyDict({res:coeff},\ force_int_exponents=False, \ force_etuples=False))