151
151
152
152
Finally, here are the partitions of `4` with ``[1,1,1]`` as an inner
153
153
bound (i. e., the partitions of `4` containing the partition ``[1,1,1]``).
154
- Note that ``inner`` sets ``min_length`` to the length of its argument::
154
+ Note that ``inner`` sets ``min_length`` to the length of its argument,
155
+ interpreted as a partition::
155
156
156
157
sage: Partitions(4, inner=[1,1,1]).list()
157
158
[[2, 1, 1], [1, 1, 1, 1]]
@@ -6164,6 +6165,27 @@ def __classcall_private__(cls, n=None, **kwargs):
6164
6165
"""
6165
6166
if n is infinity :
6166
6167
raise ValueError ("n cannot be infinite" )
6168
+ if 'length' in kwargs and ('min_length' in kwargs or 'max_length' in kwargs ):
6169
+ raise ValueError ("do not specify the length together with the minimal or maximal length" )
6170
+ # remove kwargs that specify the default value
6171
+ if 'min_part' in kwargs and kwargs ['min_part' ] == 1 :
6172
+ del kwargs ['min_part' ]
6173
+ if 'max_slope' in kwargs and not kwargs ['max_slope' ]:
6174
+ del kwargs ['max_slope' ]
6175
+ # preprocess for UniqueRepresentation
6176
+ if 'outer' in kwargs and not isinstance (kwargs ['outer' ], Partition ):
6177
+ m = infinity
6178
+ kwargs ['outer' ] = [m for e in kwargs ['outer' ]
6179
+ if (m := min (m , e if e is infinity else ZZ (e ))) > 0 ]
6180
+ if kwargs ['outer' ] and kwargs ['outer' ][0 ] is infinity :
6181
+ kwargs ['outer' ] = tuple (kwargs ['outer' ])
6182
+ else :
6183
+ kwargs ['outer' ] = Partition (kwargs ['outer' ])
6184
+ if 'inner' in kwargs and not isinstance (kwargs ['inner' ], Partition ):
6185
+ m = ZZ .zero ()
6186
+ kwargs ['inner' ] = Partition (reversed ([(m := max (m , e ))
6187
+ for e in reversed (kwargs ['inner' ])]))
6188
+
6167
6189
if isinstance (n , (int , Integer )):
6168
6190
if not kwargs :
6169
6191
return Partitions_n (n )
@@ -6208,9 +6230,6 @@ def __classcall_private__(cls, n=None, **kwargs):
6208
6230
+ "'ending', 'regular' and 'restricted' "
6209
6231
+ "cannot be combined with anything else" )
6210
6232
6211
- if 'length' in kwargs and ('min_length' in kwargs or 'max_length' in kwargs ):
6212
- raise ValueError ("do not specify the length together with the minimal or maximal length" )
6213
-
6214
6233
if set (kwargs ).issubset (['length' , 'min_part' , 'max_part' ,
6215
6234
'min_length' , 'max_length' ]):
6216
6235
if 'length' in kwargs :
@@ -6239,7 +6258,8 @@ def __classcall_private__(cls, n=None, **kwargs):
6239
6258
6240
6259
return Partitions_length_and_parts_constrained (n , min_length , max_length , min_part , max_part )
6241
6260
6242
- # FIXME: should inherit from IntegerListLex, and implement repr, or _name as a lazy attribute
6261
+ # translate keywords to IntegerListsLex
6262
+ # FIXME: should inherit from IntegerListsLex, and implement repr, or _name as a lazy attribute
6243
6263
kwargs ['name' ] = "Partitions of the integer {} satisfying constraints {}" .format (n , ", " .join (["{}={}" .format (key , kwargs [key ]) for key in sorted (kwargs )]))
6244
6264
6245
6265
# min_part is at least 1, and it is 1 by default
@@ -6252,18 +6272,17 @@ def __classcall_private__(cls, n=None, **kwargs):
6252
6272
raise ValueError ("the minimum slope must be nonnegative" )
6253
6273
6254
6274
if 'outer' in kwargs :
6275
+ kwargs ['ceiling' ] = tuple (kwargs ['outer' ])
6255
6276
kwargs ['max_length' ] = min (len (kwargs ['outer' ]),
6256
6277
kwargs .get ('max_length' , infinity ))
6257
-
6258
- kwargs ['ceiling' ] = tuple (kwargs ['outer' ])
6259
6278
del kwargs ['outer' ]
6260
6279
6261
6280
if 'inner' in kwargs :
6262
- inner = [x for x in kwargs ['inner' ] if x > 0 ]
6263
- kwargs ['floor' ] = inner
6264
- kwargs ['min_length' ] = max (len (inner ),
6281
+ kwargs ['floor' ] = tuple (kwargs ['inner' ])
6282
+ kwargs ['min_length' ] = max (len (kwargs ['inner' ]),
6265
6283
kwargs .get ('min_length' , 0 ))
6266
6284
del kwargs ['inner' ]
6285
+
6267
6286
return Partitions_with_constraints (n , ** kwargs )
6268
6287
6269
6288
if n is None or n is NN or n is NonNegativeIntegers ():
@@ -6288,6 +6307,8 @@ def __classcall_private__(cls, n=None, **kwargs):
6288
6307
elif 'max_part' in kwargs and 'max_length' in kwargs :
6289
6308
return PartitionsInBox (kwargs ['max_length' ], kwargs ['max_part' ])
6290
6309
6310
+ # IntegerListsLex does not deal well with infinite sets,
6311
+ # so we use a class inheriting from Partitions
6291
6312
return Partitions_all_constrained (** kwargs )
6292
6313
6293
6314
raise ValueError ("n must be an integer or be equal to one of "
@@ -6811,17 +6832,41 @@ def __init__(self, **kwargs):
6811
6832
"""
6812
6833
TESTS::
6813
6834
6814
- sage: TestSuite(sage.combinat.partition.Partitions_all_constrained(max_length=3)).run() # long time
6835
+ sage: TestSuite(sage.combinat.partition.Partitions_all_constrained(max_length=3, max_slope=0)).run() # long time
6836
+
6837
+ sage: list(Partitions(max_part=4, max_slope=-3))
6838
+ [[], [1], [2], [3], [4], [4, 1]]
6839
+
6840
+ sage: [pi for n in range(10) for pi in Partitions(n, max_part=4, max_slope=-3)]
6841
+ [[], [1], [2], [3], [4], [4, 1]]
6815
6842
"""
6816
6843
self ._constraints = kwargs
6817
- Partitions .__init__ (self , is_infinite = True )
6844
+ self ._max_sum = infinity
6845
+ if 'outer' in kwargs and kwargs ['outer' ] and kwargs ['outer' ][0 ] is not infinity :
6846
+ self ._max_sum = kwargs ['outer' ][0 ] * len (kwargs ['outer' ])
6847
+ else :
6848
+ if 'length' in kwargs :
6849
+ max_length = kwargs ['length' ]
6850
+ elif 'max_length' in kwargs :
6851
+ max_length = kwargs ['max_length' ]
6852
+ elif 'max_part' in kwargs and kwargs .get ('max_slope' , 0 ) < 0 :
6853
+ max_length = 1 + (kwargs ['max_part' ] - 1 ) // (- kwargs ['max_slope' ])
6854
+ else :
6855
+ max_length = infinity
6856
+
6857
+ if max_length is not infinity and 'max_part' in kwargs :
6858
+ self ._max_sum = kwargs ['max_part' ] * max_length
6859
+
6860
+ Partitions .__init__ (self , is_infinite = self ._max_sum is infinity )
6818
6861
6819
6862
def __contains__ (self , x ):
6820
6863
"""
6864
+ Check if ``x`` is contained in ``self``.
6865
+
6821
6866
TESTS::
6822
6867
6823
6868
sage: from sage.combinat.partition import Partitions_all_constrained
6824
- sage: P = Partitions_all_constrained(max_part=3, max_length=2)
6869
+ sage: P = Partitions_all_constrained(max_part=3, max_length=2, max_slope=0 )
6825
6870
sage: 1 in P
6826
6871
False
6827
6872
sage: Partition([2,1]) in P
@@ -6866,9 +6911,13 @@ def __iter__(self):
6866
6911
sage: it = iter(P)
6867
6912
sage: [next(it) for i in range(10)]
6868
6913
[[], [1], [2], [1, 1], [3], [2, 1], [4], [3, 1], [2, 2], [5]]
6914
+
6915
+ sage: P = Partitions(inner=[2,2], outer=[3,2,1])
6916
+ sage: list(P)
6917
+ [[2, 2], [3, 2], [2, 2, 1], [3, 2, 1]]
6869
6918
"""
6870
6919
n = 0
6871
- while True :
6920
+ while n <= self . _max_sum :
6872
6921
for p in Partitions (n , ** self ._constraints ):
6873
6922
yield self .element_class (self , p )
6874
6923
n += 1
@@ -7608,7 +7657,7 @@ def __classcall_private__(cls, n, parts):
7608
7657
sage: list(Partitions(4,parts_in=vector(ZZ,[2,4])))
7609
7658
[[4], [2, 2]]
7610
7659
"""
7611
- parts = tuple (sorted (set (map (ZZ ,parts ))))
7660
+ parts = tuple (sorted (set (map (ZZ , parts ))))
7612
7661
return super ().__classcall__ (cls , Integer (n ), parts )
7613
7662
7614
7663
def __init__ (self , n , parts ):
@@ -8356,6 +8405,34 @@ class Partitions_with_constraints(IntegerListsLex):
8356
8405
Element = Partition
8357
8406
options = Partitions .options
8358
8407
8408
+ def __contains__ (self , x ):
8409
+ """
8410
+ Check if ``x`` is contained in ``self``.
8411
+
8412
+ TESTS::
8413
+
8414
+ sage: P = Partitions(4, max_slope=-2)
8415
+ sage: [3,1] in P
8416
+ True
8417
+ sage: [3,1,0] in P
8418
+ True
8419
+ sage: [2,2] in P
8420
+ False
8421
+ sage: [3,1,None] in P
8422
+ False
8423
+
8424
+ sage: [1,3] in Partitions(4, min_slope=-1)
8425
+ False
8426
+ """
8427
+ # strip off trailing 0s
8428
+ for i in range (len (x )- 1 , - 1 , - 1 ):
8429
+ if x [i ] != 0 :
8430
+ x = x [:i + 1 ]
8431
+ break
8432
+ else :
8433
+ x = []
8434
+ return super ().__contains__ (x )
8435
+
8359
8436
8360
8437
######################
8361
8438
# Regular Partitions #
0 commit comments