1 | initial version |

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
```

2 | No.2 Revision |

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
```

3 | No.3 Revision |

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
```

4 | No.4 Revision |

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()
....: S.add(w)
sage: S
{[-3]
[ 1]
[ 1], [-1]
[ 1]
[ 1], [1/3]
[1/9]
[1/9], [1]
[1]
[1], [3]
[1]
[1]}
```

5 | No.5 Revision |

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()
....: S.add(w)
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()
....: Snew.add(w)
....: 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.

Copyright Sage, 2010. Some rights reserved under creative commons license. Content on this site is licensed under a Creative Commons Attribution Share Alike 3.0 license.