multiplicative_multivariate_generating_series
#
Multiplicative rational multivariate functions
This module implements the algebra generated by rational functions of the form
where the m_i are monomials and d_i are positive integers.
REFERENCES:
- [LHTY] De Loera, R. Hemmecke, J. Tauzer, R. Yoshida
“Effective lattice point counting in rational convex polytopes” (LattE)
[Ba] Barvinok
[St] Stanley “Enumerative Combinatorics” Volume I Cambridge Studies in Advanced Mathematics 49 (1997)
- class surface_dynamics.misc.multiplicative_multivariate_generating_series.MultiplicativeMultivariateGeneratingSeries(parent, data, allow_multiple=False, check=True)#
- as_symbolic()#
- delta()#
Take a derivative (up to lower order terms) with respect to each of the variables.
- derivative(var)#
EXAMPLES:
sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 2) sage: R = M.polynomial_ring() sage: x0, x1 = R.gens() sage: f = M.term(1, [((1,0),1)]) sage: f.derivative(0) (1)/((1 - x0)^2) sage: f.derivative(0).derivative(0) (2)/((1 - x0)^3) sage: xx0, xx1 = R.polynomial_ring().gens() sage: f.taylor(10).derivative(xx0) == f.derivative(0).taylor(9) True sage: f.derivative(1) 0 sage: f = M.term(x0 * x1, [((1,1),2)]) sage: f.derivative(0) (x1)/((1 - x0*x1)^2) + (2*x0*x1^2)/((1 - x0*x1)^3) sage: f.derivative(0).taylor(10) - f.taylor(10).derivative(xx0) 30*x0^5*x1^6 sage: f = M.term(1, [((1,2),2), ((0,1),2), ((1,0),2), ((1,1),2)]) sage: min((f.taylor(10).derivative(xx0) - f.derivative(0).taylor(10)).degrees()) 9 sage: min((f.taylor(10).derivative(xx1) - f.derivative(1).taylor(10)).degrees()) 10 sage: f = M.term(1, [((1,0),2), ((1,1),1)]) sage: f.taylor(10).derivative(xx0).derivative(xx1) - f.derivative(0).derivative(1).taylor(9) -18*x0^9*x1 - 42*x0^8*x1^2 - ... - 72*x0^5*x1^3 - 25*x0^4*x1^4 sage: f = M.zero() + M.term(1/1*x0^2 * x1, [((1,0),1), ((1,1),1)]) sage: f.derivative(0) (2*x0*x1)/((1 - x0)*(1 - x0*x1)) + (x0^2*x1^2)/((1 - x0)*(1 - x0*x1)^2) + (x0^2*x1)/((1 - x0)^2*(1 - x0*x1))
You can indistinctly use integers, strings or polynomial variables for
var
:sage: f = M.term(1, [((1,1),1)]) sage: f.derivative('x0') (x1)/((1 - x0*x1)^2) sage: f.derivative(0) (x1)/((1 - x0*x1)^2) sage: f.derivative(R.gen(0)) (x1)/((1 - x0*x1)^2)
Checking errors in the input:
sage: f.derivative(-1) Traceback (most recent call last): ... ValueError: generator not defined sage: f.derivative('q') Traceback (most recent call last): ... ValueError: 'q' not valid as a variable
- derivative_up_to_lower_order_terms(var)#
Each term
u/v
is replaced by-u v'/v^2
.This corresponds to one half of the derivative, the other half being
u' / v
. This second part can be ignored when asymptotics question are considered.EXAMPLES:
sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 2) sage: f = M.term(1, [((1,0),2)]) sage: f (1)/((1 - x0)^2) sage: f.derivative_up_to_lower_order_terms(0) (2)/((1 - x0)^3) sage: f = M.term(1, [((1,0),1),((0,1),1),((1,1),1)])
- factor()#
Group all the partial fractions into a unique fraction.
EXAMPLES:
sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 3) sage: f = M.term(1, [([1,3,0],1),([1,0,-1],1)]) sage: g = M.term(1, [([1,1,0],1),([1,0,-1],2)]) sage: (f + g).factor() (-x0*x1^3 + x0^2*x1*x2^-1 - x0*x1 - x0*x2^-1 + 2)/((1 - x0*x2^-1)^2*(1 - x0*x1)*(1 - x0*x1^3)) sage: x0, x1, x2 = M.polynomial_ring().gens() sage: f = M.term(x0 + x1, [([1,3,0],1),([1,0,1],1)]) sage: g = M.term(x2 - 1, [([1,1,0],1),([1,0,1],2)]) sage: h = f + g sage: t1 = h.taylor(8) sage: t2 = h.factor().taylor(8) sage: assert all(sum(e) >= 8 for e in (t1 - t2).exponents())
Simplification:
sage: f1 = M.term(x0, [([1,0,0],1)]) sage: f2 = M.term(x1, [([0,1,0],1)]) sage: f3 = M.term(x0*x1 - 1, [([1,0,0],1), ([0,1,0],1)]) sage: (f1 + f2 + f3).factor() (-1) sage: f1 + f2 + 1 == -f3 # indirect doctest True
- is_one()#
- is_zero()#
- numerator()#
Return the numerator if there is at most one summand.
EXAMPLES:
sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 3) sage: x0, x1, x2 = M.polynomial_ring().gens() sage: f = M.term(x0 + x1^2*x2, [([1,3,0],1),([1,0,-1],1)]) sage: f.numerator() x1^2*x2 + x0 sage: g = M.term(1 - x2, [([1,1,0],1),([1,0,-1],2)]) sage: (f + g).numerator() Traceback (most recent call last): ... ValueError: not a simple fraction sage: (f + g).factor().numerator() x0^2*x1^3 - x0*x1^3 + x0^3*x1*x2^-1 - x0^2*x1 - x0*x1^2 + x1^2*x2 - x0^2*x2^-1 + x0 - x2 + 1
- numerator_subs(*args, **kwds)#
- residue()#
denominator: each (1 - mon)^k in denom is replaced with -> mon^k numerator: evaluate at (1,1,…,1)
OUTPUT: a pair ‘(degree, value)`
EXAMPLES:
sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing sage: M = MultiplicativeMultivariateGeneratingSeriesRing(2, 'x') sage: R = M.polynomial_ring() sage: x0,x1 = R.gens() sage: f = M.term(x0, [((1,1),2)]) sage: f.residue() (2, [(1, {(1, 1): 2})]) sage: f = M.term(x0, [((1,1),2)]) + M.term(1, [((1,0),1),((0,1),1),((1,1),1)]) sage: r = f.residue() sage: r # random (3, [(1, {(1, 0): 1, (0, 1): 1, (1, 1): 1})]) sage: f = M.term(x0, [((1,1),2)]) + M.term(1, [((1,0),1),((1,1),1)]) sage: r = f.residue() sage: r # random (2, [(1, {(1, 1): 2}), (1, {(1, 0): 1, (1, 1): 1})])
- subs_numerator(*args, **kwds)#
TESTS:
sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 2) sage: R = M.polynomial_ring() sage: x0, x1 = R.gens() sage: f = M.term(-x0 + 2*x0*x1^3, [((1,1), 1), ((1,2),2)]) sage: f.subs_numerator(x0=1, x1=1) (1)/((1 - x0*x1)*(1 - x0*x1^2)^2)
- summands()#
Return the list of elementary summands
EXAMPLES:
sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import * sage: M = MultiplicativeMultivariateGeneratingSeriesRing(2, 'x') sage: m1 = M.term(1, [((1,-1),1), ((0,1),1)]) sage: m2 = M.term(1, [((-1,1),1), ((1,0),1)]) sage: f = (m1 + m2)**2 sage: for s in f.summands(): print(s) (2)/((1 - x0^-1*x1)*(1 - x1)*(1 - x0*x1^-1)*(1 - x0)) (1)/((1 - x0^-1*x1)^2*(1 - x0)^2) (1)/((1 - x1)^2*(1 - x0*x1^-1)^2)
- taylor(prec, R=None)#
EXAMPLES:
sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing sage: M = MultiplicativeMultivariateGeneratingSeriesRing('t,u') sage: t,u = M.polynomial_ring().gens() sage: f = M.term(t + u^3, [((1,1), 1), ((1,2),2)]) sage: f (u^3 + t)/((1 - t*u)*(1 - t*u^2)^2) sage: f.taylor(10) 2*t^4*u^8 + 4*t^3*u^9 + t^4*u^7 + 3*t^3*u^8 + ... + t*u^4 + 2*t^2*u^2 + t^2*u + u^3 + t
TODO: this is only working term by term but for example containing negative powers as:
sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 2) # not tested sage: m1 = M.term(1, [((1,-1),1), ((0,1),1)]) # not tested sage: m2 = M.term(1, [((-1,1),1), ((1,0),1)]) # not tested sage: f = m1 + m2 # not tested sage: f.taylor(10) # not tested
TESTS:
sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 2) sage: R = M.polynomial_ring() sage: x0, x1 = R.gens() sage: import sage.rings.polynomial.multi_polynomial_libsingular sage: isinstance(M.term(1, [((1,0),1)]).taylor(10), sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular) True
- class surface_dynamics.misc.multiplicative_multivariate_generating_series.MultiplicativeMultivariateGeneratingSeriesRing(poly_ring)#
EXAMPLES:
sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing sage: MultiplicativeMultivariateGeneratingSeriesRing('x', 3) Multiplicative multivariate generating series on x0, x1, x2 sage: MultiplicativeMultivariateGeneratingSeriesRing(['x', 'y', 'z']) Multiplicative multivariate generating series on x, y, z sage: MultiplicativeMultivariateGeneratingSeriesRing('a,b,c') Multiplicative multivariate generating series on a, b, c sage: MultiplicativeMultivariateGeneratingSeriesRing('y', 2) Multiplicative multivariate generating series on y0, y1 sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 3) sage: M.zero() 0 sage: M.one() (1) sage: m1 = M.term(1, [((1,1,0),1)]) sage: m1 (1)/((1 - x0*x1)) sage: m2 = M.term(-2, [((1,0,0),1),((0,1,0),2)]) sage: m2 (-2)/((1 - x1)^2*(1 - x0))
- Element#
- residue_ring()#
Return the residue ring (the additive version of self).
EXAMPLES:
sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 3) sage: M.residue_ring() Additive multivariate generating series on x0, x1, x2
- surface_dynamics.misc.multiplicative_multivariate_generating_series.latte_generating_series(L, M=None)#
EXAMPLES:
sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import latte_generating_series sage: ieqs = [[0, 1, 0, 0, 0, 0, 0], ....: [0, 0, 1, -1, 1, 0, 0], ....: [0, 0, 0, 0, 1, 0, 0], ....: [0, 0, 0, 1, 0, 0, 0], ....: [0, 0, 1, 0, 0, 0, 0]] sage: eqns = [[0, 0, 1, -1, 1, 0, -1], [0, 0, 1, -1, 1, -1, 0]] sage: L = Polyhedron(ieqs=ieqs, eqns=eqns) sage: latte_generating_series(L) # optional: latte_int (1)/((1 - x2^-1*x4*x5)*(1 - x2*x3)*(1 - x1*x2)*(1 - x0)) + (1)/((1 - x3*x4*x5)*(1 - x2*x4^-1*x5^-1)*(1 - x1*x4*x5)*(1 - x0))
- surface_dynamics.misc.multiplicative_multivariate_generating_series.parse_latte_generating_series(M, s)#
INPUT:
M
- a multivariate generating series rings
- a string as given by LattE
OUTPUT: multivariate short rational function