# Revision history [back]

Let me assume that you want all possible compositions of length say n=3.

First, let us put the four functions into a list L:

sage: L = [R1,R2,R3,R4] ; L
[<function R1 at 0x7fc150827320>,
<function R2 at 0x7fc1508272a8>,
<function R3 at 0x7fc150827a28>,
<function R4 at 0x7fc150827aa0>]


Then, we want to look at the product of L n times, and for each n-uple i, we want to appy each element of i (which is a function) iteratively starting fro the vector v:

sage: n = 3
sage: from itertools import product
sage: for i in product(L, repeat=3):
....:     w = v
....:     print i        # to see which functions are applied (from left to right)
....:     for f in i:
....:         w = f(w)
....:     print w      # to see the composition applied to v


Let me assume that you want all possible compositions of length say n=3.

First, let us put the four functions into a list L:

sage: L = [R1,R2,R3,R4] ; L
[<function R1 at 0x7fc150827320>,
<function R2 at 0x7fc1508272a8>,
<function R3 at 0x7fc150827a28>,
<function R4 at 0x7fc150827aa0>]


Then, we want to look at the product of L with itself n times, and for each n-uple i, we want to appy each element of i (which is a function) iteratively starting fro the vector v:

sage: n = 3
sage: from itertools import product
sage: for i in product(L, repeat=3):
....:     w = v
....:     print i        # to see which functions are applied (from left to right)
....:     for f in i:
....:         w = f(w)
....:     print w      # to see the composition applied to v


Let me assume that you want all possible compositions of length say n=3.

First, let us put the four functions into a list L:

sage: L = [R1,R2,R3,R4] ; L
[<function R1 at 0x7fc150827320>,
<function R2 at 0x7fc1508272a8>,
<function R3 at 0x7fc150827a28>,
<function R4 at 0x7fc150827aa0>]


Then, we want to look at the product of L with itself n times, and for each n-uple i, we want to appy each element of i (which is a function) iteratively starting fro from the vector v:

sage: n = 3
sage: from itertools import product
sage: for i in product(L, repeat=3):
....:     w = v
....:     print i        # to see which functions are applied (from left to right)
....:     for f in i:
....:         w = f(w)
....:     print w      # to see the composition applied to v


Let me assume that you want all possible compositions of length say n=3.

First, let us put the four functions into a list L:

sage: L = [R1,R2,R3,R4] ; L
[<function R1 at 0x7fc150827320>,
<function R2 at 0x7fc1508272a8>,
<function R3 at 0x7fc150827a28>,
<function R4 at 0x7fc150827aa0>]


Then, we want to look at the product of L with itself n times, and for each n-uple i, we want to appy each element of i (which is a function) iteratively starting from the vector v:

sage: n = 3
sage: from itertools import product
sage: for i in product(L, repeat=3):
....:     w = v
....:     print i        # to see which functions are applied (from left to right)
....:     for f in i:
....:         w = f(w)
....:     print w      # to see the composition applied to v


EDIT If you want to avoid redundency, you can put your results in a set. However, matrices are unhashable by default, so they can not be elements of sets. Hence you have to make them immutable first:

sage: S = set()
sage: for i in product(L, repeat=3):
....:     w = v
....:     for f in i:
....:         w = f(w)
....:         w.set_immutable()
sage: S
{[-3]
[ 1]
[ 1], [-1]
[ 1]
[ 1], [1/3]
[1/9]
[1/9], [1]
[1]
[1], [3]
[1]
[1]}


Let me assume that you want all possible compositions of length say n=3.

First, let us put the four functions into a list L:

sage: L = [R1,R2,R3,R4] ; L
[<function R1 at 0x7fc150827320>,
<function R2 at 0x7fc1508272a8>,
<function R3 at 0x7fc150827a28>,
<function R4 at 0x7fc150827aa0>]


Then, we want to look at the product of L with itself n times, and for each n-uple i, we want to appy each element of i (which is a function) iteratively starting from the vector v:

sage: n = 3
sage: from itertools import product
sage: for i in product(L, repeat=3):
....:     w = v
....:     print i        # to see which functions are applied (from left to right)
....:     for f in i:
....:         w = f(w)
....:     print w      # to see the composition applied to v


EDIT If you want to avoid redundency, you can put your results in a set. However, matrices are unhashable by default, so they can not be elements of sets. Hence you have to make them immutable first:

sage: S = set()
sage: for i in product(L, repeat=3):
....:     w = v
....:     for f in i:
....:         w = f(w)
....:         w.set_immutable()
sage: S
{[-3]
[ 1]
[ 1], [-1]
[ 1]
[ 1], [1/3]
[1/9]
[1/9], [1]
[1]
[1], [3]
[1]
[1]}


In case there are a lot of equalities in the partial compotitions we can an iterative approach (as @nbruin's answer) so that the simplification is done at each step:

sage: v.set_immutable()
sage: Sold = {v}
sage: for i in range(n):
....:     Snew = set()
....:     for f in L:
....:         for u in Sold:
....:             w = f(u)
....:             w.set_immutable()
....:     Sold = Snew
sage: Sold
{[-3]
[ 1]
[ 1], [-1]
[ 1]
[ 1], [1/3]
[1/9]
[1/9], [1]
[1]
[1], [3]
[1]
[1]}


In your example, you will save a lot of redundent computations, therefore you will be able to go way further.