ASKSAGE: Sage Q&A Forum - Individual question feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Wed, 04 Jan 2017 21:47:04 -0600apply functions iteratively (modified re-post)https://ask.sagemath.org/question/36159/apply-functions-iteratively-modified-re-post/*(This is a modified re-post of [Apply Functions Iteratively](https://ask.sagemath.org/question/35989/apply-functions-iteratively/) since my original question wasn't answered)*
I have a few functions `R1,R2,R3,R4` which act on vectors. If `X = matrix(3,1,(x0,y0,r))` then I have
`def R1(X):
return matrix(3,1,(X[0,0]/(X[0,0]^2+X[1,0]^2-X[2,0]^2),X[1,0]/(X[0,0]^2+X[1,0]^2-X[2,0]^2),X[2,0]/abs(X[0,0]^2+X[1,0]^2-X[2,0]^2)))`
`def R2(X):
return matrix(3,1,(-X[0,0],X[1,0],X[2,0]))`
`def R3(X):
return matrix(3,1,(-X[0,0]+2,X[1,0],X[2,0]))`
`def R4(X):
return matrix(3,1,(X[0,0],-X[1,0]+2,X[2,0]))`
For instance, if `v = matrix(3,1,(1,1,1))`, then applying R2 to v gives the matrix $(-1,1,1)$.
I'd like to apply about 10 "levels" of iteration of these functions and have the output as a list of vectors.
So, the list should be
$R1(v), R2(v),R3(v),R4(v),R1^2(v),R2(R1(v)),R3(R1(v)),R4(R1(v)),R1^3(v),...,R1^{10}(v)\,...,R4^{10}(v)$
(as vectors)
where $R_j^n = R_j \circ \cdots \circ R_j$ $n$ times.
I know how to apply a single function iteratively, but I don't know how to combine/loop the four together.
Thanks.Tue, 03 Jan 2017 19:14:39 -0600https://ask.sagemath.org/question/36159/apply-functions-iteratively-modified-re-post/Answer by tmonteil for <p><em>(This is a modified re-post of <a href="https://ask.sagemath.org/question/35989/apply-functions-iteratively/">Apply Functions Iteratively</a> since my original question wasn't answered)</em> </p>
<p>I have a few functions <code>R1,R2,R3,R4</code> which act on vectors. If <code>X = matrix(3,1,(x0,y0,r))</code> then I have</p>
<p><code>def R1(X):
return matrix(3,1,(X[0,0]/(X[0,0]^2+X[1,0]^2-X[2,0]^2),X[1,0]/(X[0,0]^2+X[1,0]^2-X[2,0]^2),X[2,0]/abs(X[0,0]^2+X[1,0]^2-X[2,0]^2)))</code></p>
<p><code>def R2(X):
return matrix(3,1,(-X[0,0],X[1,0],X[2,0]))</code></p>
<p><code>def R3(X):
return matrix(3,1,(-X[0,0]+2,X[1,0],X[2,0]))</code></p>
<p><code>def R4(X):
return matrix(3,1,(X[0,0],-X[1,0]+2,X[2,0]))</code></p>
<p>For instance, if <code>v = matrix(3,1,(1,1,1))</code>, then applying R2 to v gives the matrix $(-1,1,1)$.</p>
<p>I'd like to apply about 10 "levels" of iteration of these functions and have the output as a list of vectors.
So, the list should be
$R1(v), R2(v),R3(v),R4(v),R1^2(v),R2(R1(v)),R3(R1(v)),R4(R1(v)),R1^3(v),...,R1^{10}(v)\,...,R4^{10}(v)$
(as vectors)
where $R_j^n = R_j \circ \cdots \circ R_j$ $n$ times.</p>
<p>I know how to apply a single function iteratively, but I don't know how to combine/loop the four together.
Thanks.</p>
https://ask.sagemath.org/question/36159/apply-functions-iteratively-modified-re-post/?answer=36160#post-id-36160Let 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.Tue, 03 Jan 2017 19:45:10 -0600https://ask.sagemath.org/question/36159/apply-functions-iteratively-modified-re-post/?answer=36160#post-id-36160Comment by Daniel L for <p>Let me assume that you want all possible compositions of length say n=3.</p>
<p>First, let us put the four functions into a list <code>L</code>:</p>
<pre><code>sage: L = [R1,R2,R3,R4] ; L
[<function R1 at 0x7fc150827320>,
<function R2 at 0x7fc1508272a8>,
<function R3 at 0x7fc150827a28>,
<function R4 at 0x7fc150827aa0>]
</code></pre>
<p>Then, we want to look at the product of <code>L</code> with itself <code>n</code> times, and for each <code>n-uple</code> <code>i</code>, we want to appy each element of <code>i</code> (which is a function) iteratively starting from the vector <code>v</code>:</p>
<pre><code>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
</code></pre>
<p><strong>EDIT</strong> 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:</p>
<pre><code>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]}
</code></pre>
<p>In case there are a lot of equalities in the partial compotitions we can an iterative approach (as <a href="/users/62/nbruin/">@nbruin</a>'s answer) so that the simplification is done at each step:</p>
<pre><code>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]}
</code></pre>
<p>In your example, you will save a lot of redundent computations, therefore you will be able to go way further.</p>
https://ask.sagemath.org/question/36159/apply-functions-iteratively-modified-re-post/?comment=36193#post-id-36193This works well. Thank you!Wed, 04 Jan 2017 21:47:04 -0600https://ask.sagemath.org/question/36159/apply-functions-iteratively-modified-re-post/?comment=36193#post-id-36193Answer by nbruin for <p><em>(This is a modified re-post of <a href="https://ask.sagemath.org/question/35989/apply-functions-iteratively/">Apply Functions Iteratively</a> since my original question wasn't answered)</em> </p>
<p>I have a few functions <code>R1,R2,R3,R4</code> which act on vectors. If <code>X = matrix(3,1,(x0,y0,r))</code> then I have</p>
<p><code>def R1(X):
return matrix(3,1,(X[0,0]/(X[0,0]^2+X[1,0]^2-X[2,0]^2),X[1,0]/(X[0,0]^2+X[1,0]^2-X[2,0]^2),X[2,0]/abs(X[0,0]^2+X[1,0]^2-X[2,0]^2)))</code></p>
<p><code>def R2(X):
return matrix(3,1,(-X[0,0],X[1,0],X[2,0]))</code></p>
<p><code>def R3(X):
return matrix(3,1,(-X[0,0]+2,X[1,0],X[2,0]))</code></p>
<p><code>def R4(X):
return matrix(3,1,(X[0,0],-X[1,0]+2,X[2,0]))</code></p>
<p>For instance, if <code>v = matrix(3,1,(1,1,1))</code>, then applying R2 to v gives the matrix $(-1,1,1)$.</p>
<p>I'd like to apply about 10 "levels" of iteration of these functions and have the output as a list of vectors.
So, the list should be
$R1(v), R2(v),R3(v),R4(v),R1^2(v),R2(R1(v)),R3(R1(v)),R4(R1(v)),R1^3(v),...,R1^{10}(v)\,...,R4^{10}(v)$
(as vectors)
where $R_j^n = R_j \circ \cdots \circ R_j$ $n$ times.</p>
<p>I know how to apply a single function iteratively, but I don't know how to combine/loop the four together.
Thanks.</p>
https://ask.sagemath.org/question/36159/apply-functions-iteratively-modified-re-post/?answer=36163#post-id-36163If you want various levels in the list, you probably want the original as well. You could do
ops=[R1,R2,R3,R4]
T=[v]
L=[]
for i in range(10):
L += T
T = [f(v) for v in T for f in ops]Tue, 03 Jan 2017 21:30:10 -0600https://ask.sagemath.org/question/36159/apply-functions-iteratively-modified-re-post/?answer=36163#post-id-36163