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
22 for y
in y_r
: # loop over 2nd order dimension
23 for x
in x_r
: # loop over 3rd order dimension
24 # ok work out which order to construct things in.
25 # start by creating a list of tuples of the dimension
27 vals
= [(SVSHAPE
.lims
[0], x
, "x"),
28 (SVSHAPE
.lims
[1], y
, "y"),
29 (SVSHAPE
.lims
[2], z
, "z")
31 # now select those by order. this allows us to
32 # create schedules for [z][x], [x][y], or [y][z]
33 # for matrix multiply.
34 vals
= [vals
[SVSHAPE
.order
[0]],
35 vals
[SVSHAPE
.order
[1]],
36 vals
[SVSHAPE
.order
[2]]
38 # some of the dimensions can be "skipped". the order
39 # was actually selected above on all 3 dimensions,
40 # e.g. [z][x][y] or [y][z][x]. "skip" allows one of
41 # those to be knocked out
42 if SVSHAPE
.skip
== 0b00:
44 elif SVSHAPE
.skip
== 0b11:
46 elif SVSHAPE
.skip
== 0b01:
48 elif SVSHAPE
.skip
== 0b10:
54 # ok now we can construct the result, using bits of
55 # "order" to say which ones get stacked on
57 lim
, idx
, dbg
= vals
[i
]
59 #print ("select %d %s" % (i, dbg))
60 idx
*= mult
# shifts up by previous dimension(s)
61 result
+= idx
# adds on this dimension
62 mult
*= lim
# for the next dimension
64 yield result
+ SVSHAPE
.offset
67 # set the dimension sizes here
72 # set total (can repeat, e.g. VL=x*y*z*4)
73 VL
= xdim
* ydim
* zdim
79 SVSHAPE0
.lims
= [xdim
, ydim
, zdim
]
80 SVSHAPE0
.order
= [1,0,2] # experiment with different permutations, here
82 SVSHAPE0
.offset
= 0 # experiment with different offset, here
83 SVSHAPE0
.invxyz
= [0,0,0] # inversion if desired
85 # enumerate over the iterator function, getting new indices
86 for idx
, new_idx
in enumerate(iterate_indices(SVSHAPE0
)):
89 print ("%d->%d" % (idx
, new_idx
))
92 if __name__
== '__main__':