@@ -879,7 +879,14 @@ def is_SPP(self) -> bool:
879
879
sage: PP = PlanePartition([[3,2],[2,0],[0,0]])
880
880
sage: PP.is_SPP()
881
881
True
882
+
883
+ TESTS::
884
+
885
+ sage: PlanePartition([]).is_SPP()
886
+ True
882
887
"""
888
+ if not self :
889
+ return True
883
890
Z = self .z_tableau ()
884
891
c1 = len (Z )
885
892
c2 = len (Z [0 ])
@@ -907,6 +914,11 @@ def is_CSPP(self) -> bool:
907
914
sage: PP = PlanePartition([[3,2,2],[3,1,0],[1,1,0]])
908
915
sage: PP.is_CSPP()
909
916
True
917
+
918
+ TESTS::
919
+
920
+ sage: PlanePartition([]).is_CSPP()
921
+ True
910
922
"""
911
923
if self .z_tableau () == self .y_tableau ():
912
924
return True
@@ -927,6 +939,11 @@ def is_TSPP(self) -> bool:
927
939
sage: PP = PlanePartition([[3,3,3],[3,3,2],[3,2,1]])
928
940
sage: PP.is_TSPP()
929
941
True
942
+
943
+ TESTS::
944
+
945
+ sage: PlanePartition([]).is_TSPP()
946
+ True
930
947
"""
931
948
return self .is_CSPP () and self .is_SPP ()
932
949
@@ -950,6 +967,11 @@ def is_SCPP(self) -> bool:
950
967
sage: PP = PlanePartitions([4,4,4])([[4,4,4,4],[4,4,2,0],[4,2,0,0],[0,0,0,0]])
951
968
sage: PP.is_SCPP()
952
969
True
970
+
971
+ TESTS::
972
+
973
+ sage: PlanePartition([]).is_SCPP()
974
+ True
953
975
"""
954
976
return self .z_tableau (tableau = False ) == self .complement (tableau_only = True )
955
977
@@ -965,6 +987,11 @@ def is_TCPP(self) -> bool:
965
987
sage: PP = PlanePartition([[4,4,3,2],[4,4,2,1],[4,2,0,0],[2,0,0,0]])
966
988
sage: PP.is_TCPP()
967
989
True
990
+
991
+ TESTS::
992
+
993
+ sage: PlanePartition([]).is_TCPP()
994
+ True
968
995
"""
969
996
return self .transpose (True ) == self .complement (True )
970
997
@@ -990,6 +1017,11 @@ def is_SSCPP(self) -> bool:
990
1017
sage: PP = PlanePartition([[4,2,2,2],[2,2,2,2],[2,2,2,2],[2,2,2,0]])
991
1018
sage: PP.is_SSCPP()
992
1019
True
1020
+
1021
+ TESTS::
1022
+
1023
+ sage: PlanePartition([]).is_SSCPP()
1024
+ True
993
1025
"""
994
1026
return self .is_SPP () and self .is_SCPP ()
995
1027
@@ -1006,6 +1038,11 @@ def is_CSTCPP(self) -> bool:
1006
1038
sage: PP = PlanePartition([[4,4,3,2],[4,3,2,1],[3,2,1,0],[2,1,0,0]])
1007
1039
sage: PP.is_CSTCPP()
1008
1040
True
1041
+
1042
+ TESTS::
1043
+
1044
+ sage: PlanePartition([]).is_CSTCPP()
1045
+ True
1009
1046
"""
1010
1047
return self .is_CSPP () and self .is_TCPP ()
1011
1048
@@ -1022,6 +1059,11 @@ def is_CSSCPP(self) -> bool:
1022
1059
sage: PP = PlanePartition([[4,4,4,1],[3,3,2,1],[3,2,1,1],[3,0,0,0]])
1023
1060
sage: PP.is_CSSCPP()
1024
1061
True
1062
+
1063
+ TESTS::
1064
+
1065
+ sage: PlanePartition([]).is_CSSCPP()
1066
+ True
1025
1067
"""
1026
1068
return self .is_CSPP () and self .is_SCPP ()
1027
1069
@@ -1038,6 +1080,11 @@ def is_TSSCPP(self) -> bool:
1038
1080
sage: PP = PlanePartition([[4,4,3,2],[4,3,2,1],[3,2,1,0],[2,1,0,0]])
1039
1081
sage: PP.is_TSSCPP()
1040
1082
True
1083
+
1084
+ TESTS::
1085
+
1086
+ sage: PlanePartition([]).is_TSSCPP()
1087
+ True
1041
1088
"""
1042
1089
return self .is_TSPP () and self .is_SCPP ()
1043
1090
@@ -1609,10 +1656,20 @@ def __iter__(self) -> Iterator:
1609
1656
1610
1657
sage: list(PlanePartitions([1,2,1]))
1611
1658
[Plane partition [], Plane partition [[1]], Plane partition [[1, 1]]]
1659
+
1660
+ TESTS::
1661
+
1662
+ sage: all(len(set(PP)) == PP.cardinality()
1663
+ ....: for b in cartesian_product([range(4)]*3)
1664
+ ....: if (PP := PlanePartitions(b)))
1665
+ True
1612
1666
"""
1613
1667
A = self ._box [0 ]
1614
1668
B = self ._box [1 ]
1615
1669
C = self ._box [2 ]
1670
+ if not A :
1671
+ yield self .element_class (self , [], check = False )
1672
+ return
1616
1673
from sage .combinat .tableau import SemistandardTableaux as SST
1617
1674
for T in SST ([B for i in range (A )], max_entry = C + A ): # type:ignore
1618
1675
PP = [[0 for _ in range (B )] for _ in range (A )]
@@ -1725,7 +1782,7 @@ def __iter__(self) -> Iterator:
1725
1782
1726
1783
TESTS::
1727
1784
1728
- sage: all(len(set(PP)) == PP.cardinality() for n in range(1, 10 ) if (PP := PlanePartitions(n)))
1785
+ sage: all(len(set(PP)) == PP.cardinality() for n in range(9 ) if (PP := PlanePartitions(n)))
1729
1786
True
1730
1787
"""
1731
1788
from sage .combinat .partition import Partitions
@@ -1944,7 +2001,9 @@ def __iter__(self) -> Iterator:
1944
2001
1945
2002
TESTS::
1946
2003
1947
- sage: all(len(set(PP)) == PP.cardinality() for n in range(1, 5) if (PP := PlanePartitions([n]*3, symmetry='SPP')))
2004
+ sage: all(len(set(PP)) == PP.cardinality()
2005
+ ....: for a, b in cartesian_product([range(4)]*2)
2006
+ ....: if (PP := PlanePartitions([a, a, b], symmetry='SPP')))
1948
2007
True
1949
2008
"""
1950
2009
for acl in self .to_poset ().antichains_iterator ():
@@ -2174,7 +2233,7 @@ def __iter__(self) -> Iterator:
2174
2233
2175
2234
TESTS::
2176
2235
2177
- sage: all(len(set(PP)) == PP.cardinality() for n in range(1, 5) if (PP := PlanePartitions([n]*3, symmetry='CSPP')))
2236
+ sage: all(len(set(PP)) == PP.cardinality() for n in range(5) if (PP := PlanePartitions([n]*3, symmetry='CSPP')))
2178
2237
True
2179
2238
"""
2180
2239
for acl in self .to_poset ().antichains_iterator ():
@@ -2357,11 +2416,11 @@ def __iter__(self) -> Iterator:
2357
2416
2358
2417
TESTS::
2359
2418
2360
- sage: all(len(set(PP)) == PP.cardinality() for n in range(1, 5) if (PP := PlanePartitions([n]*3, symmetry='TSPP')))
2419
+ sage: all(len(set(PP)) == PP.cardinality() for n in range(5) if (PP := PlanePartitions([n]*3, symmetry='TSPP')))
2361
2420
True
2362
2421
"""
2363
- for A in self .to_poset ().antichains_iterator ():
2364
- yield self .from_antichain (A )
2422
+ for acl in self .to_poset ().antichains_iterator ():
2423
+ yield self .from_antichain (acl )
2365
2424
2366
2425
def cardinality (self ) -> Integer :
2367
2426
r"""
@@ -2457,37 +2516,39 @@ def __iter__(self) -> Iterator:
2457
2516
sage: PP = PlanePartitions([3,4,5], symmetry='SCPP')
2458
2517
sage: len(set(PP)) == PP.cardinality()
2459
2518
True
2519
+
2520
+ sage: all(len(set(PP)) == PP.cardinality()
2521
+ ....: for b in cartesian_product([range(4)]*3)
2522
+ ....: if is_even(prod(b)) and (PP := PlanePartitions(b, symmetry='SCPP')))
2523
+ True
2460
2524
"""
2461
2525
b = self ._box [0 ]
2462
2526
a = self ._box [1 ]
2463
2527
c = self ._box [2 ]
2464
2528
2465
2529
def Partitions_inside_lambda (la ):
2466
- "Iterate over all partitions contained in la with the same number of parts including 0s."
2467
- if not la :
2468
- yield []
2469
- return
2470
- for mu_0 in range (la [0 ], 0 , - 1 ):
2471
- new_la = [min (mu_0 , la [i ]) for i in range (1 , len (la ))]
2472
- for mu in Partitions_inside_lambda (new_la ):
2473
- yield [mu_0 ] + mu
2474
- yield [0 ] * len (la )
2475
- return
2530
+ """
2531
+ Iterate over all partitions contained in la with the same number
2532
+ of parts including 0s.
2533
+ """
2534
+ from sage .combinat .partition import Partitions
2535
+ for k in range (sum (la ), - 1 , - 1 ):
2536
+ for mu in Partitions (k , outer = la ):
2537
+ yield mu + [0 ]* (len (la )- len (mu ))
2476
2538
2477
2539
def Partitions_inside_lambda_with_smallest_at_least_k (la , k ):
2478
- "Iterate over all partitions contained in la with the smallest entry at least k."
2479
- if not la :
2480
- yield []
2481
- return
2482
- if la [- 1 ] < k :
2483
- yield
2484
- return
2485
- for mu in Partitions_inside_lambda ([val - k for val in la ]):
2540
+ """
2541
+ Iterate over all partitions contained in la with the smallest
2542
+ entry at least k.
2543
+ """
2544
+ for mu in Partitions_inside_lambda ([val - k for val in la ]):
2486
2545
yield [mu [i ] + k for i in range (len (la ))]
2487
- return
2488
2546
2489
2547
def possible_middle_row_for_b_odd (a , c ):
2490
- "Iterate over all possible middle row for SCPP inside box(a,b,c) when b is odd."
2548
+ """
2549
+ Iterate over all possible middle row for SCPP inside box(a,b,c)
2550
+ when b is odd.
2551
+ """
2491
2552
if a * c % 2 == 1 :
2492
2553
yield
2493
2554
return
@@ -2496,18 +2557,22 @@ def possible_middle_row_for_b_odd(a, c):
2496
2557
if not a % 2 :
2497
2558
la = nu + mu
2498
2559
else :
2499
- la = nu + [c // 2 ] + mu
2560
+ la = nu + [c // 2 ] + mu
2500
2561
yield la
2501
- return
2502
2562
2503
2563
def possible_middle_row_for_b_even (a , c ):
2504
- "Iterate over all possible middle ((b/2)+1)st row for SCPP inside box(a,b,c) when b is even."
2564
+ """
2565
+ Iterate over all possible middle ((b/2)+1)st row for SCPP inside
2566
+ box(a,b,c) when b is even.
2567
+ """
2505
2568
for mu in Partitions_inside_lambda ([c // 2 for i in range ((a + 1 ) // 2 )]):
2569
+ if not mu :
2570
+ yield []
2571
+ continue
2506
2572
nu = [c - mu [len (mu )- 1 - i ] for i in range (a // 2 )]
2507
2573
for tau in Partitions_inside_lambda_with_smallest_at_least_k (nu , mu [0 ]):
2508
2574
la = tau + mu
2509
2575
yield la
2510
- return
2511
2576
2512
2577
def PPs_with_first_row_la_and_with_k_rows (la , k ):
2513
2578
"Iterate over PPs with first row la and with k rows in total."
@@ -2520,7 +2585,6 @@ def PPs_with_first_row_la_and_with_k_rows(la, k):
2520
2585
for mu in Partitions_inside_lambda (la ):
2521
2586
for PP in PPs_with_first_row_la_and_with_k_rows (mu , k - 1 ):
2522
2587
yield [la ] + PP
2523
- return
2524
2588
2525
2589
def complement (PP , c ):
2526
2590
"Return the complement of PP with respect to height c"
@@ -2531,18 +2595,19 @@ def complement(PP, c):
2531
2595
return [[c - PP [b - 1 - i ][a - 1 - j ] for j in range (a )] for i in range (b )]
2532
2596
2533
2597
if b % 2 == 1 :
2534
- for la in possible_middle_row_for_b_odd (a , c ): # la is the middle row of SCPP
2598
+ # la is the middle row of SCPP
2599
+ for la in possible_middle_row_for_b_odd (a , c ):
2535
2600
for PP in PPs_with_first_row_la_and_with_k_rows (la , (b + 1 ) // 2 ):
2536
2601
PP_below = PP [1 :]
2537
2602
PP_above = complement (PP_below , c )
2538
2603
yield self .element_class (self , PP_above + [la ] + PP_below )
2539
2604
else :
2540
- for la in possible_middle_row_for_b_even (a , c ): # la is the middle ((a/2)+1)st row of SCPP
2605
+ # la is the middle ((a/2)+1)st row of SCPP
2606
+ for la in possible_middle_row_for_b_even (a , c ):
2541
2607
for PP in PPs_with_first_row_la_and_with_k_rows (la , b // 2 ):
2542
2608
PP_below = PP
2543
2609
PP_above = complement (PP_below , c )
2544
2610
yield self .element_class (self , PP_above + PP_below )
2545
- return
2546
2611
2547
2612
def cardinality (self ) -> Integer :
2548
2613
r"""
@@ -2718,7 +2783,6 @@ def __iter__(self) -> Iterator:
2718
2783
for p in PlanePartitions (self ._box ):
2719
2784
if p .is_TCPP ():
2720
2785
yield self .element_class (self , p )
2721
- return
2722
2786
2723
2787
def cardinality (self ) -> Integer :
2724
2788
r"""
@@ -2741,8 +2805,10 @@ def cardinality(self) -> Integer:
2741
2805
a = self ._box [0 ]
2742
2806
c = self ._box [2 ]
2743
2807
return Integer (binomial (c // 2 + a - 1 , a - 1 )
2744
- * prod ((c + i + j + 1 ) / (i + j + 1 )
2745
- for j in range (1 , a - 1 ) for i in range (1 , 1 + j )))
2808
+ * prod (c + i + j + 1
2809
+ for j in range (1 , a - 1 ) for i in range (1 , 1 + j ))
2810
+ // prod (i + j + 1
2811
+ for j in range (1 , a - 1 ) for i in range (1 , 1 + j )))
2746
2812
2747
2813
2748
2814
# Class 7
@@ -2797,14 +2863,22 @@ def __iter__(self) -> Iterator:
2797
2863
EXAMPLES::
2798
2864
2799
2865
sage: list(PlanePartitions([4,4,2], symmetry='SSCPP'))
2800
- [Plane partition [[2, 2, 2 , 1], [2, 2 , 1], [2 , 1], [1]],
2866
+ [Plane partition [[1, 1, 1 , 1], [1, 1 , 1, 1 ], [1 , 1, 1, 1 ], [1, 1, 1, 1]],
2801
2867
Plane partition [[2, 2, 2, 1], [2, 1, 1], [2, 1, 1], [1]],
2802
2868
Plane partition [[2, 2, 1, 1], [2, 2, 1, 1], [1, 1], [1, 1]],
2869
+ Plane partition [[2, 2, 2, 1], [2, 2, 1], [2, 1], [1]],
2803
2870
Plane partition [[2, 2, 1, 1], [2, 1, 1, 1], [1, 1, 1], [1, 1]],
2804
- Plane partition [[2, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1]],
2805
- Plane partition [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]]
2871
+ Plane partition [[2, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1]]]
2872
+
2873
+ TESTS::
2874
+
2875
+ sage: all(len(set(PP)) == PP.cardinality()
2876
+ ....: for a, b in cartesian_product([range(5), range(0, 5, 2)])
2877
+ ....: if (PP := PlanePartitions([a, a, b], symmetry='SSCPP')))
2878
+ True
2806
2879
"""
2807
- for p in PlanePartitions (self ._box ):
2880
+ # any SSCPP is a SPP
2881
+ for p in PlanePartitions (self ._box , symmetry = 'SPP' ):
2808
2882
if p .is_SSCPP ():
2809
2883
yield self .element_class (self , p )
2810
2884
@@ -2896,8 +2970,16 @@ def __iter__(self) -> Iterator:
2896
2970
2897
2971
sage: list(PlanePartitions([2,2,2], symmetry='CSTCPP'))
2898
2972
[Plane partition [[2, 1], [1]]]
2973
+
2974
+ TESTS::
2975
+
2976
+ sage: all(len(set(PP)) == PP.cardinality()
2977
+ ....: for n in range(0, 5, 2)
2978
+ ....: if (PP := PlanePartitions([n]*3, symmetry='CSTCPP')))
2979
+ True
2899
2980
"""
2900
- for p in PlanePartitions (self ._box ):
2981
+ # any CSTCPP is a TSPP, a SSCPP and a CSSCPP
2982
+ for p in PlanePartitions (self ._box , symmetry = 'TSPP' ):
2901
2983
if p .is_CSTCPP ():
2902
2984
yield self .element_class (self , p )
2903
2985
@@ -2973,7 +3055,8 @@ def __iter__(self) -> Iterator:
2973
3055
sage: list(PlanePartitions([2,2,2], symmetry='CSSCPP'))
2974
3056
[Plane partition [[2, 1], [1]]]
2975
3057
"""
2976
- for p in PlanePartitions (self ._box ):
3058
+ # any CSSCPP is a SCPP and an CSPP, there are much fewer CSPP
3059
+ for p in PlanePartitions (self ._box , symmetry = 'CSPP' ):
2977
3060
if p .is_CSSCPP ():
2978
3061
yield self .element_class (self , p )
2979
3062
@@ -3191,7 +3274,6 @@ def __iter__(self) -> Iterator:
3191
3274
"""
3192
3275
for acl in self .to_poset ().antichains_iterator ():
3193
3276
yield self .from_antichain (acl )
3194
- return
3195
3277
3196
3278
def cardinality (self ) -> Integer :
3197
3279
r"""
0 commit comments