# Revision history [back]

To iterate over the power of a set, you can use itertools as follows:

sage: itertools.product(M, repeat=3)
<itertools.product object at 0x7fa377e38f50>


Which is a generator that you can expand into al list to be sure:

sage: list(itertools.product(M, repeat=3))
[(
[1 0]  [1 0]  [1 0]
[0 1], [0 1], [0 1]
),
(
[1 0]  [1 0]  [0 1]
[0 1], [0 1], [1 0]
),
(
[1 0]  [1 0]  [1 1]
[0 1], [0 1], [0 1]
),
(
[1 0]  [0 1]  [1 0]
[0 1], [1 0], [0 1]
),
(
[1 0]  [0 1]  [0 1]
[0 1], [1 0], [1 0]
),
(
[1 0]  [0 1]  [1 1]
[0 1], [1 0], [0 1]
),
(
[1 0]  [1 1]  [1 0]
[0 1], [0 1], [0 1]
),
(
[1 0]  [1 1]  [0 1]
[0 1], [0 1], [1 0]
),
(
[1 0]  [1 1]  [1 1]
[0 1], [0 1], [0 1]
),
(
[0 1]  [1 0]  [1 0]
[1 0], [0 1], [0 1]
),
(
[0 1]  [1 0]  [0 1]
[1 0], [0 1], [1 0]
),
(
[0 1]  [1 0]  [1 1]
[1 0], [0 1], [0 1]
),
(
[0 1]  [0 1]  [1 0]
[1 0], [1 0], [0 1]
),
(
[0 1]  [0 1]  [0 1]
[1 0], [1 0], [1 0]
),
(
[0 1]  [0 1]  [1 1]
[1 0], [1 0], [0 1]
),
(
[0 1]  [1 1]  [1 0]
[1 0], [0 1], [0 1]
),
(
[0 1]  [1 1]  [0 1]
[1 0], [0 1], [1 0]
),
(
[0 1]  [1 1]  [1 1]
[1 0], [0 1], [0 1]
),
(
[1 1]  [1 0]  [1 0]
[0 1], [0 1], [0 1]
),
(
[1 1]  [1 0]  [0 1]
[0 1], [0 1], [1 0]
),
(
[1 1]  [1 0]  [1 1]
[0 1], [0 1], [0 1]
),
(
[1 1]  [0 1]  [1 0]
[0 1], [1 0], [0 1]
),
(
[1 1]  [0 1]  [0 1]
[0 1], [1 0], [1 0]
),
(
[1 1]  [0 1]  [1 1]
[0 1], [1 0], [0 1]
),
(
[1 1]  [1 1]  [1 0]
[0 1], [0 1], [0 1]
),
(
[1 1]  [1 1]  [0 1]
[0 1], [0 1], [1 0]
),
(
[1 1]  [1 1]  [1 1]
[0 1], [0 1], [0 1]
)]


Each element of this list is a triple of matrices, you can make the producst of each such triple as follows:

sage: [prod(i) for i in itertools.product(M, repeat=3)]
[
[1 0]  [0 1]  [1 1]  [0 1]  [1 0]  [0 1]  [1 1]  [1 1]  [1 2]  [0 1]
[0 1], [1 0], [0 1], [1 0], [0 1], [1 1], [0 1], [1 0], [0 1], [1 0],

[1 0]  [0 1]  [1 0]  [0 1]  [1 1]  [0 1]  [1 0]  [0 1]  [1 1]  [1 1]
[0 1], [1 1], [0 1], [1 0], [0 1], [1 1], [1 1], [1 2], [0 1], [1 0],

[1 2]  [1 1]  [1 1]  [1 2]  [1 2]  [2 1]  [1 3]
[0 1], [1 0], [0 1], [1 1], [0 1], [1 0], [0 1]
]


If you want to make a function that returns a set, you can do, using the immutabilize function defined in my answer of this ask question:

sage: f = lambda l : {immutabilize(prod(i)) for i in itertools.product(M, repeat=l)}
sage: f(1)
{[0 1]
[1 0], [1 0]
[0 1], [1 1]
[0 1]}
sage: f(2)
{[0 1]
[1 0], [0 1]
[1 1], [1 0]
[0 1], [1 1]
[0 1], [1 1]
[1 0], [1 2]
[0 1]}
sage: f(3)
{[0 1]
[1 0], [0 1]
[1 1], [0 1]
[1 2], [1 0]
[0 1], [1 0]
[1 1], [1 1]
[0 1], [1 1]
[1 0], [1 2]
[0 1], [1 2]
[1 1], [1 3]
[0 1], [2 1]
[1 0]}
sage: f(4)
{[0 1]
[1 0], [0 1]
[1 1], [0 1]
[1 2], [0 1]
[1 3], [1 0]
[0 1], [1 0]
[1 1], [1 0]
[2 1], [1 1]
[0 1], [1 1]
[1 0], [1 1]
[1 2], [1 2]
[0 1], [1 2]
[1 1], [1 3]
[0 1], [1 3]
[1 2], [1 4]
[0 1], [2 1]
[1 0], [2 1]
[1 1], [2 3]
[1 1], [3 1]
[1 0]}


As you can see, many matrices in the list are the same, so that making a set seriously reduces the number of product to work with:

sage: [len(f(l)) for l in range(1,10)]
[3, 6, 11, 19, 32, 53, 87, 142, 231]


To be compared with:

sage: [3^l for l in range(1,10)]
[3, 9, 27, 81, 243, 729, 2187, 6561, 19683]


The formatting of sets of matrices is not very nice, but you can make it nicer while printing it as a list (still with the benefits of having removed repetitions):

sage: list(f(4))
[
[0 1]  [1 1]  [1 1]  [0 1]  [1 0]  [0 1]  [1 2]  [1 2]  [0 1]  [1 0]
[1 1], [1 0], [0 1], [1 0], [1 1], [1 2], [1 1], [0 1], [1 3], [2 1],

[1 1]  [1 0]  [1 4]  [3 1]  [2 1]  [1 3]  [1 3]  [2 3]  [2 1]
[1 2], [0 1], [0 1], [1 0], [1 1], [1 2], [0 1], [1 1], [1 0]
]


To iterate over the power of a set, you can use itertools as follows:

sage: itertools.product(M, repeat=3)
<itertools.product object at 0x7fa377e38f50>


Which is a generator that you can expand into al list to be sure:check its content is what you need:

sage: list(itertools.product(M, repeat=3))
[(
[1 0]  [1 0]  [1 0]
[0 1], [0 1], [0 1]
),
(
[1 0]  [1 0]  [0 1]
[0 1], [0 1], [1 0]
),
(
[1 0]  [1 0]  [1 1]
[0 1], [0 1], [0 1]
),
(
[1 0]  [0 1]  [1 0]
[0 1], [1 0], [0 1]
),
(
[1 0]  [0 1]  [0 1]
[0 1], [1 0], [1 0]
),
(
[1 0]  [0 1]  [1 1]
[0 1], [1 0], [0 1]
),
(
[1 0]  [1 1]  [1 0]
[0 1], [0 1], [0 1]
),
(
[1 0]  [1 1]  [0 1]
[0 1], [0 1], [1 0]
),
(
[1 0]  [1 1]  [1 1]
[0 1], [0 1], [0 1]
),
(
[0 1]  [1 0]  [1 0]
[1 0], [0 1], [0 1]
),
(
[0 1]  [1 0]  [0 1]
[1 0], [0 1], [1 0]
),
(
[0 1]  [1 0]  [1 1]
[1 0], [0 1], [0 1]
),
(
[0 1]  [0 1]  [1 0]
[1 0], [1 0], [0 1]
),
(
[0 1]  [0 1]  [0 1]
[1 0], [1 0], [1 0]
),
(
[0 1]  [0 1]  [1 1]
[1 0], [1 0], [0 1]
),
(
[0 1]  [1 1]  [1 0]
[1 0], [0 1], [0 1]
),
(
[0 1]  [1 1]  [0 1]
[1 0], [0 1], [1 0]
),
(
[0 1]  [1 1]  [1 1]
[1 0], [0 1], [0 1]
),
(
[1 1]  [1 0]  [1 0]
[0 1], [0 1], [0 1]
),
(
[1 1]  [1 0]  [0 1]
[0 1], [0 1], [1 0]
),
(
[1 1]  [1 0]  [1 1]
[0 1], [0 1], [0 1]
),
(
[1 1]  [0 1]  [1 0]
[0 1], [1 0], [0 1]
),
(
[1 1]  [0 1]  [0 1]
[0 1], [1 0], [1 0]
),
(
[1 1]  [0 1]  [1 1]
[0 1], [1 0], [0 1]
),
(
[1 1]  [1 1]  [1 0]
[0 1], [0 1], [0 1]
),
(
[1 1]  [1 1]  [0 1]
[0 1], [0 1], [1 0]
),
(
[1 1]  [1 1]  [1 1]
[0 1], [0 1], [0 1]
)]


Each element of this list is a triple of matrices, you can make the producst of each such triple as follows:

sage: [prod(i) for i in itertools.product(M, repeat=3)]
[
[1 0]  [0 1]  [1 1]  [0 1]  [1 0]  [0 1]  [1 1]  [1 1]  [1 2]  [0 1]
[0 1], [1 0], [0 1], [1 0], [0 1], [1 1], [0 1], [1 0], [0 1], [1 0],

[1 0]  [0 1]  [1 0]  [0 1]  [1 1]  [0 1]  [1 0]  [0 1]  [1 1]  [1 1]
[0 1], [1 1], [0 1], [1 0], [0 1], [1 1], [1 1], [1 2], [0 1], [1 0],

[1 2]  [1 1]  [1 1]  [1 2]  [1 2]  [2 1]  [1 3]
[0 1], [1 0], [0 1], [1 1], [0 1], [1 0], [0 1]
]


If you want to make a function that returns a set, you can do, using the immutabilize function defined in my answer of this ask question:

sage: f = lambda l : {immutabilize(prod(i)) for i in itertools.product(M, repeat=l)}
sage: f(1)
{[0 1]
[1 0], [1 0]
[0 1], [1 1]
[0 1]}
sage: f(2)
{[0 1]
[1 0], [0 1]
[1 1], [1 0]
[0 1], [1 1]
[0 1], [1 1]
[1 0], [1 2]
[0 1]}
sage: f(3)
{[0 1]
[1 0], [0 1]
[1 1], [0 1]
[1 2], [1 0]
[0 1], [1 0]
[1 1], [1 1]
[0 1], [1 1]
[1 0], [1 2]
[0 1], [1 2]
[1 1], [1 3]
[0 1], [2 1]
[1 0]}
sage: f(4)
{[0 1]
[1 0], [0 1]
[1 1], [0 1]
[1 2], [0 1]
[1 3], [1 0]
[0 1], [1 0]
[1 1], [1 0]
[2 1], [1 1]
[0 1], [1 1]
[1 0], [1 1]
[1 2], [1 2]
[0 1], [1 2]
[1 1], [1 3]
[0 1], [1 3]
[1 2], [1 4]
[0 1], [2 1]
[1 0], [2 1]
[1 1], [2 3]
[1 1], [3 1]
[1 0]}


As you can see, many matrices in the list are the same, so that making a set seriously reduces the number of product to work with:

sage: [len(f(l)) for l in range(1,10)]
[3, 6, 11, 19, 32, 53, 87, 142, 231]


To be compared with:

sage: [3^l for l in range(1,10)]
[3, 9, 27, 81, 243, 729, 2187, 6561, 19683]


The formatting of sets of matrices is not very nice, but you can make it nicer while printing it as a list (still with the benefits of having removed repetitions):

sage: list(f(4))
[
[0 1]  [1 1]  [1 1]  [0 1]  [1 0]  [0 1]  [1 2]  [1 2]  [0 1]  [1 0]
[1 1], [1 0], [0 1], [1 0], [1 1], [1 2], [1 1], [0 1], [1 3], [2 1],

[1 1]  [1 0]  [1 4]  [3 1]  [2 1]  [1 3]  [1 3]  [2 3]  [2 1]
[1 2], [0 1], [0 1], [1 0], [1 1], [1 2], [0 1], [1 1], [1 0]
]


To iterate over the power of a set, you can use itertools as follows:

sage: itertools.product(M, repeat=3)
<itertools.product object at 0x7fa377e38f50>


Which is a generator that you can expand into al list to check its content is what you need:

sage: list(itertools.product(M, repeat=3))
[(
[1 0]  [1 0]  [1 0]
[0 1], [0 1], [0 1]
),
(
[1 0]  [1 0]  [0 1]
[0 1], [0 1], [1 0]
),
(
[1 0]  [1 0]  [1 1]
[0 1], [0 1], [0 1]
),
(
[1 0]  [0 1]  [1 0]
[0 1], [1 0], [0 1]
),
(
[1 0]  [0 1]  [0 1]
[0 1], [1 0], [1 0]
),
(
[1 0]  [0 1]  [1 1]
[0 1], [1 0], [0 1]
),
(
[1 0]  [1 1]  [1 0]
[0 1], [0 1], [0 1]
),
(
[1 0]  [1 1]  [0 1]
[0 1], [0 1], [1 0]
),
(
[1 0]  [1 1]  [1 1]
[0 1], [0 1], [0 1]
),
(
[0 1]  [1 0]  [1 0]
[1 0], [0 1], [0 1]
),
(
[0 1]  [1 0]  [0 1]
[1 0], [0 1], [1 0]
),
(
[0 1]  [1 0]  [1 1]
[1 0], [0 1], [0 1]
),
(
[0 1]  [0 1]  [1 0]
[1 0], [1 0], [0 1]
),
(
[0 1]  [0 1]  [0 1]
[1 0], [1 0], [1 0]
),
(
[0 1]  [0 1]  [1 1]
[1 0], [1 0], [0 1]
),
(
[0 1]  [1 1]  [1 0]
[1 0], [0 1], [0 1]
),
(
[0 1]  [1 1]  [0 1]
[1 0], [0 1], [1 0]
),
(
[0 1]  [1 1]  [1 1]
[1 0], [0 1], [0 1]
),
(
[1 1]  [1 0]  [1 0]
[0 1], [0 1], [0 1]
),
(
[1 1]  [1 0]  [0 1]
[0 1], [0 1], [1 0]
),
(
[1 1]  [1 0]  [1 1]
[0 1], [0 1], [0 1]
),
(
[1 1]  [0 1]  [1 0]
[0 1], [1 0], [0 1]
),
(
[1 1]  [0 1]  [0 1]
[0 1], [1 0], [1 0]
),
(
[1 1]  [0 1]  [1 1]
[0 1], [1 0], [0 1]
),
(
[1 1]  [1 1]  [1 0]
[0 1], [0 1], [0 1]
),
(
[1 1]  [1 1]  [0 1]
[0 1], [0 1], [1 0]
),
(
[1 1]  [1 1]  [1 1]
[0 1], [0 1], [0 1]
)]


Each element of this list is a triple of matrices, you can make the producst of each such triple as follows:

sage: [prod(i) for i in itertools.product(M, repeat=3)]
[
[1 0]  [0 1]  [1 1]  [0 1]  [1 0]  [0 1]  [1 1]  [1 1]  [1 2]  [0 1]
[0 1], [1 0], [0 1], [1 0], [0 1], [1 1], [0 1], [1 0], [0 1], [1 0],

[1 0]  [0 1]  [1 0]  [0 1]  [1 1]  [0 1]  [1 0]  [0 1]  [1 1]  [1 1]
[0 1], [1 1], [0 1], [1 0], [0 1], [1 1], [1 1], [1 2], [0 1], [1 0],

[1 2]  [1 1]  [1 1]  [1 2]  [1 2]  [2 1]  [1 3]
[0 1], [1 0], [0 1], [1 1], [0 1], [1 0], [0 1]
]


If you want to make a function that returns a set, you can do, using the immutabilize function defined in my answer of this ask question:

sage: f = lambda l : {immutabilize(prod(i)) for i in itertools.product(M, repeat=l)}
sage: f(1)
{[0 1]
[1 0], [1 0]
[0 1], [1 1]
[0 1]}
sage: f(2)
{[0 1]
[1 0], [0 1]
[1 1], [1 0]
[0 1], [1 1]
[0 1], [1 1]
[1 0], [1 2]
[0 1]}
sage: f(3)
{[0 1]
[1 0], [0 1]
[1 1], [0 1]
[1 2], [1 0]
[0 1], [1 0]
[1 1], [1 1]
[0 1], [1 1]
[1 0], [1 2]
[0 1], [1 2]
[1 1], [1 3]
[0 1], [2 1]
[1 0]}
sage: f(4)
{[0 1]
[1 0], [0 1]
[1 1], [0 1]
[1 2], [0 1]
[1 3], [1 0]
[0 1], [1 0]
[1 1], [1 0]
[2 1], [1 1]
[0 1], [1 1]
[1 0], [1 1]
[1 2], [1 2]
[0 1], [1 2]
[1 1], [1 3]
[0 1], [1 3]
[1 2], [1 4]
[0 1], [2 1]
[1 0], [2 1]
[1 1], [2 3]
[1 1], [3 1]
[1 0]}


As you can see, many matrices in the list are the same, so that making a set seriously reduces the number of product to work with:

sage: [len(f(l)) for l in range(1,10)]
[3, 6, 11, 19, 32, 53, 87, 142, 231]


To be compared with:

sage: [3^l for l in range(1,10)]
[3, 9, 27, 81, 243, 729, 2187, 6561, 19683]


The formatting of sets of matrices is not very nice, but you can make it nicer while printing it as a list (still with the benefits of having removed repetitions):repetitions, because it comes from a set):

sage: list(f(4))
[
[0 1]  [1 1]  [1 1]  [0 1]  [1 0]  [0 1]  [1 2]  [1 2]  [0 1]  [1 0]
[1 1], [1 0], [0 1], [1 0], [1 1], [1 2], [1 1], [0 1], [1 3], [2 1],

[1 1]  [1 0]  [1 4]  [3 1]  [2 1]  [1 3]  [1 3]  [2 3]  [2 1]
[1 2], [0 1], [0 1], [1 0], [1 1], [1 2], [0 1], [1 1], [1 0]
]