3333
3434from itertools import accumulate , chain , product
3535
36+ from sage .arith .misc import divisors
3637from sage .categories .graded_algebras_with_basis import GradedAlgebrasWithBasis
3738from sage .categories .modules import Modules
3839from sage .categories .monoids import Monoids
4243from sage .combinat .cyclic_sieving_phenomenon import orbit_decomposition
4344from sage .combinat .free_module import CombinatorialFreeModule
4445from sage .combinat .integer_vector import IntegerVectors
46+ from sage .combinat .integer_vector_weighted import WeightedIntegerVectors
4547from sage .combinat .partition import Partitions , _Partitions
4648from sage .combinat .sf .sf import SymmetricFunctions
4749from sage .groups .perm_gps .constructor import PermutationGroupElement
4850from sage .groups .perm_gps .permgroup import PermutationGroup , PermutationGroup_generic
4951from sage .groups .perm_gps .permgroup_named import SymmetricGroup
5052from sage .libs .gap .libgap import libgap
51- from sage .misc .cachefunc import cached_method
53+ from sage .misc .cachefunc import cached_method , cached_function
5254from sage .misc .fast_methods import WithEqualityById
5355from sage .misc .inherit_comparison import InheritComparisonClasscallMetaclass
56+ from sage .misc .misc_c import prod
5457from sage .modules .free_module_element import vector
5558from sage .monoids .indexed_free_monoid import (IndexedFreeAbelianMonoid ,
5659 IndexedFreeAbelianMonoidElement )
@@ -297,13 +300,13 @@ def __lt__(self, other):
297300 sage: len(P.cover_relations())
298301 7
299302 sage: sorted(P.cover_relations(), key=str)
300- [[C_4, {((1,2)(3,4),)}],
303+ [[C_4, E_2(X^2)],
304+ [E_2(E_2), C_4],
305+ [E_2(E_2), Pb_4],
306+ [E_4, E_2(E_2)],
301307 [E_4, Eo_4],
302- [E_4, P_4],
303308 [Eo_4, Pb_4],
304- [P_4, C_4],
305- [P_4, Pb_4],
306- [Pb_4, {((1,2)(3,4),)}]]
309+ [Pb_4, E_2(X^2)]]
307310
308311 TESTS::
309312
@@ -450,7 +453,7 @@ def _element_constructor_(self, G, pi=None, check=True):
450453
451454 sage: G = PermutationGroup([[(1,3),(5,7)]], domain=[1,3,5,7])
452455 sage: A(G, ([1,3], [5,7]))
453- {((1,2)(3,4),): ({1, 2}, {3, 4})}
456+ E_2(X*Y)
454457
455458 Test that errors are raised on some possible misuses::
456459
@@ -531,7 +534,7 @@ def _element_constructor_(self, G, pi=None, check=True):
531534
532535 def _rename (self , n ):
533536 r"""
534- Names for common species.
537+ Give common species of degree `n` their traditional names .
535538
536539 EXAMPLES::
537540
@@ -546,9 +549,9 @@ def _rename(self, n):
546549 sage: A(CyclicPermutationGroup(4), {1: range(1, 5)})
547550 C_4(Y)
548551 sage: A(DihedralGroup(4), {0: range(1, 5)})
549- P_4(X )
552+ E_2(E_2(X) )
550553 sage: A(DihedralGroup(4), {1: range(1, 5)})
551- P_4(Y )
554+ E_2(E_2(Y) )
552555 sage: A(AlternatingGroup(4), {0: range(1, 5)})
553556 Eo_4(X)
554557 sage: A(AlternatingGroup(4), {1: range(1, 5)})
@@ -589,6 +592,8 @@ def _rename(self, n):
589592 [(i , i + 1 ) for i in range (1 , n , 2 )]]
590593 self (PermutationGroup (gens ), pi , check = False ).rename (f"Pb_{ n } " + sort )
591594
595+ _atomic_set_like_species (n , self ._names )
596+
592597 def __contains__ (self , x ):
593598 r"""
594599 Return whether ``x`` is in ``self``.
@@ -717,11 +722,7 @@ def _an_element_(self):
717722
718723 sage: A = AtomicSpecies("X, Y")
719724 sage: a = A.an_element(); a
720- {((1,2)(3,4),): ({1, 2}, {3, 4})}
721-
722- sage: a.rename("E_2(XY)")
723- sage: a
724- E_2(XY)
725+ E_2(X*Y)
725726 """
726727 G = PermutationGroup ([[(2 * s + 1 , 2 * s + 2 ) for s in range (self ._arity )]])
727728 m = {s : [2 * s + 1 , 2 * s + 2 ] for s in range (self ._arity )}
@@ -845,7 +846,7 @@ class MolecularSpecies(IndexedFreeAbelianMonoid):
845846 sage: M = MolecularSpecies("X,Y")
846847 sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]])
847848 sage: M(G, {0: [5,6], 1: [1,2,3,4]})
848- E_2(X)*{((1,2)(3,4),): ({}, {1, 2, 3, 4})}
849+ E_2(X)*E_2(Y^2)
849850 """
850851 @staticmethod
851852 def __classcall__ (cls , names ):
@@ -940,11 +941,11 @@ def _element_constructor_(self, G, pi=None, check=True):
940941 sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x])
941942 sage: X = SetPartitions(4, [2, 2])
942943 sage: M((X, a, 'left'), {0: X.base_set()})
943- P_4
944+ E_2(E_2)
944945
945946 sage: X = SetPartitions(8, [4, 2, 2])
946947 sage: M((X, a, 'left'), {0: X.base_set()}, check=False)
947- E_4*P_4
948+ E_4*E_2(E_2)
948949
949950 TESTS::
950951
@@ -956,7 +957,7 @@ def _element_constructor_(self, G, pi=None, check=True):
956957
957958 sage: G = PermutationGroup([[(2,3),(4,5)]], domain=[2,3,4,5])
958959 sage: M(G, {0: [2, 3], 1: [4, 5]})
959- E_2(XY )
960+ E_2(X*Y )
960961
961962 sage: X = SetPartitions(4, 2)
962963 sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x])
@@ -967,7 +968,7 @@ def _element_constructor_(self, G, pi=None, check=True):
967968
968969 sage: G = PermutationGroup([[(1,3),(5,7)]], domain=[1,3,5,7])
969970 sage: M(G, ([1,3], [5,7]))
970- E_2(XY )
971+ E_2(X*Y )
971972
972973 sage: G = PermutationGroup([[(1,2), (3,4,5,6)]])
973974 sage: a = M(G, {0:[1,2], 1:[3,4,5,6]})
@@ -1176,23 +1177,23 @@ def _richcmp_(self, other, op):
11761177 sage: len(P.cover_relations())
11771178 17
11781179 sage: sorted(P.cover_relations(), key=str)
1179- [[C_4, {((1,2)(3,4),)}],
1180+ [[C_4, E_2(X^2)],
1181+ [E_2(E_2), C_4],
1182+ [E_2(E_2), E_2^2],
1183+ [E_2(E_2), Pb_4],
1184+ [E_2(X^2), X^4],
1185+ [E_2^2, E_2(X^2)],
11801186 [E_2^2, X^2*E_2],
1181- [E_2^2, {((1,2)(3,4),)} ],
1187+ [E_4, E_2(E_2) ],
11821188 [E_4, Eo_4],
1183- [E_4, P_4],
11841189 [E_4, X*E_3],
11851190 [Eo_4, Pb_4],
11861191 [Eo_4, X*C_3],
1187- [P_4, C_4],
1188- [P_4, E_2^2],
1189- [P_4, Pb_4],
1190- [Pb_4, {((1,2)(3,4),)}],
1192+ [Pb_4, E_2(X^2)],
11911193 [X*C_3, X^4],
11921194 [X*E_3, X*C_3],
11931195 [X*E_3, X^2*E_2],
1194- [X^2*E_2, X^4],
1195- [{((1,2)(3,4),)}, X^4]]
1196+ [X^2*E_2, X^4]]
11961197
11971198 TESTS::
11981199
@@ -1249,7 +1250,7 @@ def permutation_group(self):
12491250 sage: M = MolecularSpecies("X,Y")
12501251 sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]])
12511252 sage: A = M(G, {0: [5,6], 1: [1,2,3,4]}); A
1252- E_2(X)*{((1,2)(3,4),): ({}, {1, 2, 3, 4})}
1253+ E_2(X)*E_2(Y^2)
12531254 sage: A.permutation_group()
12541255 (Permutation Group with generators [(3,4)(5,6), (1,2)],
12551256 (frozenset({1, 2}), frozenset({3, 4, 5, 6})))
@@ -1274,7 +1275,7 @@ def permutation_group(self):
12741275 sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]])
12751276 sage: A = M(G, {0: [5,6], 1: [1,2,3,4]})
12761277 sage: A * B
1277- E_2(X)*C_3(X)*{((1,2)(3,4),): ({}, {1, 2, 3, 4})}
1278+ E_2(X)*C_3(X)*E_2(Y^2)
12781279 sage: (A*B).permutation_group()
12791280 (Permutation Group with generators [(6,7)(8,9), (3,4,5), (1,2)],
12801281 (frozenset({1, 2, 3, 4, 5}), frozenset({6, 7, 8, 9})))
@@ -1439,7 +1440,7 @@ def __call__(self, *args):
14391440 sage: X(E2)
14401441 E_2
14411442 sage: E2(E2)
1442- P_4
1443+ E_2(E_2)
14431444
14441445 sage: M = MolecularSpecies(["X","Y"])
14451446 sage: X = M(SymmetricGroup(1), {0: [1]})
@@ -1637,22 +1638,22 @@ def tilde(self):
16371638 sage: P = PolynomialSpecies(QQ, "X")
16381639 sage: sortkey = lambda x: (len(x[1]), sum(x[1].coefficients()), str(x[0]))
16391640 sage: n=4; table(sorted([(m, P.monomial(m).tilde()) for m in M.subset(n)], key=sortkey))
1640- X^4 X^4
1641- X^2*E_2 2* X^2*E_2
1642- {((1,2)(3,4),)} 2*{((1,2)(3,4),)}
1643- X*C_3 3*X*C_3
1644- C_4 4*C_4
1645- E_2^2 4*E_2^2
1646- Pb_4 4*Pb_4
1647- X*E_3 X*E_3 + X^2*E_2 + X*C_3
1648- Eo_4 Eo_4 + 2*X*C_3 + Pb_4
1649- P_4 2*P_4 + E_2^2 + Pb_4 + C_4
1650- E_4 E_4 + E_2^2 + X*C_3 + P_4 + C_4
1641+ X^4 X^4
1642+ E_2( X^2) 2*E_2( X^2)
1643+ X^2*E_2 2*X^2*E_2
1644+ X*C_3 3*X*C_3
1645+ C_4 4*C_4
1646+ E_2^2 4*E_2^2
1647+ Pb_4 4*Pb_4
1648+ X*E_3 X*E_3 + X^2*E_2 + X*C_3
1649+ Eo_4 Eo_4 + 2*X*C_3 + Pb_4
1650+ E_2(E_2) 2*E_2(E_2) + E_2^2 + Pb_4 + C_4
1651+ E_4 E_4 + E_2^2 + X*C_3 + E_2(E_2) + C_4
16511652
16521653 sage: P.<X,Y> = PolynomialSpecies(QQ)
16531654 sage: E2 = PolynomialSpecies(QQ, "X")(SymmetricGroup(2))
16541655 sage: E2(X*Y).tilde()
1655- 2*E_2(XY )
1656+ 2*E_2(X*Y )
16561657 """
16571658 P = self .parent ()
16581659 M = P ._indices
@@ -1776,7 +1777,7 @@ def _compose_with_singletons(self, names, args):
17761777 sage: P = PolynomialSpecies(ZZ, "X")
17771778 sage: C4 = P(CyclicPermutationGroup(4))
17781779 sage: C4._compose_with_singletons("X, Y", [[2, 2]])
1779- E_2(XY ) + X^2*Y^2
1780+ E_2(X*Y ) + X^2*Y^2
17801781
17811782 sage: P = PolynomialSpecies(ZZ, ["X", "Y"])
17821783 sage: F = P(PermutationGroup([[(1,2,3), (4,5,6)]]), {0: [1,2,3], 1: [4,5,6]})
@@ -1864,12 +1865,12 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees):
18641865
18651866 sage: C4 = P(CyclicPermutationGroup(4))
18661867 sage: C4._compose_with_weighted_singletons(["X"], [-1], [[4]])
1867- -C_4 + {((1,2)(3,4),)}
1868+ -C_4 + E_2(X^2)
18681869
18691870 Exercise (2.5.17) in [BLL1998]_::
18701871
18711872 sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[2, 2]])
1872- E_2(XY ) + X^2*Y^2
1873+ E_2(X*Y ) + X^2*Y^2
18731874 sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[3, 1]])
18741875 X^3*Y
18751876 sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[4, 0]])
@@ -1878,7 +1879,7 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees):
18781879 Equation (4.60) in [ALL2002]_::
18791880
18801881 sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, -1], [[2, 2]])
1881- -E_2(XY ) + 2*X^2*Y^2
1882+ -E_2(X*Y ) + 2*X^2*Y^2
18821883
18831884 A bivariate example::
18841885
@@ -1894,7 +1895,7 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees):
18941895 TESTS::
18951896
18961897 sage: (C4+E2^2)._compose_with_weighted_singletons(["X"], [-1], [[4]])
1897- -C_4 + E_2^2 + {((1,2)(3,4),)} - 2*X^2*E_2 + X^4
1898+ -C_4 + E_2^2 + E_2(X^2) - 2*X^2*E_2 + X^4
18981899
18991900 sage: C4._compose_with_weighted_singletons(["X"], [-1, 0], [[4]])
19001901 Traceback (most recent call last):
@@ -1967,10 +1968,10 @@ def __call__(self, *args):
19671968 sage: E2(-X)
19681969 -E_2 + X^2
19691970 sage: E2(X^2)
1970- {((1,2)(3,4),)}
1971+ E_2(X^2)
19711972
19721973 sage: E2(X + X^2)
1973- E_2 + X^3 + {((1,2)(3,4),)}
1974+ E_2 + X^3 + E_2(X^2)
19741975
19751976 sage: P2 = PolynomialSpecies(QQ, ["X", "Y"])
19761977 sage: X = P2(SymmetricGroup(1), {0: [1]})
@@ -1979,7 +1980,7 @@ def __call__(self, *args):
19791980 E_2(X) + X*Y + E_2(Y)
19801981
19811982 sage: E2(X*Y)(E2(X), E2(Y))
1982- {((7,8), (5,6), (3,4), (1,2), (1,3)(2,4)(5,7)(6,8)): ({1, 2, 3, 4}, {5, 6, 7, 8})}
1983+ E_2(E_2(X)*E_2(Y))
19831984
19841985 sage: R.<q> = QQ[]
19851986 sage: P = PolynomialSpecies(R, ["X"])
@@ -2188,13 +2189,13 @@ def _element_constructor_(self, G, pi=None, check=True):
21882189 sage: X = SetPartitions(4, 2)
21892190 sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x])
21902191 sage: P((X, a, 'left'), {0: [1,2], 1: [3,4]})
2191- E_2(X)*E_2(Y) + X^2*E_2(Y) + E_2(XY ) + Y^2*E_2(X)
2192+ E_2(X)*E_2(Y) + X^2*E_2(Y) + E_2(X*Y ) + Y^2*E_2(X)
21922193
21932194 sage: P = PolynomialSpecies(ZZ, ["X"])
21942195 sage: X = SetPartitions(4, 2)
21952196 sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x])
21962197 sage: P((X, a, 'left'), {0: [1,2,3,4]})
2197- X*E_3 + P_4
2198+ X*E_3 + E_2(E_2)
21982199
21992200 The species of permutation groups::
22002201
@@ -2206,7 +2207,7 @@ def _element_constructor_(self, G, pi=None, check=True):
22062207 ....: H = S.subgroup(G.conjugate(pi).gens())
22072208 ....: return next(K for K in X if K == H)
22082209 sage: P((X, act), {0: range(1, n+1)}, check=False)
2209- 4*E_4 + 4*P_4 + E_2^2 + 2*X*E_3
2210+ 4*E_4 + 4*E_2(E_2) + E_2^2 + 2*X*E_3
22102211
22112212 Create a multisort species given an action::
22122213
@@ -2505,3 +2506,58 @@ def factor(s, c, d):
25052506 for s in range (self ._arity ))
25062507
25072508 Element = PolynomialSpeciesElement
2509+
2510+
2511+ @cached_function
2512+ def _atomic_set_like_species (n , names ):
2513+ r"""
2514+ Return a list of the atomic set like species of degree `n`,
2515+ and provide their traditional names.
2516+
2517+ INPUT:
2518+
2519+ - ``n`` -- positive integer, the degree
2520+ - ``names`` -- an iterable of strings for the sorts of the species
2521+
2522+ EXAMPLES::
2523+
2524+ sage: from sage.rings.species import _atomic_set_like_species
2525+ sage: _atomic_set_like_species(6, "X")
2526+ (E_2(E_3), E_2(X*E_2), E_2(X^3), E_3(E_2), E_3(X^2), E_6)
2527+
2528+ sage: l = [len(_atomic_set_like_species(n, "X")) for n in range(12)]
2529+ sage: l
2530+ [0, 1, 1, 1, 3, 1, 6, 1, 10, 4, 12, 1]
2531+ sage: oeis(l) # optional - internet
2532+ 0: A007650: Number of set-like atomic species of degree n.
2533+
2534+ sage: _atomic_set_like_species(4, "U, V")
2535+ (E_2(E_2(V)), E_2(E_2(U)), E_2(V^2), E_2(U*V), E_2(U^2), E_4(U), E_4(V))
2536+ """
2537+ if not n :
2538+ return ()
2539+ M1 = MolecularSpecies ("X" )
2540+ M = MolecularSpecies (names )
2541+ if n == 1 :
2542+ return tuple ([M (SymmetricGroup (1 ), {s : [1 ]}) for s in range (M ._arity )])
2543+ result = []
2544+ for d in divisors (n ):
2545+ if d == 1 :
2546+ continue
2547+ if d == n :
2548+ result .extend (M (SymmetricGroup (n ), {s : range (1 , n + 1 )})
2549+ for s in range (M ._arity ))
2550+ continue
2551+ E_d = M1 (SymmetricGroup (d ))
2552+ l = []
2553+ w = []
2554+ for degree in range (1 , n // d + 1 ):
2555+ a_degree = _atomic_set_like_species (degree , names )
2556+ l .extend (a_degree )
2557+ w .extend ([degree ]* len (a_degree ))
2558+ for a in WeightedIntegerVectors (n // d , w ):
2559+ G = prod (F ** e for F , e in zip (l , a ))
2560+ F = E_d (G )
2561+ F .support ()[0 ].rename (f"E_{ d } ({ G } )" )
2562+ result .append (F )
2563+ return tuple (result )
0 commit comments