Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Recursive Species """ #***************************************************************************** # Copyright (C) 2008 Mike Hansen <mhansen@gmail.com>, # # Distributed under the terms of the GNU General Public License (GPL) # # This code is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # The full text of the GPL is available at: # # http://www.gnu.org/licenses/ #***************************************************************************** from sage.combinat.species.species import GenericCombinatorialSpecies from sage.combinat.species.structure import SpeciesStructureWrapper from sage.rings.all import QQ
class CombinatorialSpeciesStructure(SpeciesStructureWrapper): pass
class CombinatorialSpecies(GenericCombinatorialSpecies): def __init__(self): """ EXAMPLES::
sage: F = CombinatorialSpecies() sage: loads(dumps(F)) Combinatorial species
::
sage: X = species.SingletonSpecies() sage: E = species.EmptySetSpecies() sage: L = CombinatorialSpecies() sage: L.define(E+X*L) sage: L.generating_series().coefficients(4) [1, 1, 1, 1] sage: LL = loads(dumps(L)) sage: LL.generating_series().coefficients(4) [1, 1, 1, 1] """
_default_structure_class = CombinatorialSpeciesStructure
def __hash__(self): """ EXAMPLES::
sage: hash(CombinatorialSpecies) #random 53751280
::
sage: X = species.SingletonSpecies() sage: E = species.EmptySetSpecies() sage: L = CombinatorialSpecies() sage: L.define(E+X*L) sage: hash(L) #random -826511807095108317 """
def __eq__(self, other): """ TESTS::
sage: A = species.CombinatorialSpecies() sage: B = species.CombinatorialSpecies() sage: A == B False sage: X = species.SingletonSpecies() sage: A.define(X+A*A) sage: B.define(X+B*B) sage: A == B True
sage: C = species.CombinatorialSpecies() sage: E = species.EmptySetSpecies() sage: C.define(E+X*C*C) sage: A == C False """
def __ne__(self, other): """ Check whether ``self`` is not equal to ``other``.
EXAMPLES::
sage: A = species.CombinatorialSpecies() sage: B = species.CombinatorialSpecies() sage: A != B True sage: X = species.SingletonSpecies() sage: A.define(X+A*A) sage: B.define(X+B*B) sage: A != B False
sage: C = species.CombinatorialSpecies() sage: E = species.EmptySetSpecies() sage: C.define(E+X*C*C) sage: A != C True """
def _unique_info(self): """ Return a tuple which should uniquely identify the species.
EXAMPLES::
sage: F = CombinatorialSpecies() sage: F._unique_info() (<class 'sage.combinat.species.recursive_species.CombinatorialSpecies'>,)
::
sage: X = species.SingletonSpecies() sage: E = species.EmptySetSpecies() sage: L = CombinatorialSpecies() sage: L.define(E+X*L) sage: L._unique_info() (<class 'sage.combinat.species.recursive_species.CombinatorialSpecies'>, <class 'sage.combinat.species.sum_species.SumSpecies'>, None, None, 1, Empty set species, Product of (Singleton species) and (Combinatorial species)) """ else:
def __getstate__(self): """ EXAMPLES::
sage: X = species.SingletonSpecies() sage: E = species.EmptySetSpecies() sage: L = CombinatorialSpecies() sage: L.define(E+X*L) sage: L.__getstate__() {'reference': Sum of (Empty set species) and (Product of (Singleton species) and (Combinatorial species))} """
def __setstate__(self, state): """ EXAMPLES::
sage: X = species.SingletonSpecies() sage: E = species.EmptySetSpecies() sage: L = CombinatorialSpecies() sage: L.define(E+X*L) sage: state = L.__getstate__(); state {'reference': Sum of (Empty set species) and (Product of (Singleton species) and (Combinatorial species))} sage: L._reference = None sage: L.__setstate__(state) sage: L._reference Sum of (Empty set species) and (Product of (Singleton species) and (Combinatorial species)) """
def _structures(self, structure_class, labels): """ EXAMPLES::
sage: F = CombinatorialSpecies() sage: list(F._structures(F._default_structure_class, [1,2,3])) Traceback (most recent call last): ... NotImplementedError """
def _isotypes(self, structure_class, labels): """ EXAMPLES::
sage: F = CombinatorialSpecies() sage: list(F._isotypes(F._default_structure_class, [1,2,3])) Traceback (most recent call last): ... NotImplementedError """
def _gs(self, series_ring, base_ring): """ EXAMPLES::
sage: F = CombinatorialSpecies() sage: F.generating_series() Uninitialized lazy power series """
def _itgs(self, series_ring, base_ring): """ EXAMPLES::
sage: F = CombinatorialSpecies() sage: F.isotype_generating_series() Uninitialized lazy power series """
def _cis(self, series_ring, base_ring): """ EXAMPLES::
sage: F = CombinatorialSpecies() sage: F.cycle_index_series() Uninitialized lazy power series """
def weight_ring(self): """ EXAMPLES::
sage: F = species.CombinatorialSpecies() sage: F.weight_ring() Rational Field
::
sage: X = species.SingletonSpecies() sage: E = species.EmptySetSpecies() sage: L = CombinatorialSpecies() sage: L.define(E+X*L) sage: L.weight_ring() Rational Field """
else:
def define(self, x): """ Define ``self`` to be equal to the combinatorial species ``x``.
This is used to define combinatorial species recursively. All of the real work is done by calling the .set() method for each of the series associated to self.
EXAMPLES: The species of linear orders L can be recursively defined by `L = 1 + X*L` where 1 represents the empty set species and X represents the singleton species.
::
sage: X = species.SingletonSpecies() sage: E = species.EmptySetSpecies() sage: L = CombinatorialSpecies() sage: L.define(E+X*L) sage: L.generating_series().coefficients(4) [1, 1, 1, 1] sage: L.structures([1,2,3]).cardinality() 6 sage: L.structures([1,2,3]).list() [1*(2*(3*{})), 1*(3*(2*{})), 2*(1*(3*{})), 2*(3*(1*{})), 3*(1*(2*{})), 3*(2*(1*{}))]
::
sage: L = species.LinearOrderSpecies() sage: L.generating_series().coefficients(4) [1, 1, 1, 1] sage: L.structures([1,2,3]).cardinality() 6 sage: L.structures([1,2,3]).list() [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
TESTS::
sage: A = CombinatorialSpecies() sage: A.define(E+X*A*A) sage: A.generating_series().coefficients(6) [1, 1, 2, 5, 14, 42] sage: A.generating_series().counts(6) [1, 1, 4, 30, 336, 5040] sage: len(A.structures([1,2,3,4]).list()) 336 sage: A.isotype_generating_series().coefficients(6) [1, 1, 2, 5, 14, 42] sage: len(A.isotypes([1,2,3,4]).list()) 14
::
sage: A = CombinatorialSpecies() sage: A.define(X+A*A) sage: A.generating_series().coefficients(6) [0, 1, 1, 2, 5, 14] sage: A.generating_series().counts(6) [0, 1, 2, 12, 120, 1680] sage: len(A.structures([1,2,3]).list()) 12 sage: A.isotype_generating_series().coefficients(6) [0, 1, 1, 2, 5, 14] sage: len(A.isotypes([1,2,3,4]).list()) 5
::
sage: X2 = X*X sage: X5 = X2*X2*X sage: A = CombinatorialSpecies() sage: B = CombinatorialSpecies() sage: C = CombinatorialSpecies() sage: A.define(X5+B*B) sage: B.define(X5+C*C) sage: C.define(X2+C*C+A*A) sage: A.generating_series().coefficients(Integer(10)) [0, 0, 0, 0, 0, 1, 0, 0, 1, 2] sage: A.generating_series().coefficients(15) [0, 0, 0, 0, 0, 1, 0, 0, 1, 2, 5, 4, 14, 10, 48] sage: B.generating_series().coefficients(15) [0, 0, 0, 0, 1, 1, 2, 0, 5, 0, 14, 0, 44, 0, 138] sage: C.generating_series().coefficients(15) [0, 0, 1, 0, 1, 0, 2, 0, 5, 0, 15, 0, 44, 2, 142]
::
sage: F = CombinatorialSpecies() sage: F.define(E+X+(X*F+X*X*F)) sage: F.generating_series().counts(10) [1, 2, 6, 30, 192, 1560, 15120, 171360, 2217600, 32296320] sage: F.generating_series().coefficients(10) [1, 2, 3, 5, 8, 13, 21, 34, 55, 89] sage: F.isotype_generating_series().coefficients(10) [1, 2, 3, 5, 8, 13, 21, 34, 55, 89] """ raise TypeError("x must be a combinatorial species")
raise TypeError("only undefined combinatorial species can be set")
def _add_to_digraph(self, d): """ Adds this species as a vertex to the digraph d along with any 'children' of this species.
Note that to avoid infinite recursion, we just return if this species already occurs in the digraph d.
EXAMPLES::
sage: d = DiGraph(multiedges=True) sage: X = species.SingletonSpecies() sage: B = species.CombinatorialSpecies() sage: B.define(X+B*B) sage: B._add_to_digraph(d); d Multi-digraph on 4 vertices
TESTS::
sage: C = species.CombinatorialSpecies() sage: C._add_to_digraph(d) Traceback (most recent call last): ... NotImplementedError """
def _equation(self, var_mapping): """ Returns the right hand side of an algebraic equation satisfied by this species. This is a utility function called by the algebraic_equation_system method.
EXAMPLES::
sage: C = species.CombinatorialSpecies() sage: C.algebraic_equation_system() Traceback (most recent call last): ... NotImplementedError
::
sage: B = species.BinaryTreeSpecies() sage: B.algebraic_equation_system() [-node3^2 + node1, -node1 + node3 - z] """ except AttributeError: raise NotImplementedError |