# Is there a bug with the "parts" input in VectorPartitions?

Using Sagemath 10.1 if I run the code:

VectorPartitions([2,2], parts=[[0,1],[1,1],[1,0]]).list()


I get the answer [[[0, 1], [0, 1], [1, 0], [1, 0]], [[0, 1], [1, 0], [1, 1]], [[1, 1], [1, 1]]], as excepted. However, if I run

VectorPartitions([2,2], parts=[[1,1],[1,0],[0,1]]).list()


I get the answer []. And it gets worse; running

VectorPartitions([2,2], parts=[[1,0],[0,1],[1,1]]).list()


yields [[[1, 1], [1, 1]]]. I could go on, but I think you get the point.

Either I have absolutely no idea what the parts input is supposed to do or there is a bug here. So I guess my question is twofold: is there a bug and, if so, is there a reasonable workaround in the meantime?

edit retag close merge delete

Sort by » oldest newest most voted

I took a look to the code of the VectorPartitions and there was a line that i could not understand immediately...

@staticmethod
def __classcall_private__(cls, vec, min=None, parts=None, distinct=False, is_repeatable=None):
r"""
Create the class of vector partitions of vec where all parts
are greater than or equal to the vector min.

EXAMPLES::

sage: VP1 = VectorPartitions([2, 1])
sage: VP2 = VectorPartitions((2, 1), min = [0, 1])
sage: VP1 is VP2
True
"""
if min is None:
min = find_min(vec)  # tuple([0 for v in vec[:-1]]+[1])
if parts is None:
parts = list(IntegerVectorsIterator(vec, min=min))
if [0]*len(vec) in parts:
parts.remove([0]*len(vec))
if min in parts:
min_index = parts.index(min)
parts = parts[min_index:]
parts = list(parts)
for part_index in range(len(parts)):
parts[part_index] = tuple(parts[part_index])
return super().__classcall__(cls, tuple(vec), tuple(min), tuple(parts), distinct, is_repeatable)


The line that was somehow strange was the one where the code wants to work with the minimal vector [0, ... , 0, 1]... So i tried to use my min, to overwrite...

Let us compare:

sage: a, b, c = (0, 1), (1, 0), (1, 1)
sage:
sage: for p in Permutations((a,b,c)):
....:     print(p, '--->', list(VectorPartitions([2, 2], parts=p)))
....:
[(0, 1), (1, 0), (1, 1)] ---> [[[0, 1], [0, 1], [1, 0], [1, 0]], [[0, 1], [1, 0], [1, 1]], [[1, 1], [1, 1]]]
[(0, 1), (1, 1), (1, 0)] ---> [[[0, 1], [0, 1], [1, 0], [1, 0]], [[0, 1], [1, 0], [1, 1]], [[1, 1], [1, 1]]]
[(1, 0), (0, 1), (1, 1)] ---> [[[0, 1], [1, 0], [1, 1]], [[1, 1], [1, 1]]]
[(1, 0), (1, 1), (0, 1)] ---> []
[(1, 1), (0, 1), (1, 0)] ---> [[[0, 1], [1, 0], [1, 1]], [[0, 1], [0, 1], [1, 0], [1, 0]]]
[(1, 1), (1, 0), (0, 1)] ---> []
sage:


Yes, against my wish. We get a correct answer only when the parts are lexicographically sorted. Or we declare our min:

sage: for p in Permutations((a,b,c)):
....:     print(p, '--->', list(VectorPartitions([2, 2], parts=p, min=[0, 0])))
....:
[(0, 1), (1, 0), (1, 1)] ---> [[[0, 1], [0, 1], [1, 0], [1, 0]], [[0, 1], [1, 0], [1, 1]], [[1, 1], [1, 1]]]
[(0, 1), (1, 1), (1, 0)] ---> [[[0, 1], [0, 1], [1, 0], [1, 0]], [[0, 1], [1, 0], [1, 1]], [[1, 1], [1, 1]]]
[(1, 0), (0, 1), (1, 1)] ---> [[[0, 1], [0, 1], [1, 0], [1, 0]], [[0, 1], [1, 0], [1, 1]], [[1, 1], [1, 1]]]
[(1, 0), (1, 1), (0, 1)] ---> [[[0, 1], [0, 1], [1, 0], [1, 0]], [[0, 1], [1, 0], [1, 1]], [[1, 1], [1, 1]]]
[(1, 1), (0, 1), (1, 0)] ---> [[[1, 1], [1, 1]], [[0, 1], [1, 0], [1, 1]], [[0, 1], [0, 1], [1, 0], [1, 0]]]
[(1, 1), (1, 0), (0, 1)] ---> [[[1, 1], [1, 1]], [[0, 1], [1, 0], [1, 1]], [[0, 1], [0, 1], [1, 0], [1, 0]]]
sage:


(Tuples are used in order to have quickly the permutations.) (I did not try other cases... Hope it works, it is late in the night here...)

more

Thanks! Manually inputting the minimum vector to be zeros does appear to work in some further examples I tried. As you implicitly noted, it also seems one can sort the list of parts before inputting to get the correct answer.

Doing some brief testing, it seems that you get a decent speed up by sorting rather than inputting the minimum vector manually, especially when there are a large number of partitions. I have no idea why this should be faster.

( 2023-11-21 06:00:49 +0100 )edit

Please report the issue at https://github.com/sagemath/sage/issues

( 2023-11-21 13:15:34 +0100 )edit

On a different note parameter parts should better be called parts_in for the sake of consistency with Partitions(), Compositions() etc.

( 2023-11-21 16:55:09 +0100 )edit