33
33
34
34
from itertools import accumulate , chain , product
35
35
36
+ from sage .arith .misc import divisors
36
37
from sage .categories .graded_algebras_with_basis import GradedAlgebrasWithBasis
37
38
from sage .categories .modules import Modules
38
39
from sage .categories .monoids import Monoids
42
43
from sage .combinat .cyclic_sieving_phenomenon import orbit_decomposition
43
44
from sage .combinat .free_module import CombinatorialFreeModule
44
45
from sage .combinat .integer_vector import IntegerVectors
46
+ from sage .combinat .integer_vector_weighted import WeightedIntegerVectors
45
47
from sage .combinat .partition import Partitions , _Partitions
46
48
from sage .combinat .sf .sf import SymmetricFunctions
47
49
from sage .groups .perm_gps .constructor import PermutationGroupElement
48
50
from sage .groups .perm_gps .permgroup import PermutationGroup , PermutationGroup_generic
49
51
from sage .groups .perm_gps .permgroup_named import SymmetricGroup
50
52
from sage .libs .gap .libgap import libgap
51
- from sage .misc .cachefunc import cached_method
53
+ from sage .misc .cachefunc import cached_method , cached_function
52
54
from sage .misc .fast_methods import WithEqualityById
53
55
from sage .misc .inherit_comparison import InheritComparisonClasscallMetaclass
56
+ from sage .misc .misc_c import prod
54
57
from sage .modules .free_module_element import vector
55
58
from sage .monoids .indexed_free_monoid import (IndexedFreeAbelianMonoid ,
56
59
IndexedFreeAbelianMonoidElement )
@@ -297,13 +300,13 @@ def __lt__(self, other):
297
300
sage: len(P.cover_relations())
298
301
7
299
302
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)],
301
307
[E_4, Eo_4],
302
- [E_4, P_4],
303
308
[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)]]
307
310
308
311
TESTS::
309
312
@@ -450,7 +453,7 @@ def _element_constructor_(self, G, pi=None, check=True):
450
453
451
454
sage: G = PermutationGroup([[(1,3),(5,7)]], domain=[1,3,5,7])
452
455
sage: A(G, ([1,3], [5,7]))
453
- {((1,2)(3,4),): ({1, 2}, {3, 4})}
456
+ E_2(X*Y)
454
457
455
458
Test that errors are raised on some possible misuses::
456
459
@@ -531,7 +534,7 @@ def _element_constructor_(self, G, pi=None, check=True):
531
534
532
535
def _rename (self , n ):
533
536
r"""
534
- Names for common species.
537
+ Give common species of degree `n` their traditional names .
535
538
536
539
EXAMPLES::
537
540
@@ -546,9 +549,9 @@ def _rename(self, n):
546
549
sage: A(CyclicPermutationGroup(4), {1: range(1, 5)})
547
550
C_4(Y)
548
551
sage: A(DihedralGroup(4), {0: range(1, 5)})
549
- P_4(X )
552
+ E_2(E_2(X) )
550
553
sage: A(DihedralGroup(4), {1: range(1, 5)})
551
- P_4(Y )
554
+ E_2(E_2(Y) )
552
555
sage: A(AlternatingGroup(4), {0: range(1, 5)})
553
556
Eo_4(X)
554
557
sage: A(AlternatingGroup(4), {1: range(1, 5)})
@@ -589,6 +592,8 @@ def _rename(self, n):
589
592
[(i , i + 1 ) for i in range (1 , n , 2 )]]
590
593
self (PermutationGroup (gens ), pi , check = False ).rename (f"Pb_{ n } " + sort )
591
594
595
+ _atomic_set_like_species (n , self ._names )
596
+
592
597
def __contains__ (self , x ):
593
598
r"""
594
599
Return whether ``x`` is in ``self``.
@@ -717,11 +722,7 @@ def _an_element_(self):
717
722
718
723
sage: A = AtomicSpecies("X, Y")
719
724
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)
725
726
"""
726
727
G = PermutationGroup ([[(2 * s + 1 , 2 * s + 2 ) for s in range (self ._arity )]])
727
728
m = {s : [2 * s + 1 , 2 * s + 2 ] for s in range (self ._arity )}
@@ -845,7 +846,7 @@ class MolecularSpecies(IndexedFreeAbelianMonoid):
845
846
sage: M = MolecularSpecies("X,Y")
846
847
sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]])
847
848
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)
849
850
"""
850
851
@staticmethod
851
852
def __classcall__ (cls , names ):
@@ -940,11 +941,11 @@ def _element_constructor_(self, G, pi=None, check=True):
940
941
sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x])
941
942
sage: X = SetPartitions(4, [2, 2])
942
943
sage: M((X, a, 'left'), {0: X.base_set()})
943
- P_4
944
+ E_2(E_2)
944
945
945
946
sage: X = SetPartitions(8, [4, 2, 2])
946
947
sage: M((X, a, 'left'), {0: X.base_set()}, check=False)
947
- E_4*P_4
948
+ E_4*E_2(E_2)
948
949
949
950
TESTS::
950
951
@@ -956,7 +957,7 @@ def _element_constructor_(self, G, pi=None, check=True):
956
957
957
958
sage: G = PermutationGroup([[(2,3),(4,5)]], domain=[2,3,4,5])
958
959
sage: M(G, {0: [2, 3], 1: [4, 5]})
959
- E_2(XY )
960
+ E_2(X*Y )
960
961
961
962
sage: X = SetPartitions(4, 2)
962
963
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):
967
968
968
969
sage: G = PermutationGroup([[(1,3),(5,7)]], domain=[1,3,5,7])
969
970
sage: M(G, ([1,3], [5,7]))
970
- E_2(XY )
971
+ E_2(X*Y )
971
972
972
973
sage: G = PermutationGroup([[(1,2), (3,4,5,6)]])
973
974
sage: a = M(G, {0:[1,2], 1:[3,4,5,6]})
@@ -1176,23 +1177,23 @@ def _richcmp_(self, other, op):
1176
1177
sage: len(P.cover_relations())
1177
1178
17
1178
1179
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)],
1180
1186
[E_2^2, X^2*E_2],
1181
- [E_2^2, {((1,2)(3,4),)} ],
1187
+ [E_4, E_2(E_2) ],
1182
1188
[E_4, Eo_4],
1183
- [E_4, P_4],
1184
1189
[E_4, X*E_3],
1185
1190
[Eo_4, Pb_4],
1186
1191
[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)],
1191
1193
[X*C_3, X^4],
1192
1194
[X*E_3, X*C_3],
1193
1195
[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]]
1196
1197
1197
1198
TESTS::
1198
1199
@@ -1249,7 +1250,7 @@ def permutation_group(self):
1249
1250
sage: M = MolecularSpecies("X,Y")
1250
1251
sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]])
1251
1252
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)
1253
1254
sage: A.permutation_group()
1254
1255
(Permutation Group with generators [(3,4)(5,6), (1,2)],
1255
1256
(frozenset({1, 2}), frozenset({3, 4, 5, 6})))
@@ -1274,7 +1275,7 @@ def permutation_group(self):
1274
1275
sage: G = PermutationGroup([[(1,2),(3,4)], [(5,6)]])
1275
1276
sage: A = M(G, {0: [5,6], 1: [1,2,3,4]})
1276
1277
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)
1278
1279
sage: (A*B).permutation_group()
1279
1280
(Permutation Group with generators [(6,7)(8,9), (3,4,5), (1,2)],
1280
1281
(frozenset({1, 2, 3, 4, 5}), frozenset({6, 7, 8, 9})))
@@ -1439,7 +1440,7 @@ def __call__(self, *args):
1439
1440
sage: X(E2)
1440
1441
E_2
1441
1442
sage: E2(E2)
1442
- P_4
1443
+ E_2(E_2)
1443
1444
1444
1445
sage: M = MolecularSpecies(["X","Y"])
1445
1446
sage: X = M(SymmetricGroup(1), {0: [1]})
@@ -1637,22 +1638,22 @@ def tilde(self):
1637
1638
sage: P = PolynomialSpecies(QQ, "X")
1638
1639
sage: sortkey = lambda x: (len(x[1]), sum(x[1].coefficients()), str(x[0]))
1639
1640
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
1651
1652
1652
1653
sage: P.<X,Y> = PolynomialSpecies(QQ)
1653
1654
sage: E2 = PolynomialSpecies(QQ, "X")(SymmetricGroup(2))
1654
1655
sage: E2(X*Y).tilde()
1655
- 2*E_2(XY )
1656
+ 2*E_2(X*Y )
1656
1657
"""
1657
1658
P = self .parent ()
1658
1659
M = P ._indices
@@ -1776,7 +1777,7 @@ def _compose_with_singletons(self, names, args):
1776
1777
sage: P = PolynomialSpecies(ZZ, "X")
1777
1778
sage: C4 = P(CyclicPermutationGroup(4))
1778
1779
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
1780
1781
1781
1782
sage: P = PolynomialSpecies(ZZ, ["X", "Y"])
1782
1783
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):
1864
1865
1865
1866
sage: C4 = P(CyclicPermutationGroup(4))
1866
1867
sage: C4._compose_with_weighted_singletons(["X"], [-1], [[4]])
1867
- -C_4 + {((1,2)(3,4),)}
1868
+ -C_4 + E_2(X^2)
1868
1869
1869
1870
Exercise (2.5.17) in [BLL1998]_::
1870
1871
1871
1872
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
1873
1874
sage: C4._compose_with_weighted_singletons(["X", "Y"], [1, 1], [[3, 1]])
1874
1875
X^3*Y
1875
1876
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):
1878
1879
Equation (4.60) in [ALL2002]_::
1879
1880
1880
1881
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
1882
1883
1883
1884
A bivariate example::
1884
1885
@@ -1894,7 +1895,7 @@ def _compose_with_weighted_singletons(self, names, multiplicities, degrees):
1894
1895
TESTS::
1895
1896
1896
1897
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
1898
1899
1899
1900
sage: C4._compose_with_weighted_singletons(["X"], [-1, 0], [[4]])
1900
1901
Traceback (most recent call last):
@@ -1967,10 +1968,10 @@ def __call__(self, *args):
1967
1968
sage: E2(-X)
1968
1969
-E_2 + X^2
1969
1970
sage: E2(X^2)
1970
- {((1,2)(3,4),)}
1971
+ E_2(X^2)
1971
1972
1972
1973
sage: E2(X + X^2)
1973
- E_2 + X^3 + {((1,2)(3,4),)}
1974
+ E_2 + X^3 + E_2(X^2)
1974
1975
1975
1976
sage: P2 = PolynomialSpecies(QQ, ["X", "Y"])
1976
1977
sage: X = P2(SymmetricGroup(1), {0: [1]})
@@ -1979,7 +1980,7 @@ def __call__(self, *args):
1979
1980
E_2(X) + X*Y + E_2(Y)
1980
1981
1981
1982
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))
1983
1984
1984
1985
sage: R.<q> = QQ[]
1985
1986
sage: P = PolynomialSpecies(R, ["X"])
@@ -2188,13 +2189,13 @@ def _element_constructor_(self, G, pi=None, check=True):
2188
2189
sage: X = SetPartitions(4, 2)
2189
2190
sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x])
2190
2191
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)
2192
2193
2193
2194
sage: P = PolynomialSpecies(ZZ, ["X"])
2194
2195
sage: X = SetPartitions(4, 2)
2195
2196
sage: a = lambda g, x: SetPartition([[g(e) for e in b] for b in x])
2196
2197
sage: P((X, a, 'left'), {0: [1,2,3,4]})
2197
- X*E_3 + P_4
2198
+ X*E_3 + E_2(E_2)
2198
2199
2199
2200
The species of permutation groups::
2200
2201
@@ -2206,7 +2207,7 @@ def _element_constructor_(self, G, pi=None, check=True):
2206
2207
....: H = S.subgroup(G.conjugate(pi).gens())
2207
2208
....: return next(K for K in X if K == H)
2208
2209
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
2210
2211
2211
2212
Create a multisort species given an action::
2212
2213
@@ -2505,3 +2506,58 @@ def factor(s, c, d):
2505
2506
for s in range (self ._arity ))
2506
2507
2507
2508
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