Lazy Combinatorial Species¶
We regard a combinatorial species as a sequence of group actions of the symmetric groups \(\mathfrak S_n\), for \(n\in\NN\).
Coefficients of lazy species are computed on demand. They have infinite precision, although equality can only be decided in special cases.
AUTHORS:
Mainak Roy, Martin Rubey, Travis Scrimshaw (2024-2025)
EXAMPLES:
We can reproduce the molecular expansions from Appendix B in [GL2011] with little effort. The molecular expansion of the species of point determining graphs can be computed as the species of graphs composed with the compositional inverse of the species of non-empty sets:
sage: L.<X> = LazyCombinatorialSpecies(QQ)
sage: E = L.Sets()
sage: Ep = E.restrict(1)
sage: G = L.Graphs()
>>> from sage.all import *
>>> L = LazyCombinatorialSpecies(QQ, names=('X',)); (X,) = L._first_ngens(1)
>>> E = L.Sets()
>>> Ep = E.restrict(Integer(1))
>>> G = L.Graphs()
The molecular decomposition begins with:
sage: P = G(Ep.revert())
sage: P.truncate(6)
1 + X + E_2 + (E_3+X*E_2) + (E_4+X*E_3+E_2(E_2)+X^2*E_2+E_2(X^2))
+ (E_5+E_2*E_3+X*E_4+X*E_2^2+X^2*E_3+2*X*E_2(E_2)+P_5+5*X*E_2(X^2)+3*X^3*E_2)
>>> from sage.all import *
>>> P = G(Ep.revert())
>>> P.truncate(Integer(6))
1 + X + E_2 + (E_3+X*E_2) + (E_4+X*E_3+E_2(E_2)+X^2*E_2+E_2(X^2))
+ (E_5+E_2*E_3+X*E_4+X*E_2^2+X^2*E_3+2*X*E_2(E_2)+P_5+5*X*E_2(X^2)+3*X^3*E_2)
Note that [GL2011] write \(D_5\) instead of \(P_5\), and there is apparently a misprint: \(X*E_2(E_2) + 4 X^3 E_2\) should be \(2 X E_2(E_2) + 3 X^3 E_2\).
To compute the molecular decomposition of the species of connected graphs with no endpoints, we use Equation (3.3) in [GL2011]. Before that we need to define the species of connected graphs:
sage: Gc = Ep.revert()(G-1)
sage: E_2 = L(SymmetricGroup(2))
sage: Mc = Gc(X*E(-X)) + E_2(-X)
sage: E(Mc).truncate(5)
1 + X + E_2 + 2*E_3 + (2*E_4+E_2(E_2)+E_2^2+X*E_3)
>>> from sage.all import *
>>> Gc = Ep.revert()(G-Integer(1))
>>> E_2 = L(SymmetricGroup(Integer(2)))
>>> Mc = Gc(X*E(-X)) + E_2(-X)
>>> E(Mc).truncate(Integer(5))
1 + X + E_2 + 2*E_3 + (2*E_4+E_2(E_2)+E_2^2+X*E_3)
Note that [GL2011] apparently contains a misprint: \(2 X E_3\) should be \(X E_3 + E_2^2\). Indeed, the graphs on four vertices without endpoints are the complete graph and the empty graph, the square, the diamond graph and the triangle with an extra isolated vertex.
To compute the molecular decomposition of the species of bi-point-determining graphs we use Corollary (4.6) in [GL2011]:
sage: B = G(2*Ep.revert() - X)
sage: B.truncate(6)
1 + X + E_2(X^2) + (P_5+5*X*E_2(X^2))
>>> from sage.all import *
>>> B = G(Integer(2)*Ep.revert() - X)
>>> B.truncate(Integer(6))
1 + X + E_2(X^2) + (P_5+5*X*E_2(X^2))
- class sage.rings.lazy_species.ChainSpecies(parent)[source]¶
Bases:
LazyCombinatorialSpeciesElement,UniqueRepresentationInitialize the species of chains.
- structures(labels)[source]¶
Iterate over the structures on the given set of labels.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(ZZ, "X") sage: Ch = L.Chains() sage: list(Ch.structures([1,2,3])) [(1, 3, 2), (1, 2, 3), (2, 1, 3)]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(ZZ, "X") >>> Ch = L.Chains() >>> list(Ch.structures([Integer(1),Integer(2),Integer(3)])) [(1, 3, 2), (1, 2, 3), (2, 1, 3)]
- class sage.rings.lazy_species.CompositionSpeciesElement(left, *args)[source]¶
Bases:
LazyCombinatorialSpeciesElementGeneratingSeriesMixin,LazyCombinatorialSpeciesElementInitialize the composition of species.
- cycle_index_series()[source]¶
Return the cycle index series for this species.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: E = L.Sets() sage: F = E(E.restrict(1)) sage: F.cycle_index_series()[5] h[2, 2, 1] - h[3, 1, 1] + 3*h[3, 2] + 2*h[4, 1] + 2*h[5]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> E = L.Sets() >>> F = E(E.restrict(Integer(1))) >>> F.cycle_index_series()[Integer(5)] h[2, 2, 1] - h[3, 1, 1] + 3*h[3, 2] + 2*h[4, 1] + 2*h[5]
- generating_series()[source]¶
Return the (exponential) generating series of
self.EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: E = L.Sets() sage: F = E(E.restrict(1)) sage: F.generating_series() 1 + X + X^2 + 5/6*X^3 + 5/8*X^4 + 13/30*X^5 + 203/720*X^6 + O(X^7)
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> E = L.Sets() >>> F = E(E.restrict(Integer(1))) >>> F.generating_series() 1 + X + X^2 + 5/6*X^3 + 5/8*X^4 + 13/30*X^5 + 203/720*X^6 + O(X^7)
- structures(*labels)[source]¶
Iterate over the structures on the given set of labels.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: E = L.Sets() sage: E1 = L.Sets().restrict(1) sage: sorted(E(E1).structures([1,2,3])) [((((1, 'X'),), ((2, 'X'),), ((3, 'X'),)), ((1,), (2,), (3,))), ((((1, 'X'),), ((2, 'X'), (3, 'X'))), ((1,), (2, 3))), ((((1, 'X'), (2, 'X')), ((3, 'X'),)), ((1, 2), (3,))), ((((1, 'X'), (2, 'X'), (3, 'X')),), ((1, 2, 3),)), ((((1, 'X'), (3, 'X')), ((2, 'X'),)), ((1, 3), (2,)))] sage: C = L.Cycles() sage: L.<X, Y> = LazyCombinatorialSpecies(QQ) sage: sum(1 for s in C(X*Y).structures([1,2,3], [1,2,3])) 12 sage: C(X*Y).generating_series()[6] 1/3*X^3*Y^3 sage: sum(1 for s in E(X*Y).structures([1,2,3], ["a", "b", "c"])) 6
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> E = L.Sets() >>> E1 = L.Sets().restrict(Integer(1)) >>> sorted(E(E1).structures([Integer(1),Integer(2),Integer(3)])) [((((1, 'X'),), ((2, 'X'),), ((3, 'X'),)), ((1,), (2,), (3,))), ((((1, 'X'),), ((2, 'X'), (3, 'X'))), ((1,), (2, 3))), ((((1, 'X'), (2, 'X')), ((3, 'X'),)), ((1, 2), (3,))), ((((1, 'X'), (2, 'X'), (3, 'X')),), ((1, 2, 3),)), ((((1, 'X'), (3, 'X')), ((2, 'X'),)), ((1, 3), (2,)))] >>> C = L.Cycles() >>> L = LazyCombinatorialSpecies(QQ, names=('X', 'Y',)); (X, Y,) = L._first_ngens(2) >>> sum(Integer(1) for s in C(X*Y).structures([Integer(1),Integer(2),Integer(3)], [Integer(1),Integer(2),Integer(3)])) 12 >>> C(X*Y).generating_series()[Integer(6)] 1/3*X^3*Y^3 >>> sum(Integer(1) for s in E(X*Y).structures([Integer(1),Integer(2),Integer(3)], ["a", "b", "c"])) 6
- class sage.rings.lazy_species.CycleSpecies(parent)[source]¶
Bases:
LazyCombinatorialSpeciesElement,UniqueRepresentationInitialize the species of cycles.
- generating_series()[source]¶
Return the (exponential) generating series of the species of cycles.
This is \(-log(1-x)\).
EXAMPLES:
sage: L.<X> = LazyCombinatorialSpecies(QQ) sage: L.Cycles().generating_series() X + 1/2*X^2 + 1/3*X^3 + 1/4*X^4 + 1/5*X^5 + 1/6*X^6 + 1/7*X^7 + O(X^8)
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, names=('X',)); (X,) = L._first_ngens(1) >>> L.Cycles().generating_series() X + 1/2*X^2 + 1/3*X^3 + 1/4*X^4 + 1/5*X^5 + 1/6*X^6 + 1/7*X^7 + O(X^8)
- isotype_generating_series()[source]¶
Return the isotype generating series of the species of cycles.
This is \(x/(1-x)\).
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: L.Cycles().isotype_generating_series() X + X^2 + X^3 + O(X^4)
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> L.Cycles().isotype_generating_series() X + X^2 + X^3 + O(X^4)
- structures(labels)[source]¶
Iterate over the structures on the given set of labels.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(ZZ, "X") sage: C = L.Cycles() sage: list(C.structures([])) [] sage: list(C.structures([1])) [(1,)] sage: list(C.structures([1,2])) [(1, 2)] sage: list(C.structures([1,2,3])) [(1, 2, 3), (1, 3, 2)]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(ZZ, "X") >>> C = L.Cycles() >>> list(C.structures([])) [] >>> list(C.structures([Integer(1)])) [(1,)] >>> list(C.structures([Integer(1),Integer(2)])) [(1, 2)] >>> list(C.structures([Integer(1),Integer(2),Integer(3)])) [(1, 2, 3), (1, 3, 2)]
- class sage.rings.lazy_species.GraphSpecies(parent)[source]¶
Bases:
LazyCombinatorialSpeciesElementGeneratingSeriesMixin,LazyCombinatorialSpeciesElement,UniqueRepresentationInitialize the species of simple graphs.
- cycle_index_series()[source]¶
Return the cycle index series of the species of simple graphs.
The cycle index series is computed using Proposition 2.2.7 in [BLL1998].
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: L.Graphs().cycle_index_series().truncate(4) p[] + p[1] + (p[1,1]+p[2]) + (4/3*p[1,1,1]+2*p[2,1]+2/3*p[3])
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> L.Graphs().cycle_index_series().truncate(Integer(4)) p[] + p[1] + (p[1,1]+p[2]) + (4/3*p[1,1,1]+2*p[2,1]+2/3*p[3])
Check that the number of isomorphism types is computed quickly:
sage: L.Graphs().isotype_generating_series()[20] 645490122795799841856164638490742749440
>>> from sage.all import * >>> L.Graphs().isotype_generating_series()[Integer(20)] 645490122795799841856164638490742749440
- generating_series()[source]¶
Return the (exponential) generating series of the species of simple graphs.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: L.Graphs().generating_series().truncate(7) 1 + X + X^2 + 4/3*X^3 + 8/3*X^4 + 128/15*X^5 + 2048/45*X^6
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> L.Graphs().generating_series().truncate(Integer(7)) 1 + X + X^2 + 4/3*X^3 + 8/3*X^4 + 128/15*X^5 + 2048/45*X^6
- isotypes(labels)[source]¶
Iterate over the isotypes on the given list of sizes.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: G = L.Graphs() sage: list(G.isotypes(2)) [Graph on 2 vertices, Graph on 2 vertices]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> G = L.Graphs() >>> list(G.isotypes(Integer(2))) [Graph on 2 vertices, Graph on 2 vertices]
- class sage.rings.lazy_species.LazyCombinatorialSpecies(base_ring, names, sparse)[source]¶
Bases:
LazyCompletionGradedAlgebraThe ring of lazy species.
EXAMPLES:
We provide univariate and multivariate (mostly known as multisort) species:
sage: LazyCombinatorialSpecies(QQ, "X") Lazy completion of Polynomial species in X over Rational Field sage: LazyCombinatorialSpecies(QQ, "X, Y") Lazy completion of Polynomial species in X, Y over Rational Field
>>> from sage.all import * >>> LazyCombinatorialSpecies(QQ, "X") Lazy completion of Polynomial species in X over Rational Field >>> LazyCombinatorialSpecies(QQ, "X, Y") Lazy completion of Polynomial species in X, Y over Rational Field
In the univariate case, several basic species are provided as methods:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: L.Sets() Set species sage: L.Cycles() Cycle species sage: L.OrientedSets() Oriented Set species sage: L.Polygons() Polygon species sage: L.Graphs() Graph species sage: L.SetPartitions() Set Partition species
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> L.Sets() Set species >>> L.Cycles() Cycle species >>> L.OrientedSets() Oriented Set species >>> L.Polygons() Polygon species >>> L.Graphs() Graph species >>> L.SetPartitions() Set Partition species
- Element[source]¶
alias of
LazyCombinatorialSpeciesElement
- class sage.rings.lazy_species.LazyCombinatorialSpeciesElement(parent, coeff_stream)[source]¶
Bases:
LazyCompletionGradedAlgebraElementEXAMPLES:
Compute the molecular expansion of \(E(-X)\):
sage: L = LazyCombinatorialSpecies(ZZ, "X") sage: E = L(SymmetricGroup) sage: E_inv = 1 / E sage: E_inv 1 + (-X) + (-E_2+X^2) + (-E_3+2*X*E_2-X^3) + (-E_4+2*X*E_3+E_2^2-3*X^2*E_2+X^4) + (-E_5+2*X*E_4+2*E_2*E_3-3*X^2*E_3-3*X*E_2^2+4*X^3*E_2-X^5) + (-E_6+2*X*E_5+2*E_2*E_4-3*X^2*E_4+E_3^2-6*X*E_2*E_3+4*X^3*E_3-E_2^3+6*X^2*E_2^2-5*X^4*E_2+X^6) + O^7
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(ZZ, "X") >>> E = L(SymmetricGroup) >>> E_inv = Integer(1) / E >>> E_inv 1 + (-X) + (-E_2+X^2) + (-E_3+2*X*E_2-X^3) + (-E_4+2*X*E_3+E_2^2-3*X^2*E_2+X^4) + (-E_5+2*X*E_4+2*E_2*E_3-3*X^2*E_3-3*X*E_2^2+4*X^3*E_2-X^5) + (-E_6+2*X*E_5+2*E_2*E_4-3*X^2*E_4+E_3^2-6*X*E_2*E_3+4*X^3*E_3-E_2^3+6*X^2*E_2^2-5*X^4*E_2+X^6) + O^7
Compare with the explicit formula:
sage: def coefficient(m): ....: return sum((-1)^len(la) * multinomial((n := la.to_exp())) * prod(E[i]^ni for i, ni in enumerate(n, 1)) for la in Partitions(m)) sage: all(coefficient(m) == E_inv[m] for m in range(10)) True
>>> from sage.all import * >>> def coefficient(m): ... return sum((-Integer(1))**len(la) * multinomial((n := la.to_exp())) * prod(E[i]**ni for i, ni in enumerate(n, Integer(1))) for la in Partitions(m)) >>> all(coefficient(m) == E_inv[m] for m in range(Integer(10))) True
- combinatorial_logarithm()[source]¶
Return the combinatorial logarithm of
self.This is the series reversion of the species of non-empty sets applied to
self - 1.EXAMPLES:
sage: L.<X> = LazyCombinatorialSpecies(QQ) sage: L.Sets().restrict(1).revert() - (1+X).combinatorial_logarithm() O^7
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, names=('X',)); (X,) = L._first_ngens(1) >>> L.Sets().restrict(Integer(1)).revert() - (Integer(1)+X).combinatorial_logarithm() O^7
This method is much faster, however:
sage: (1+X).combinatorial_logarithm().generating_series()[10] -1/10
>>> from sage.all import * >>> (Integer(1)+X).combinatorial_logarithm().generating_series()[Integer(10)] -1/10
- compositional_inverse()[source]¶
Return the compositional inverse of
self.EXAMPLES:
sage: L.<X> = LazyCombinatorialSpecies(QQ) sage: E1 = L.Sets().restrict(1) sage: g = E1.revert() sage: g[:5] [X, -E_2, -E_3 + X*E_2, -E_4 + E_2(E_2) + X*E_3 - X^2*E_2] sage: E = L.Sets() sage: P = E(X*E1(-X))*(1+X) - 1 sage: P.revert()[:5] [X, X^2, X*E_2 + 2*X^3, X*E_3 + 2*X^2*E_2 + E_2(X^2) + 5*X^4]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, names=('X',)); (X,) = L._first_ngens(1) >>> E1 = L.Sets().restrict(Integer(1)) >>> g = E1.revert() >>> g[:Integer(5)] [X, -E_2, -E_3 + X*E_2, -E_4 + E_2(E_2) + X*E_3 - X^2*E_2] >>> E = L.Sets() >>> P = E(X*E1(-X))*(Integer(1)+X) - Integer(1) >>> P.revert()[:Integer(5)] [X, X^2, X*E_2 + 2*X^3, X*E_3 + 2*X^2*E_2 + E_2(X^2) + 5*X^4]
- cycle_index_series()[source]¶
Return the cycle index series for this species.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(ZZ, "X") sage: E = L.Sets() sage: h = SymmetricFunctions(QQ).h() sage: LazySymmetricFunctions(h)(E.cycle_index_series()) h[] + h[1] + h[2] + h[3] + h[4] + h[5] + h[6] + O^7 sage: s = SymmetricFunctions(QQ).s() sage: C = L.Cycles() sage: s(C.cycle_index_series()[5]) s[1, 1, 1, 1, 1] + s[2, 2, 1] + 2*s[3, 1, 1] + s[3, 2] + s[5] sage: L = LazyCombinatorialSpecies(QQ, "X") sage: E = L.Sets() sage: L2.<X, Y> = LazyCombinatorialSpecies(QQ) sage: E(X + Y).cycle_index_series()[3] 1/6*p[] # p[1, 1, 1] + 1/2*p[] # p[2, 1] + 1/3*p[] # p[3] + 1/2*p[1] # p[1, 1] + 1/2*p[1] # p[2] + 1/2*p[1, 1] # p[1] + 1/6*p[1, 1, 1] # p[] + 1/2*p[2] # p[1] + 1/2*p[2, 1] # p[] + 1/3*p[3] # p[]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(ZZ, "X") >>> E = L.Sets() >>> h = SymmetricFunctions(QQ).h() >>> LazySymmetricFunctions(h)(E.cycle_index_series()) h[] + h[1] + h[2] + h[3] + h[4] + h[5] + h[6] + O^7 >>> s = SymmetricFunctions(QQ).s() >>> C = L.Cycles() >>> s(C.cycle_index_series()[Integer(5)]) s[1, 1, 1, 1, 1] + s[2, 2, 1] + 2*s[3, 1, 1] + s[3, 2] + s[5] >>> L = LazyCombinatorialSpecies(QQ, "X") >>> E = L.Sets() >>> L2 = LazyCombinatorialSpecies(QQ, names=('X', 'Y',)); (X, Y,) = L2._first_ngens(2) >>> E(X + Y).cycle_index_series()[Integer(3)] 1/6*p[] # p[1, 1, 1] + 1/2*p[] # p[2, 1] + 1/3*p[] # p[3] + 1/2*p[1] # p[1, 1] + 1/2*p[1] # p[2] + 1/2*p[1, 1] # p[1] + 1/6*p[1, 1, 1] # p[] + 1/2*p[2] # p[1] + 1/2*p[2, 1] # p[] + 1/3*p[3] # p[]
- generating_series()[source]¶
Return the (exponential) generating series of
self.EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: E = L.Sets() sage: E.generating_series() 1 + X + 1/2*X^2 + 1/6*X^3 + 1/24*X^4 + 1/120*X^5 + 1/720*X^6 + O(X^7) sage: C = L.Cycles() sage: C.generating_series() X + 1/2*X^2 + 1/3*X^3 + 1/4*X^4 + 1/5*X^5 + 1/6*X^6 + 1/7*X^7 + O(X^8) sage: L2.<X, Y> = LazyCombinatorialSpecies(QQ) sage: E(X + Y).generating_series() 1 + (X+Y) + (1/2*X^2+X*Y+1/2*Y^2) + (1/6*X^3+1/2*X^2*Y+1/2*X*Y^2+1/6*Y^3) + (1/24*X^4+1/6*X^3*Y+1/4*X^2*Y^2+1/6*X*Y^3+1/24*Y^4) + (1/120*X^5+1/24*X^4*Y+1/12*X^3*Y^2+1/12*X^2*Y^3+1/24*X*Y^4+1/120*Y^5) + (1/720*X^6+1/120*X^5*Y+1/48*X^4*Y^2+1/36*X^3*Y^3+1/48*X^2*Y^4+1/120*X*Y^5+1/720*Y^6) + O(X,Y)^7 sage: C(X + Y).generating_series() (X+Y) + (1/2*X^2+X*Y+1/2*Y^2) + (1/3*X^3+X^2*Y+X*Y^2+1/3*Y^3) + (1/4*X^4+X^3*Y+3/2*X^2*Y^2+X*Y^3+1/4*Y^4) + (1/5*X^5+X^4*Y+2*X^3*Y^2+2*X^2*Y^3+X*Y^4+1/5*Y^5) + (1/6*X^6+X^5*Y+5/2*X^4*Y^2+10/3*X^3*Y^3+5/2*X^2*Y^4+X*Y^5+1/6*Y^6) + (1/7*X^7+X^6*Y+3*X^5*Y^2+5*X^4*Y^3+5*X^3*Y^4+3*X^2*Y^5+X*Y^6+1/7*Y^7) + O(X,Y)^8
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> E = L.Sets() >>> E.generating_series() 1 + X + 1/2*X^2 + 1/6*X^3 + 1/24*X^4 + 1/120*X^5 + 1/720*X^6 + O(X^7) >>> C = L.Cycles() >>> C.generating_series() X + 1/2*X^2 + 1/3*X^3 + 1/4*X^4 + 1/5*X^5 + 1/6*X^6 + 1/7*X^7 + O(X^8) >>> L2 = LazyCombinatorialSpecies(QQ, names=('X', 'Y',)); (X, Y,) = L2._first_ngens(2) >>> E(X + Y).generating_series() 1 + (X+Y) + (1/2*X^2+X*Y+1/2*Y^2) + (1/6*X^3+1/2*X^2*Y+1/2*X*Y^2+1/6*Y^3) + (1/24*X^4+1/6*X^3*Y+1/4*X^2*Y^2+1/6*X*Y^3+1/24*Y^4) + (1/120*X^5+1/24*X^4*Y+1/12*X^3*Y^2+1/12*X^2*Y^3+1/24*X*Y^4+1/120*Y^5) + (1/720*X^6+1/120*X^5*Y+1/48*X^4*Y^2+1/36*X^3*Y^3+1/48*X^2*Y^4+1/120*X*Y^5+1/720*Y^6) + O(X,Y)^7 >>> C(X + Y).generating_series() (X+Y) + (1/2*X^2+X*Y+1/2*Y^2) + (1/3*X^3+X^2*Y+X*Y^2+1/3*Y^3) + (1/4*X^4+X^3*Y+3/2*X^2*Y^2+X*Y^3+1/4*Y^4) + (1/5*X^5+X^4*Y+2*X^3*Y^2+2*X^2*Y^3+X*Y^4+1/5*Y^5) + (1/6*X^6+X^5*Y+5/2*X^4*Y^2+10/3*X^3*Y^3+5/2*X^2*Y^4+X*Y^5+1/6*Y^6) + (1/7*X^7+X^6*Y+3*X^5*Y^2+5*X^4*Y^3+5*X^3*Y^4+3*X^2*Y^5+X*Y^6+1/7*Y^7) + O(X,Y)^8
- isotype_generating_series()[source]¶
Return the isotype generating series of
self.EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: E = L(SymmetricGroup) sage: E.isotype_generating_series() 1 + X + X^2 + X^3 + X^4 + X^5 + X^6 + O(X^7) sage: C = L(CyclicPermutationGroup, valuation=1) sage: E(C).isotype_generating_series() 1 + X + 2*X^2 + 3*X^3 + 5*X^4 + 7*X^5 + 11*X^6 + O(X^7) sage: L2.<X, Y> = LazyCombinatorialSpecies(QQ) sage: E(X + Y).isotype_generating_series() 1 + (X+Y) + (X^2+X*Y+Y^2) + (X^3+X^2*Y+X*Y^2+Y^3) + (X^4+X^3*Y+X^2*Y^2+X*Y^3+Y^4) + (X^5+X^4*Y+X^3*Y^2+X^2*Y^3+X*Y^4+Y^5) + (X^6+X^5*Y+X^4*Y^2+X^3*Y^3+X^2*Y^4+X*Y^5+Y^6) + O(X,Y)^7 sage: C(X + Y).isotype_generating_series() (X+Y) + (X^2+X*Y+Y^2) + (X^3+X^2*Y+X*Y^2+Y^3) + (X^4+X^3*Y+2*X^2*Y^2+X*Y^3+Y^4) + (X^5+X^4*Y+2*X^3*Y^2+2*X^2*Y^3+X*Y^4+Y^5) + (X^6+X^5*Y+3*X^4*Y^2+4*X^3*Y^3+3*X^2*Y^4+X*Y^5+Y^6) + O(X,Y)^7
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> E = L(SymmetricGroup) >>> E.isotype_generating_series() 1 + X + X^2 + X^3 + X^4 + X^5 + X^6 + O(X^7) >>> C = L(CyclicPermutationGroup, valuation=Integer(1)) >>> E(C).isotype_generating_series() 1 + X + 2*X^2 + 3*X^3 + 5*X^4 + 7*X^5 + 11*X^6 + O(X^7) >>> L2 = LazyCombinatorialSpecies(QQ, names=('X', 'Y',)); (X, Y,) = L2._first_ngens(2) >>> E(X + Y).isotype_generating_series() 1 + (X+Y) + (X^2+X*Y+Y^2) + (X^3+X^2*Y+X*Y^2+Y^3) + (X^4+X^3*Y+X^2*Y^2+X*Y^3+Y^4) + (X^5+X^4*Y+X^3*Y^2+X^2*Y^3+X*Y^4+Y^5) + (X^6+X^5*Y+X^4*Y^2+X^3*Y^3+X^2*Y^4+X*Y^5+Y^6) + O(X,Y)^7 >>> C(X + Y).isotype_generating_series() (X+Y) + (X^2+X*Y+Y^2) + (X^3+X^2*Y+X*Y^2+Y^3) + (X^4+X^3*Y+2*X^2*Y^2+X*Y^3+Y^4) + (X^5+X^4*Y+2*X^3*Y^2+2*X^2*Y^3+X*Y^4+Y^5) + (X^6+X^5*Y+3*X^4*Y^2+4*X^3*Y^3+3*X^2*Y^4+X*Y^5+Y^6) + O(X,Y)^7
- isotypes(*shape)[source]¶
Iterate over the isotypes on the given list of sizes.
Generically, this yields a list of tuples consisting of a molecular species and, if necessary, an index.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: E = L(SymmetricGroup) sage: list(E.isotypes(3)) [(E_3,)] sage: P = L(CyclicPermutationGroup, valuation=1) sage: list(P.isotypes(3)) [(C_3,)] sage: F = 1/(2-E) sage: sorted(F.isotypes(3)) [(E_3,), (X*E_2, 0), (X*E_2, 1), (X^3,)] sage: from sage.rings.species import PolynomialSpecies sage: L = LazyCombinatorialSpecies(QQ, "X, Y") sage: P = PolynomialSpecies(QQ, "X, Y") sage: XY = L(P(PermutationGroup([], domain=[1, 2]), {0: [1], 1: [2]})) sage: list((XY).isotypes(1, 1)) [(X*Y,)] sage: list(E(XY).isotypes(2, 2)) [(E_2(X*Y),)]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> E = L(SymmetricGroup) >>> list(E.isotypes(Integer(3))) [(E_3,)] >>> P = L(CyclicPermutationGroup, valuation=Integer(1)) >>> list(P.isotypes(Integer(3))) [(C_3,)] >>> F = Integer(1)/(Integer(2)-E) >>> sorted(F.isotypes(Integer(3))) [(E_3,), (X*E_2, 0), (X*E_2, 1), (X^3,)] >>> from sage.rings.species import PolynomialSpecies >>> L = LazyCombinatorialSpecies(QQ, "X, Y") >>> P = PolynomialSpecies(QQ, "X, Y") >>> XY = L(P(PermutationGroup([], domain=[Integer(1), Integer(2)]), {Integer(0): [Integer(1)], Integer(1): [Integer(2)]})) >>> list((XY).isotypes(Integer(1), Integer(1))) [(X*Y,)] >>> list(E(XY).isotypes(Integer(2), Integer(2))) [(E_2(X*Y),)]
- polynomial(degree=None, names=None)[source]¶
Return
selfas a polynomial ifselfis actually so or up to specified degree.INPUT:
degree– (optional) integernames– (default: name of the variables of the series) names of the variables
OUTPUT:
If
degreeis notNone, the terms of the series of degree greater thandegreeare first truncated. IfdegreeisNoneand the series is not a polynomial polynomial, aValueErroris raised.EXAMPLES:
sage: L = LazyCombinatorialSpecies(ZZ, "X") sage: E = L(SymmetricGroup) sage: E.polynomial(3) 1 + X + E_2 + E_3
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(ZZ, "X") >>> E = L(SymmetricGroup) >>> E.polynomial(Integer(3)) 1 + X + E_2 + E_3
- restrict(min_degree=None, max_degree=None)[source]¶
Return the series obtained by keeping only terms of degree between
min_degreeandmax_degree.INPUT:
min_degree,max_degree– (optional) integers indicating which degrees to keep
EXAMPLES:
sage: L = LazyCombinatorialSpecies(ZZ, "X") sage: G = L.Graphs() sage: list(G.isotypes(2)) [Graph on 2 vertices, Graph on 2 vertices] sage: list(G.restrict(2, 2).isotypes(2)) [Graph on 2 vertices, Graph on 2 vertices]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(ZZ, "X") >>> G = L.Graphs() >>> list(G.isotypes(Integer(2))) [Graph on 2 vertices, Graph on 2 vertices] >>> list(G.restrict(Integer(2), Integer(2)).isotypes(Integer(2))) [Graph on 2 vertices, Graph on 2 vertices]
- revert()[source]¶
Return the compositional inverse of
self.EXAMPLES:
sage: L.<X> = LazyCombinatorialSpecies(QQ) sage: E1 = L.Sets().restrict(1) sage: g = E1.revert() sage: g[:5] [X, -E_2, -E_3 + X*E_2, -E_4 + E_2(E_2) + X*E_3 - X^2*E_2] sage: E = L.Sets() sage: P = E(X*E1(-X))*(1+X) - 1 sage: P.revert()[:5] [X, X^2, X*E_2 + 2*X^3, X*E_3 + 2*X^2*E_2 + E_2(X^2) + 5*X^4]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, names=('X',)); (X,) = L._first_ngens(1) >>> E1 = L.Sets().restrict(Integer(1)) >>> g = E1.revert() >>> g[:Integer(5)] [X, -E_2, -E_3 + X*E_2, -E_4 + E_2(E_2) + X*E_3 - X^2*E_2] >>> E = L.Sets() >>> P = E(X*E1(-X))*(Integer(1)+X) - Integer(1) >>> P.revert()[:Integer(5)] [X, X^2, X*E_2 + 2*X^3, X*E_3 + 2*X^2*E_2 + E_2(X^2) + 5*X^4]
- structures(*labels)[source]¶
Iterate over the structures on the given set of labels.
Generically, this yields a list of pairs consisting of a molecular species and a relabelled representative of the cosets of corresponding groups.
The relabelling is such that the first few labels correspond to the first factor in the atomic decomposition, etc.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: E = L(SymmetricGroup) sage: list(E.structures([1,2,3])) [(E_3, ((1, 2, 3),))] sage: C = L(CyclicPermutationGroup, valuation=1) sage: list(C.structures([1,2,3])) [(C_3, ((1, 2, 3),)), (C_3, ((1, 3, 2),))] sage: F = 1/(2-E) sage: sorted(F.structures([1,2,3])) [(E_3, ((1, 2, 3),)), (X*E_2, ((1,), (2, 3)), 0), (X*E_2, ((1,), (2, 3)), 1), (X*E_2, ((2,), (1, 3)), 0), (X*E_2, ((2,), (1, 3)), 1), (X*E_2, ((3,), (1, 2)), 0), (X*E_2, ((3,), (1, 2)), 1), (X^3, ((1,), (2,), (3,))), (X^3, ((1,), (3,), (2,))), (X^3, ((2,), (1,), (3,))), (X^3, ((2,), (3,), (1,))), (X^3, ((3,), (1,), (2,))), (X^3, ((3,), (2,), (1,)))] sage: from sage.rings.species import PolynomialSpecies sage: L = LazyCombinatorialSpecies(QQ, "X, Y") sage: P = PolynomialSpecies(QQ, "X, Y") sage: XY = L(P(PermutationGroup([], domain=[1, 2]), {0: [1], 1: [2]})) sage: list((XY).structures([1], ["a"])) [(X*Y, ((1,), ('a',)))] sage: sorted(E(XY).structures([1,2], [3, 4])) [((E_2, ((((1, 'X'), (3, 'Y')), ((2, 'X'), (4, 'Y'))),)), ((X*Y, ((1,), (3,))), (X*Y, ((2,), (4,))))), ((E_2, ((((1, 'X'), (4, 'Y')), ((2, 'X'), (3, 'Y'))),)), ((X*Y, ((1,), (4,))), (X*Y, ((2,), (3,)))))] sage: list(XY.structures([], [1, 2])) []
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> E = L(SymmetricGroup) >>> list(E.structures([Integer(1),Integer(2),Integer(3)])) [(E_3, ((1, 2, 3),))] >>> C = L(CyclicPermutationGroup, valuation=Integer(1)) >>> list(C.structures([Integer(1),Integer(2),Integer(3)])) [(C_3, ((1, 2, 3),)), (C_3, ((1, 3, 2),))] >>> F = Integer(1)/(Integer(2)-E) >>> sorted(F.structures([Integer(1),Integer(2),Integer(3)])) [(E_3, ((1, 2, 3),)), (X*E_2, ((1,), (2, 3)), 0), (X*E_2, ((1,), (2, 3)), 1), (X*E_2, ((2,), (1, 3)), 0), (X*E_2, ((2,), (1, 3)), 1), (X*E_2, ((3,), (1, 2)), 0), (X*E_2, ((3,), (1, 2)), 1), (X^3, ((1,), (2,), (3,))), (X^3, ((1,), (3,), (2,))), (X^3, ((2,), (1,), (3,))), (X^3, ((2,), (3,), (1,))), (X^3, ((3,), (1,), (2,))), (X^3, ((3,), (2,), (1,)))] >>> from sage.rings.species import PolynomialSpecies >>> L = LazyCombinatorialSpecies(QQ, "X, Y") >>> P = PolynomialSpecies(QQ, "X, Y") >>> XY = L(P(PermutationGroup([], domain=[Integer(1), Integer(2)]), {Integer(0): [Integer(1)], Integer(1): [Integer(2)]})) >>> list((XY).structures([Integer(1)], ["a"])) [(X*Y, ((1,), ('a',)))] >>> sorted(E(XY).structures([Integer(1),Integer(2)], [Integer(3), Integer(4)])) [((E_2, ((((1, 'X'), (3, 'Y')), ((2, 'X'), (4, 'Y'))),)), ((X*Y, ((1,), (3,))), (X*Y, ((2,), (4,))))), ((E_2, ((((1, 'X'), (4, 'Y')), ((2, 'X'), (3, 'Y'))),)), ((X*Y, ((1,), (4,))), (X*Y, ((2,), (3,)))))] >>> list(XY.structures([], [Integer(1), Integer(2)])) []
- class sage.rings.lazy_species.LazyCombinatorialSpeciesElementGeneratingSeriesMixin[source]¶
Bases:
objectA lazy species element whose generating series are obtained by specializing the cycle index series rather than the molecular expansion.
- generating_series()[source]¶
Return the (exponential) generating series of
self.The series is obtained by applying the exponential specialization to the cycle index series.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: L.Graphs().generating_series().truncate(7) 1 + X + X^2 + 4/3*X^3 + 8/3*X^4 + 128/15*X^5 + 2048/45*X^6
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> L.Graphs().generating_series().truncate(Integer(7)) 1 + X + X^2 + 4/3*X^3 + 8/3*X^4 + 128/15*X^5 + 2048/45*X^6
- isotype_generating_series()[source]¶
Return the isotype generating series of
self.The series is obtained by applying the principal specialization of order \(1\) to the cycle index series, that is, setting \(x_1 = x\) and \(x_k = 0\) for \(k > 1\).
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: L.Graphs().isotype_generating_series().truncate(8) 1 + X + 2*X^2 + 4*X^3 + 11*X^4 + 34*X^5 + 156*X^6 + 1044*X^7
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> L.Graphs().isotype_generating_series().truncate(Integer(8)) 1 + X + 2*X^2 + 4*X^3 + 11*X^4 + 34*X^5 + 156*X^6 + 1044*X^7
- class sage.rings.lazy_species.LazyCombinatorialSpeciesMultivariate(base_ring, names, sparse)[source]¶
Bases:
LazyCombinatorialSpecies
- class sage.rings.lazy_species.LazyCombinatorialSpeciesUnivariate(base_ring, names, sparse)[source]¶
Bases:
LazyCombinatorialSpecies- Chains()[source]¶
Return the species of chains.
Chains are linear orders up to reversal.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: Ch = L.Chains() sage: set(Ch.isotypes(4)) {(E_2(X^2),)} sage: list(Ch.structures(["a", "b", "c"])) [('a', 'c', 'b'), ('a', 'b', 'c'), ('b', 'a', 'c')]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> Ch = L.Chains() >>> set(Ch.isotypes(Integer(4))) {(E_2(X^2),)} >>> list(Ch.structures(["a", "b", "c"])) [('a', 'c', 'b'), ('a', 'b', 'c'), ('b', 'a', 'c')]
- Cycles()[source]¶
Return the species of (oriented) cycles.
This species corresponds to the sequence of group actions having the cyclic groups as stabilizers.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: G = L.Cycles() sage: set(G.isotypes(4)) {(C_4,)} sage: set(G.structures(["a", "b", "c"])) {('a', 'b', 'c'), ('a', 'c', 'b')}
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> G = L.Cycles() >>> set(G.isotypes(Integer(4))) {(C_4,)} >>> set(G.structures(["a", "b", "c"])) {('a', 'b', 'c'), ('a', 'c', 'b')}
- Graphs()[source]¶
Return the species of vertex labelled simple graphs.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: G = L.Graphs() sage: set(G.isotypes(2)) {Graph on 2 vertices, Graph on 2 vertices} sage: G.isotype_generating_series()[20] 645490122795799841856164638490742749440
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> G = L.Graphs() >>> set(G.isotypes(Integer(2))) {Graph on 2 vertices, Graph on 2 vertices} >>> G.isotype_generating_series()[Integer(20)] 645490122795799841856164638490742749440
- OrientedSets()[source]¶
Return the species of oriented sets.
Oriented sets are total orders up to an even orientation.
This species corresponds to the sequence of group actions having the alternating groups as stabilizers.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: G = L.OrientedSets() sage: set(G.isotypes(5)) {(Eo_5,)} sage: set(G.structures(["a", 1, "b", 2])) {(Eo_4, ((1, 2, 'a', 'b'),)), (Eo_4, ((1, 2, 'b', 'a'),))}
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> G = L.OrientedSets() >>> set(G.isotypes(Integer(5))) {(Eo_5,)} >>> set(G.structures(["a", Integer(1), "b", Integer(2)])) {(Eo_4, ((1, 2, 'a', 'b'),)), (Eo_4, ((1, 2, 'b', 'a'),))}
- Polygons()[source]¶
Return the species of polygons.
Polygons are cycles up to orientation.
This species corresponds to the sequence of group actions having the dihedral groups as stabilizers.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: G = L.Polygons() sage: set(G.isotypes(5)) {(P_5,)} sage: set(G.structures(["a", 1, "b", 2])) {(E_2(E_2), ((1, 'a', 2, 'b'),)), (E_2(E_2), ((1, 'b', 2, 'a'),)), (E_2(E_2), ((1, 2, 'a', 'b'),))}
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> G = L.Polygons() >>> set(G.isotypes(Integer(5))) {(P_5,)} >>> set(G.structures(["a", Integer(1), "b", Integer(2)])) {(E_2(E_2), ((1, 'a', 2, 'b'),)), (E_2(E_2), ((1, 'b', 2, 'a'),)), (E_2(E_2), ((1, 2, 'a', 'b'),))}
- SetPartitions()[source]¶
Return the species of set partitions.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: G = L.SetPartitions() sage: set(G.isotypes(4)) {[1, 1, 1, 1], [2, 1, 1], [2, 2], [3, 1], [4]} sage: list(G.structures(["a", "b", "c"])) [{{'a', 'b', 'c'}}, {{'a', 'b'}, {'c'}}, {{'a', 'c'}, {'b'}}, {{'a'}, {'b', 'c'}}, {{'a'}, {'b'}, {'c'}}]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> G = L.SetPartitions() >>> set(G.isotypes(Integer(4))) {[1, 1, 1, 1], [2, 1, 1], [2, 2], [3, 1], [4]} >>> list(G.structures(["a", "b", "c"])) [{{'a', 'b', 'c'}}, {{'a', 'b'}, {'c'}}, {{'a', 'c'}, {'b'}}, {{'a'}, {'b', 'c'}}, {{'a'}, {'b'}, {'c'}}]
- Sets()[source]¶
Return the species of sets.
This species corresponds to the sequence of trivial group actions. Put differently, the stabilizers are the full symmetric groups.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: G = L.Sets() sage: set(G.isotypes(4)) {(E_4,)} sage: set(G.structures(["a", 1, x])) {(1, 'a', x)}
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> G = L.Sets() >>> set(G.isotypes(Integer(4))) {(E_4,)} >>> set(G.structures(["a", Integer(1), x])) {(1, 'a', x)}
- class sage.rings.lazy_species.OrientedSetSpecies(parent)[source]¶
Bases:
LazyCombinatorialSpeciesElement,UniqueRepresentationInitialize the species of polygons.
- class sage.rings.lazy_species.PolygonSpecies(parent)[source]¶
Bases:
LazyCombinatorialSpeciesElement,UniqueRepresentationInitialize the species of polygons.
- class sage.rings.lazy_species.ProductSpeciesElement(left, right)[source]¶
Bases:
LazyCombinatorialSpeciesElementInitialize the product of two species.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: F = L.Sets() * L.SetPartitions() sage: TestSuite(F).run(skip=['_test_category', '_test_pickling'])
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> F = L.Sets() * L.SetPartitions() >>> TestSuite(F).run(skip=['_test_category', '_test_pickling'])
- generating_series()[source]¶
Return the (exponential) generating series of
self.EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: E = L.Sets() sage: F = E*E sage: F.generating_series() 1 + 2*X + 2*X^2 + 4/3*X^3 + 2/3*X^4 + 4/15*X^5 + 4/45*X^6 + O(X^7)
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> E = L.Sets() >>> F = E*E >>> F.generating_series() 1 + 2*X + 2*X^2 + 4/3*X^3 + 2/3*X^4 + 4/15*X^5 + 4/45*X^6 + O(X^7)
- isotype_generating_series()[source]¶
Return the isotype generating series of
self.EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: E = L.Sets() sage: F = E*E sage: F.isotype_generating_series() 1 + 2*X + 3*X^2 + 4*X^3 + 5*X^4 + 6*X^5 + 7*X^6 + O(X^7)
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> E = L.Sets() >>> F = E*E >>> F.isotype_generating_series() 1 + 2*X + 3*X^2 + 4*X^3 + 5*X^4 + 6*X^5 + 7*X^6 + O(X^7)
- structures(*labels)[source]¶
Iterate over the structures on the given set of labels.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(ZZ, "X") sage: E = L.Sets() sage: C = L.Cycles() sage: P = E * C sage: list(P.structures([1,2])) [((), (1, 2)), ((1,), (2,)), ((2,), (1,))] sage: P = E * E sage: list(P.structures([1,2])) [((), (1, 2)), ((1,), (2,)), ((2,), (1,)), ((1, 2), ())] sage: L.<X, Y> = LazyCombinatorialSpecies(QQ) sage: list((X*Y).structures([1], [2])) [((X, ((1,),)), (Y, ((2,),)))]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(ZZ, "X") >>> E = L.Sets() >>> C = L.Cycles() >>> P = E * C >>> list(P.structures([Integer(1),Integer(2)])) [((), (1, 2)), ((1,), (2,)), ((2,), (1,))] >>> P = E * E >>> list(P.structures([Integer(1),Integer(2)])) [((), (1, 2)), ((1,), (2,)), ((2,), (1,)), ((1, 2), ())] >>> L = LazyCombinatorialSpecies(QQ, names=('X', 'Y',)); (X, Y,) = L._first_ngens(2) >>> list((X*Y).structures([Integer(1)], [Integer(2)])) [((X, ((1,),)), (Y, ((2,),)))]
- class sage.rings.lazy_species.RestrictedSpeciesElement(F, min_degree, max_degree)[source]¶
Bases:
LazyCombinatorialSpeciesElementInitialize the restriction of a species to the given degrees.
- cycle_index_series()[source]¶
Return the cycle index series for this species.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: E = L.Sets() sage: E.restrict(1, 5).cycle_index_series() h[1] + h[2] + h[3] + h[4] + h[5] sage: E.restrict(1).cycle_index_series() h[1] + h[2] + h[3] + h[4] + h[5] + h[6] + h[7] + O^8
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> E = L.Sets() >>> E.restrict(Integer(1), Integer(5)).cycle_index_series() h[1] + h[2] + h[3] + h[4] + h[5] >>> E.restrict(Integer(1)).cycle_index_series() h[1] + h[2] + h[3] + h[4] + h[5] + h[6] + h[7] + O^8
- generating_series()[source]¶
Return the (exponential) generating series of
self.EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: E = L.Sets() sage: E.restrict(1, 5).generating_series() X + 1/2*X^2 + 1/6*X^3 + 1/24*X^4 + 1/120*X^5 sage: E.restrict(1).generating_series() X + 1/2*X^2 + 1/6*X^3 + 1/24*X^4 + 1/120*X^5 + 1/720*X^6 + 1/5040*X^7 + O(X^8)
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> E = L.Sets() >>> E.restrict(Integer(1), Integer(5)).generating_series() X + 1/2*X^2 + 1/6*X^3 + 1/24*X^4 + 1/120*X^5 >>> E.restrict(Integer(1)).generating_series() X + 1/2*X^2 + 1/6*X^3 + 1/24*X^4 + 1/120*X^5 + 1/720*X^6 + 1/5040*X^7 + O(X^8)
- isotype_generating_series()[source]¶
Return the isotype generating series of
self.EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: E = L.Sets() sage: E.restrict(1, 5).isotype_generating_series() X + X^2 + X^3 + X^4 + X^5 sage: E.restrict(1).isotype_generating_series() X + X^2 + X^3 + O(X^4)
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> E = L.Sets() >>> E.restrict(Integer(1), Integer(5)).isotype_generating_series() X + X^2 + X^3 + X^4 + X^5 >>> E.restrict(Integer(1)).isotype_generating_series() X + X^2 + X^3 + O(X^4)
- isotypes(*shape)[source]¶
Iterate over the isotypes on the given list of sizes.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: p = L.SetPartitions().restrict(2, 2) sage: list(p.isotypes(3)) []
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> p = L.SetPartitions().restrict(Integer(2), Integer(2)) >>> list(p.isotypes(Integer(3))) []
- structures(*labels)[source]¶
Iterate over the structures on the given set of labels.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(ZZ, "X") sage: F = L.SetPartitions().restrict(3) sage: list(F.structures([1])) [] sage: list(F.structures([1,2,3])) [{{1, 2, 3}}, {{1, 2}, {3}}, {{1, 3}, {2}}, {{1}, {2, 3}}, {{1}, {2}, {3}}]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(ZZ, "X") >>> F = L.SetPartitions().restrict(Integer(3)) >>> list(F.structures([Integer(1)])) [] >>> list(F.structures([Integer(1),Integer(2),Integer(3)])) [{{1, 2, 3}}, {{1, 2}, {3}}, {{1, 3}, {2}}, {{1}, {2, 3}}, {{1}, {2}, {3}}]
- class sage.rings.lazy_species.SetPartitionSpecies(parent)[source]¶
Bases:
CompositionSpeciesElement,UniqueRepresentationInitialize the species of set partitions.
- generating_series()[source]¶
Return the (exponential) generating series of
self.EXAMPLES:
sage: L = LazyCombinatorialSpecies(ZZ, "X") sage: P = L.SetPartitions() sage: P.generating_series() 1 + X + X^2 + 5/6*X^3 + 5/8*X^4 + 13/30*X^5 + 203/720*X^6 + O(X^7)
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(ZZ, "X") >>> P = L.SetPartitions() >>> P.generating_series() 1 + X + X^2 + 5/6*X^3 + 5/8*X^4 + 13/30*X^5 + 203/720*X^6 + O(X^7)
- isotype_generating_series()[source]¶
Return the isotype generating series of
self.EXAMPLES:
sage: L = LazyCombinatorialSpecies(ZZ, "X") sage: P = L.SetPartitions() sage: P.isotype_generating_series() 1 + X + 2*X^2 + 3*X^3 + 5*X^4 + 7*X^5 + 11*X^6 + O(X^7)
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(ZZ, "X") >>> P = L.SetPartitions() >>> P.isotype_generating_series() 1 + X + 2*X^2 + 3*X^3 + 5*X^4 + 7*X^5 + 11*X^6 + O(X^7)
- isotypes(labels)[source]¶
Iterate over the isotypes on the given list of sizes.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: p = L.SetPartitions() sage: list(p.isotypes(3)) [[3], [2, 1], [1, 1, 1]]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> p = L.SetPartitions() >>> list(p.isotypes(Integer(3))) [[3], [2, 1], [1, 1, 1]]
- structures(labels)[source]¶
Iterate over the structures on the given set of labels.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(ZZ, "X") sage: P = L.SetPartitions() sage: list(P.structures([])) [{}] sage: list(P.structures([1])) [{{1}}] sage: list(P.structures([1,2])) [{{1, 2}}, {{1}, {2}}] sage: list(P.structures([1,2,3])) [{{1, 2, 3}}, {{1, 2}, {3}}, {{1, 3}, {2}}, {{1}, {2, 3}}, {{1}, {2}, {3}}]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(ZZ, "X") >>> P = L.SetPartitions() >>> list(P.structures([])) [{}] >>> list(P.structures([Integer(1)])) [{{1}}] >>> list(P.structures([Integer(1),Integer(2)])) [{{1, 2}}, {{1}, {2}}] >>> list(P.structures([Integer(1),Integer(2),Integer(3)])) [{{1, 2, 3}}, {{1, 2}, {3}}, {{1, 3}, {2}}, {{1}, {2, 3}}, {{1}, {2}, {3}}]
- class sage.rings.lazy_species.SetSpecies(parent)[source]¶
Bases:
LazyCombinatorialSpeciesElement,UniqueRepresentationInitialize the species of sets.
- cycle_index_series()[source]¶
Return the cycle index series of the species of sets.
EXAMPLES:
sage: L.<X> = LazyCombinatorialSpecies(QQ) sage: L.Sets().cycle_index_series() h[] + h[1] + h[2] + h[3] + h[4] + h[5] + h[6] + O^7
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, names=('X',)); (X,) = L._first_ngens(1) >>> L.Sets().cycle_index_series() h[] + h[1] + h[2] + h[3] + h[4] + h[5] + h[6] + O^7
- generating_series()[source]¶
Return the (exponential) generating series of the species of sets.
This is the exponential.
EXAMPLES:
sage: L.<X> = LazyCombinatorialSpecies(QQ) sage: L.Sets().generating_series() 1 + X + 1/2*X^2 + 1/6*X^3 + 1/24*X^4 + 1/120*X^5 + 1/720*X^6 + O(X^7)
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, names=('X',)); (X,) = L._first_ngens(1) >>> L.Sets().generating_series() 1 + X + 1/2*X^2 + 1/6*X^3 + 1/24*X^4 + 1/120*X^5 + 1/720*X^6 + O(X^7)
- isotype_generating_series()[source]¶
Return the isotype generating series of the species of sets.
This is the geometric series.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: L.Sets().isotype_generating_series() 1 + X + X^2 + O(X^3)
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> L.Sets().isotype_generating_series() 1 + X + X^2 + O(X^3)
- structures(labels)[source]¶
Iterate over the structures on the given set of labels.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(ZZ, "X") sage: E = L.Sets() sage: list(E.structures([1,2,3])) [(1, 2, 3)]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(ZZ, "X") >>> E = L.Sets() >>> list(E.structures([Integer(1),Integer(2),Integer(3)])) [(1, 2, 3)]
- class sage.rings.lazy_species.SumSpeciesElement(left, right)[source]¶
Bases:
LazyCombinatorialSpeciesElementInitialize the sum of two species.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: F = L.Sets() + L.SetPartitions() sage: TestSuite(F).run(skip=['_test_category', '_test_pickling'])
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> F = L.Sets() + L.SetPartitions() >>> TestSuite(F).run(skip=['_test_category', '_test_pickling'])
- generating_series()[source]¶
Return the (exponential) generating series of
self.EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: F = L.Sets() + L.SetPartitions() sage: F.generating_series() 2 + 2*X + 3/2*X^2 + X^3 + 2/3*X^4 + 53/120*X^5 + 17/60*X^6 + O(X^7)
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> F = L.Sets() + L.SetPartitions() >>> F.generating_series() 2 + 2*X + 3/2*X^2 + X^3 + 2/3*X^4 + 53/120*X^5 + 17/60*X^6 + O(X^7)
- isotype_generating_series()[source]¶
Return the isotype generating series of
self.EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: F = L.Sets() + L.SetPartitions() sage: F.isotype_generating_series() 2 + 2*X + 3*X^2 + 4*X^3 + 6*X^4 + 8*X^5 + 12*X^6 + O(X^7)
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> F = L.Sets() + L.SetPartitions() >>> F.isotype_generating_series() 2 + 2*X + 3*X^2 + 4*X^3 + 6*X^4 + 8*X^5 + 12*X^6 + O(X^7)
- structures(*labels)[source]¶
Iterate over the structures on the given set of labels.
EXAMPLES:
sage: L = LazyCombinatorialSpecies(QQ, "X") sage: F = L.Sets() + L.SetPartitions() sage: list(F.structures([1,2,3])) [((1, 2, 3), 'left'), ({{1, 2, 3}}, 'right'), ({{1, 2}, {3}}, 'right'), ({{1, 3}, {2}}, 'right'), ({{1}, {2, 3}}, 'right'), ({{1}, {2}, {3}}, 'right')]
>>> from sage.all import * >>> L = LazyCombinatorialSpecies(QQ, "X") >>> F = L.Sets() + L.SetPartitions() >>> list(F.structures([Integer(1),Integer(2),Integer(3)])) [((1, 2, 3), 'left'), ({{1, 2, 3}}, 'right'), ({{1, 2}, {3}}, 'right'), ({{1, 3}, {2}}, 'right'), ({{1}, {2, 3}}, 'right'), ({{1}, {2}, {3}}, 'right')]
- sage.rings.lazy_species.weighted_compositions(n, d, weight_multiplicities, _w0=0)[source]¶
Return all compositions of \(n\) of weight \(d\).
The weight of a composition \(n_1, n_2, \dots\) is \(\sum_i w_i n_i\).
INPUT:
n– nonnegative integer; the sum of the partsd– nonnegative integer; the total weightweight_multiplicities– iterable;weight_multiplicities[i]is the number of positions with weighti+1
Todo
Possibly this could be merged with
WeightedIntegerVectors. However, that class does not support fixing the sum of the parts currently.EXAMPLES:
sage: from sage.rings.lazy_species import weighted_compositions sage: list(weighted_compositions(1, 1, [2,1])) [[1, 0], [0, 1]] sage: list(weighted_compositions(2, 1, [2,1])) [] sage: list(weighted_compositions(1, 2, [2,1,1])) [[0, 0, 1]] sage: list(weighted_compositions(3, 4, [2,2])) [[2, 0, 1, 0], [1, 1, 1, 0], [0, 2, 1, 0], [2, 0, 0, 1], [1, 1, 0, 1], [0, 2, 0, 1]]
>>> from sage.all import * >>> from sage.rings.lazy_species import weighted_compositions >>> list(weighted_compositions(Integer(1), Integer(1), [Integer(2),Integer(1)])) [[1, 0], [0, 1]] >>> list(weighted_compositions(Integer(2), Integer(1), [Integer(2),Integer(1)])) [] >>> list(weighted_compositions(Integer(1), Integer(2), [Integer(2),Integer(1),Integer(1)])) [[0, 0, 1]] >>> list(weighted_compositions(Integer(3), Integer(4), [Integer(2),Integer(2)])) [[2, 0, 1, 0], [1, 1, 1, 0], [0, 2, 1, 0], [2, 0, 0, 1], [1, 1, 0, 1], [0, 2, 0, 1]]
- sage.rings.lazy_species.weighted_vector_compositions(n_vec, d, weight_multiplicities_vec)[source]¶
Return all compositions of the vector \(n\) of weight \(d\).
INPUT:
n_vec– a \(k\)-tuple of non-negative integersd– a non-negative integer, the total sum of the parts in all componentsweight_multiplicities_vec– \(k\)-tuple of iterables, whereweight_multiplicities_vec[j][i]is the number of positions with weight \(i+1\) in the \(j\)-th component
EXAMPLES:
sage: from sage.rings.lazy_species import weighted_vector_compositions sage: list(weighted_vector_compositions([1,1], 2, [[2,1,1], [1,1,1]])) [([1, 0], [1]), ([0, 1], [1])] sage: list(weighted_vector_compositions([3,1], 4, [[2,1,0,0,1], [2,1,0,0,1]])) [([3, 0], [1, 0]), ([3, 0], [0, 1]), ([2, 1], [1, 0]), ([2, 1], [0, 1]), ([1, 2], [1, 0]), ([1, 2], [0, 1]), ([0, 3], [1, 0]), ([0, 3], [0, 1])]
>>> from sage.all import * >>> from sage.rings.lazy_species import weighted_vector_compositions >>> list(weighted_vector_compositions([Integer(1),Integer(1)], Integer(2), [[Integer(2),Integer(1),Integer(1)], [Integer(1),Integer(1),Integer(1)]])) [([1, 0], [1]), ([0, 1], [1])] >>> list(weighted_vector_compositions([Integer(3),Integer(1)], Integer(4), [[Integer(2),Integer(1),Integer(0),Integer(0),Integer(1)], [Integer(2),Integer(1),Integer(0),Integer(0),Integer(1)]])) [([3, 0], [1, 0]), ([3, 0], [0, 1]), ([2, 1], [1, 0]), ([2, 1], [0, 1]), ([1, 2], [1, 0]), ([1, 2], [0, 1]), ([0, 3], [1, 0]), ([0, 3], [0, 1])]