1 # a "yield" version of the REMAP algorithm. a little easier to read
2 # than the Finite State Machine version
4 # python "yield" can be iterated. use this to make it clear how
5 # the indices are generated by using natural-looking nested loops
6 def iterate_indices(SVSHAPE
):
7 # get indices to iterate over, in the required order
11 # create lists of indices to iterate over in each dimension
15 # invert the indices if needed
16 if SVSHAPE
.invxyz
[0]: x_r
.reverse()
17 if SVSHAPE
.invxyz
[1]: y_r
.reverse()
18 if SVSHAPE
.invxyz
[2]: z_r
.reverse()
19 # start an infinite (wrapping) loop
21 for z
in z_r
: # loop over 1st order dimension
23 for y
in y_r
: # loop over 2nd order dimension
25 for x
in x_r
: # loop over 3rd order dimension
27 # ok work out which order to construct things in.
28 # start by creating a list of tuples of the dimension
30 vals
= [(SVSHAPE
.lims
[0], x
, "x"),
31 (SVSHAPE
.lims
[1], y
, "y"),
32 (SVSHAPE
.lims
[2], z
, "z")
34 # now select those by order. this allows us to
35 # create schedules for [z][x], [x][y], or [y][z]
36 # for matrix multiply.
37 vals
= [vals
[SVSHAPE
.order
[0]],
38 vals
[SVSHAPE
.order
[1]],
39 vals
[SVSHAPE
.order
[2]]
41 # some of the dimensions can be "skipped". the order
42 # was actually selected above on all 3 dimensions,
43 # e.g. [z][x][y] or [y][z][x]. "skip" allows one of
44 # those to be knocked out
45 if SVSHAPE
.skip
== 0b00:
47 elif SVSHAPE
.skip
== 0b11:
49 elif SVSHAPE
.skip
== 0b01:
51 elif SVSHAPE
.skip
== 0b10:
57 # ok now we can construct the result, using bits of
58 # "order" to say which ones get stacked on
60 lim
, idx
, dbg
= vals
[i
]
62 #print ("select %d %s" % (i, dbg))
63 idx
*= mult
# shifts up by previous dimension(s)
64 result
+= idx
# adds on this dimension
65 mult
*= lim
# for the next dimension
68 ((y_end
and x_end
)<<1) |
69 ((y_end
and x_end
and z_end
)<<2))
71 yield result
+ SVSHAPE
.offset
, loopends
74 # set the dimension sizes here
79 # set total (can repeat, e.g. VL=x*y*z*4)
80 VL
= xdim
* ydim
* zdim
86 SVSHAPE0
.lims
= [xdim
, ydim
, zdim
]
87 SVSHAPE0
.order
= [1,0,2] # experiment with different permutations, here
90 SVSHAPE0
.offset
= 0 # experiment with different offset, here
91 SVSHAPE0
.invxyz
= [0,0,0] # inversion if desired
93 # enumerate over the iterator function, getting new indices
94 for idx
, (new_idx
, end
) in enumerate(iterate_indices(SVSHAPE0
)):
97 print ("%d->%d" % (idx
, new_idx
), "end", bin(end
)[2:])
100 if __name__
== '__main__':