factored_denominator#

Factored denominators and associated free modules

class surface_dynamics.misc.factored_denominator.AbstractMSum(parent, data, allow_multiple=False, check=True)#

An abstract multiple sum

degrees()#

EXAMPLES:

sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing
sage: from surface_dynamics.misc.additive_multivariate_generating_series import AdditiveMultivariateGeneratingSeriesRing

sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 2)
sage: f = M.term(1, [((1,0), 1), ((1,1),2)]) + M.term(2, [((1,0), 2), ((1,2),3)])
sage: f.degrees()
{3, 5}

sage: A = AdditiveMultivariateGeneratingSeriesRing('x', 2)
sage: f = A.term(1, [((1,0), 1), ((1,1),2)]) + A.term(2, [((1,0), 2), ((1,2),3)])
sage: f.degrees()
{3, 5}
is_trivial_one()#

EXAMPLES:

sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing

sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 2)
sage: M.term(0, []).is_trivial_one()
False
sage: M.term(0, [((1,1),1)]).is_trivial_one()
False
sage: M.term(1, []).is_trivial_one()
True
sage: M.term(1, [((1,1),1)]).is_trivial_one()
False

sage: f = M.term(1, [((1,0),1)]) + M.term(1, [((0,1),1)])
sage: f.is_trivial_one()
False
is_trivial_zero()#

EXAMPLES:

sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing

sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 2)
sage: M.term(0, []).is_trivial_zero()
True
sage: M.term(0, [((1,1),1)]).is_trivial_zero()
True
sage: M.term(1, []).is_trivial_zero()
False
class surface_dynamics.misc.factored_denominator.AbstractMSumRing(poly_ring)#

TESTS:

sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing
sage: MultiplicativeMultivariateGeneratingSeriesRing(5, 'x') is MultiplicativeMultivariateGeneratingSeriesRing(['x0','x1','x2','x3','x4'])
True
free_module()#
ngens()#

Return the number of generators.

EXAMPLES:

sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing
sage: from surface_dynamics.misc.additive_multivariate_generating_series import AdditiveMultivariateGeneratingSeriesRing

sage: MultiplicativeMultivariateGeneratingSeriesRing('x', 3).ngens()
3
sage: AdditiveMultivariateGeneratingSeriesRing('x', 3).ngens()
3
one()#

EXAMPLES:

sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing

sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 2)
sage: M.zero()
0
sage: M.zero().parent() is M
True
sage: M.one().is_one()
True
polynomial_ring()#

EXAMPLES:

sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing
sage: from surface_dynamics.misc.additive_multivariate_generating_series import AdditiveMultivariateGeneratingSeriesRing


sage: MultiplicativeMultivariateGeneratingSeriesRing('x', 3).polynomial_ring()
Multivariate Laurent Polynomial Ring in x0, x1, x2 over Rational Field
sage: AdditiveMultivariateGeneratingSeriesRing('x', 3).polynomial_ring()
Multivariate Polynomial Ring in x0, x1, x2 over Rational Field
polynomial_ring_extra_var()#
term(num, den)#

Return the term num / den.

INPUT:

  • num - a Laurent polynomial

  • den - a list of pairs (vector, power) or a dictionary

    whose keys are the vectors and the values the powers. The vector v = (v_0, v_1, \ldots) with power n corresponds to the factor (1 - x_0^{v_0} x_1^{v_1} ldots x_k^{v_k})^n.

EXAMPLES:

sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing
sage: from surface_dynamics.misc.additive_multivariate_generating_series import AdditiveMultivariateGeneratingSeriesRing


sage: A = AdditiveMultivariateGeneratingSeriesRing('x', 3)
sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 3)
sage: M.term(1, [([1,1,0],1),([1,0,-1],2)])
(1)/((1 - x0*x2^-1)^2*(1 - x0*x1))
sage: M.term(1, {(1,1,0): 1, (1,0,2): 2})
(1)/((1 - x0*x2^2)^2*(1 - x0*x1))

sage: A.term(1, [([1,1,0],1),([1,0,-1],2)])
(1)/((x0 - x2)^2*(x0 + x1))
sage: A.term(1, {(1,1,0): 1, (1,0,2): 2})
(1)/((x0 + 2*x2)^2*(x0 + x1))

Also works if the denominator is already a factored denominator:

sage: from surface_dynamics.misc.factored_denominator import FactoredDenominator
sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 3)
sage: den = FactoredDenominator({(1,0,0): 2, (1,1,1):1})
sage: M.term(1, den)
(1)/((1 - x0)^2*(1 - x0*x1*x2))

sage: A.term(1, den)
 (1)/((x0)^2*(x0 + x1 + x2))

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: d = {}
sage: v0 = vector(QQ, (1,0)); v0.set_immutable()
sage: v1 = vector(QQ, (1,1)); v1.set_immutable()
sage: d[v1] = 1
sage: d[v0] = 1
sage: M.term(1*x0^2*x1, d)
(x0^2*x1)/((1 - x0)*(1 - x0*x1))
with_extra_var()#
zero()#

EXAMPLES:

sage: from surface_dynamics.misc.multiplicative_multivariate_generating_series import MultiplicativeMultivariateGeneratingSeriesRing

sage: M = MultiplicativeMultivariateGeneratingSeriesRing('x', 2)
sage: M.zero()
0
sage: M.zero().parent() is M
True
sage: M.zero().is_zero()
True
class surface_dynamics.misc.factored_denominator.FactoredDenominator(data, V=None)#

Factored denominator

This class is a simple datastructure to handle factored denominator, that is a list of pairs (v, m) where the v are integer vectors (of fixed dimension) and m are multiplicities (i.e. positive integers).

It is used for at least two purposes:

  • (Factored) product of polynomials of the form (1 - m)^d where m is a monomial

  • generalized multiple zeta values, where denominators are products of linear forms

EXAMPLES:

sage: from surface_dynamics.misc.factored_denominator import FactoredDenominator

sage: V = ZZ**3
sage: f1 = FactoredDenominator([((1,0,0), 2)], V)
sage: f2 = FactoredDenominator([((0,1,2), 3), ((1,1,1), 1)], V)
sage: f3 = FactoredDenominator([((0,-1,2), 1), ((1,0,0), 1), ((0,0,2), 1)], V)
sage: f1
{(1, 0, 0): 2}
sage: f1 * f2 * f3
{(1, 0, 0): 3, (0, 1, 2): 3, (1, 1, 1): 1, (0, -1, 2): 1, (0, 0, 2): 1}
sage: hash(f1)  # random
9164823176457928306

sage: FactoredDenominator(f1)
{(1, 0, 0): 2}
copy()#
degree()#

EXAMPLES:

sage: from surface_dynamics.misc.factored_denominator import FactoredDenominator

sage: V = ZZ**3
sage: FactoredDenominator([], V).degree()
0
sage: FactoredDenominator([((1,0,0), 2)], V).degree()
2
sage: FactoredDenominator([((0,1,2), 3), ((1,1,1), 1)], V).degree()
4
sage: FactoredDenominator([((0,-1,2), 1), ((1,0,0), 1), ((0,0,2), 1)], V).degree()
3

TESTS:

sage: parent(FactoredDenominator([], V).degree())
Integer Ring
sage: parent(FactoredDenominator([((1,0,0), 2)], V).degree())
Integer Ring
gcd(other)#

Return the gcd of two factored denominator.

EXAMPLES:

sage: from surface_dynamics.misc.factored_denominator import FactoredDenominator

sage: V = ZZ**3

sage: f1 = FactoredDenominator([((1,0,0), 2),((0,1,0),1)], V)
sage: f2 = FactoredDenominator([((1,0,0), 1),((0,1,0),2)], V)
sage: f3 = FactoredDenominator([((1,0,0), 1),((0,1,0),1),((0,0,1),1)], V)
sage: f4 = FactoredDenominator([], V)

sage: f1.gcd(f2)
{(1, 0, 0): 1, (0, 1, 0): 1}
sage: f1.gcd(f2) == f1.gcd(f3) == f2.gcd(f3)
True

sage: f4.gcd(f1) == f4 and f1.gcd(f4) == f1
True
gcd_update(other)#
is_one()#
lcm(other)#

Return the lcm of two factored denominators.

EXAMPLES:

sage: from surface_dynamics.misc.factored_denominator import FactoredDenominator

sage: V = ZZ**3

sage: f1 = FactoredDenominator([((1,0,0), 2),((0,1,0),1)], V)
sage: f2 = FactoredDenominator([((1,0,0), 1),((0,1,0),2)], V)
sage: f3 = FactoredDenominator([((1,0,0), 1),((0,1,0),1),((0,0,1),1)], V)
sage: f4 = FactoredDenominator([], V)

sage: f1.lcm(f2)
{(1, 0, 0): 2, (0, 1, 0): 2}
sage: f1.lcm(f3)
{(1, 0, 0): 2, (0, 1, 0): 1, (0, 0, 1): 1}
sage: f2.lcm(f3)
{(1, 0, 0): 1, (0, 1, 0): 2, (0, 0, 1): 1}

sage: f1.lcm(f4) == f1 and f4.lcm(f1) == f1
True
lcm_update(other)#
logarithmic_minus_derivative(j)#

Minus the logarithmic derivative -v’ / v taken with respect to the j-th variable

Since this denominator has the form 1 / (1 - m1) (1 - m2) … (1 - mk) the logarithmic derivative is simply

m1’/(1-m1) + m2’/(1-m2) + … + mk’/(1-mk)

INPUT:

  • j – index of a variable

OUTPUT: iterator of triples (mult, v, monomial)

EXAMPLES:

sage: from surface_dynamics.misc.factored_denominator import FactoredDenominator

sage: V = ZZ**3

sage: f = FactoredDenominator([((1,0,0), 2)], V)
sage: f
{(1, 0, 0): 2}
sage: list(f.logarithmic_minus_derivative(0))
[(2, (0, 0, 0), (1, 0, 0))]
sage: list(f.logarithmic_minus_derivative(1))
[]
sage: list(f.logarithmic_minus_derivative(2))
[]

sage: f = FactoredDenominator([((1,1,1), 1)], V)
sage: list(f.logarithmic_minus_derivative(0))
[(1, (0, 1, 1), (1, 1, 1))]

sage: f = FactoredDenominator([((1,0,0), 1), ((0,1,0), 1), ((0,0,1), 1)], V)
sage: list(f.logarithmic_minus_derivative(0))
[(1, (0, 0, 0), (1, 0, 0))]

sage: f = FactoredDenominator([((1,0,0), 2), ((1,1,0), 3), ((1,1,1), 1)], V)
sage: f
{(1, 0, 0): 2, (1, 1, 0): 3, (1, 1, 1): 1}
sage: list(f.logarithmic_minus_derivative(0))
[(2, (0, 0, 0), (1, 0, 0)),
 (3, (0, 1, 0), (1, 1, 0)),
 (1, (0, 1, 1), (1, 1, 1))]
str()#
str_linear(var_names='h')#
str_monomials(var_names='x')#
subs(m)#

Matrix substitution.

EXAMPLES:

sage: from surface_dynamics.misc.factored_denominator import FactoredDenominator
sage: V = ZZ**3
sage: f = FactoredDenominator([((0,1,2), 3), ((1,1,1), 1)], V)

sage: m = matrix(3, [1,1,0,0,1,1,1,0,1])
sage: f.subs(m) == FactoredDenominator([((1,3,2), 3), ((2,2,2), 1)], V)
True

sage: m = matrix(3, [1,1,1,1,1,1,1,1,1])
sage: f.subs(m)
{(3, 3, 3): 4}

sage: m = matrix(3, [1,0,0,1,0,0,1,0,0])
sage: f.subs(m)
Traceback (most recent call last):
...
ValueError: zero denominator
to_additive_polynomial(S, extra_var=False)#

Return the product of the term in a given polynomial ring S.

EXAMPLES:

sage: from surface_dynamics.misc.factored_denominator import FactoredDenominator

sage: V = ZZ ** 3
sage: f = FactoredDenominator([((1,0,0), 2)], V)
sage: g = FactoredDenominator([((1,0,0), 2), ((1,1,1),1)], V)

sage: R1 = QQ['x,y,z']
sage: f.to_additive_polynomial(R1)
x^2
sage: g.to_additive_polynomial(R1)
x^3 + x^2*y + x^2*z

sage: f.to_additive_polynomial(R1['E'], extra_var=True)
x^2*E^2
sage: g.to_additive_polynomial(R1['E'], extra_var=True)
(x^3 + x^2*y + x^2*z)*E^3

sage: g.to_additive_polynomial(QQ['t1,t2,t3'])
t1^3 + t1^2*t2 + t1^2*t3
to_multiplicative_polynomial(S, extra_var=False)#

Return the product of the term in a given polynomial ring S.

EXAMPLES:

sage: from surface_dynamics.misc.factored_denominator import FactoredDenominator

sage: V = ZZ ** 3
sage: f = FactoredDenominator([((1,0,0), 2)], V)
sage: g = FactoredDenominator([((1,0,0), 2), ((1,1,1),1)], V)

sage: R1 = QQ['x,y,z']
sage: f.to_multiplicative_polynomial(R1)
x^2 - 2*x + 1
sage: g.to_multiplicative_polynomial(R1)
-x^3*y*z + 2*x^2*y*z - x*y*z + x^2 - 2*x + 1

sage: f.to_multiplicative_polynomial(R1['E'], extra_var=True)
x^2*E^2 - 2*x*E + 1
sage: g.to_multiplicative_polynomial(R1['E'], extra_var=True)
-x^3*y*z*E^5 + 2*x^2*y*z*E^4 - x*y*z*E^3 + x^2*E^2 - 2*x*E + 1

sage: g.to_multiplicative_polynomial(QQ['t1,t2,t3'])
-t1^3*t2*t3 + 2*t1^2*t2*t3 - t1*t2*t3 + t1^2 - 2*t1 + 1
surface_dynamics.misc.factored_denominator.laurent_monomial(R, arg)#

EXAMPLES:

sage: from surface_dynamics.misc.factored_denominator import laurent_monomial
sage: R = LaurentPolynomialRing(QQ, 'x', 2)
sage: laurent_monomial(R, (1,2))
x0*x1^2
sage: laurent_monomial(R, vector((-1r,3r)))
x0^-1*x1^3
sage: laurent_monomial(R, (-1,3)) * laurent_monomial(R, (1,1)) == laurent_monomial(R, (0,4))
True
surface_dynamics.misc.factored_denominator.vector_to_linear_form_string(u, var_names)#

EXAMPLES:

sage: from surface_dynamics.misc.factored_denominator import vector_to_linear_form_string
sage: vector_to_linear_form_string((0,4,3), 'x')
'4*x1 + 3*x2'
sage: vector_to_linear_form_string((0,4,3), 'hello')
'4*hello1 + 3*hello2'
sage: vector_to_linear_form_string((0,4,3), ('x','y','z'))
'4*y + 3*z'
sage: vector_to_linear_form_string((1,0,-1), 'x')
'x0 - x2'
sage: vector_to_linear_form_string((2,0,-3), 'x')
'2*x0 - 3*x2'
sage: vector_to_linear_form_string((-1,1,0), 'x')
'-x0 + x1'
sage: vector_to_linear_form_string((-2,3,0), 'x')
 '-2*x0 + 3*x1'
sage: vector_to_linear_form_string((0,-1,1,0), 'x')
'-x1 + x2'
surface_dynamics.misc.factored_denominator.vector_to_monomial_string(u, var_names)#

EXAMPLES:

sage: from surface_dynamics.misc.factored_denominator import vector_to_monomial_string
sage: vector_to_monomial_string((0,4,3), 'x')
'x1^4*x2^3'
sage: vector_to_monomial_string((0,4,3), 'hello')
'hello1^4*hello2^3'
sage: vector_to_monomial_string((0,4,3), ('x','y','z'))
'y^4*z^3'
sage: vector_to_monomial_string((1,0,-1), 'x')
'x0*x2^-1'