Loading [MathJax]/jax/output/HTML-CSS/jax.js
Ask Your Question
1

apply functions iteratively (modified re-post)

asked 8 years ago

Daniel L gravatar image

updated 8 years ago

(This is a modified re-post of 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),R12(v),R2(R1(v)),R3(R1(v)),R4(R1(v)),R13(v),...,R110(v)...,R410(v) (as vectors) where Rnj=RjRj n times.

I know how to apply a single function iteratively, but I don't know how to combine/loop the four together. Thanks.

Preview: (hide)

2 Answers

Sort by » oldest newest most voted
1

answered 8 years ago

tmonteil gravatar image

updated 8 years ago

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.

Preview: (hide)
link

Comments

This works well. Thank you!

Daniel L gravatar imageDaniel L ( 8 years ago )
0

answered 8 years ago

nbruin gravatar image

updated 8 years ago

If 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]
Preview: (hide)
link

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 8 years ago

Seen: 750 times

Last updated: Jan 05 '17