lims = [xdim, ydim, zdim]
idxs = [0,0,0] # starting indices
+applydim = [1, 1] # apply lower dims
order = [1,0,2] # experiment with different permutations, here
offset = 0 # experiment with different offsetet, here
invxyz = [0,1,0] # inversion allowed
ix[i] = idxs[i]
if invxyz[i]:
ix[i] = lims[i] - 1 - ix[i]
- new_idx = ix[0] + ix[1] * xdim + ix[2] * xdim * ydim
+ new_idx = ix[2]
+ if applydim[1]:
+ new_idx = new_idx * ydim + ix[1]
+ if applydim[0]:
+ new_idx = new_idx * xdim + ix[0]
print ("%d->%d" % (idx, new_idx)),
break_count += 1
if break_count == lims[order[0]]:
from remapyield import iterate_indices
+from functools import reduce
+import operator
+
+
+def iterate_triple(SVSHAPE0, SVSHAPE1, SVSHAPE2):
+ # zip three iterators together, yields a synchronised
+ # tuple of three indices at a time
+ yield from zip(iterate_indices(SVSHAPE0),
+ iterate_indices(SVSHAPE1),
+ iterate_indices(SVSHAPE2))
+
def matrix_demo():
+ #### test matrices 1
+ # 3x2 matrix
X = [[1, 2, 3],
[3, 4, 5],
]
+ # 2x3 matrix
Y = [[6, 7],
[8, 9],
[10, 11],
]
+
+ #### test matrices 2
# 3x3 matrix
X = [[12,7,3],
[4 ,5,6],
Y = [[5,8,1,2],
[6,7,3,0],
[4,5,9,1]]
+
+ # get the dimensions of the 2 matrices
xdim1 = len(X[0])
ydim1 = len(X)
xdim2 = len(Y[0])
ydim2 = len(Y)
+
+ # print out X and Y
+ print ("X:")
+ for r in X:
+ print ("\t", r)
+ print ("Y:")
+ for r in Y:
+ print ("\t", r)
+
+ # first, calculate the result matrix manually.
# set up result matrix of correct size
result = []
for _ in range(ydim1):
result.append([0]*xdim2)
- # iterate through rows of X
- for i in range(len(X)):
- # iterate through columns of Y
- for j in range(len(Y[0])):
- # iterate through rows of Y
- for k in range(len(Y)):
+ # iterate through rows of Y
+ for k in range(len(Y)): # ydim2
+ # iterate through rows of X
+ for i in range(len(X)): # ydim1
+ # iterate through columns of Y
+ for j in range(len(Y[0])): # xdim2
+ print ("order res %d X %d Y %d" % \
+ ((i*xdim2)+j, # result linear array index
+ (i*xdim1)+k, # X linear array index
+ (k*xdim2)+j)) # Y linear array index
result[i][j] += X[i][k] * Y[k][j]
+ print ("expected result")
for r in result:
- print (r)
+ print ("\t", r)
+
+ # now. flatten the X and Y matrices into linear 1D Arrays.
+ # linear rows are sequentially-packed first (inner loop),
+ # columns next (outer loop):
+ # 0 1 2 3
+ # 4 5 6 7
+ # 8 9 10 11
+ # =>
+ # 0 1 2 3 4 .... 10 11
+ xf = reduce(operator.add, X)
+ yf = reduce(operator.add, Y)
+ print ("flattened X,Y")
+ print ("\t", xf)
+ print ("\t", yf)
+ # and create a linear result2, same scheme
+ result2 = [0] * (ydim1*xdim2)
+
+ ########
+ # now create the schedule. we use three generators, zipped
+ # together
+
+ class SVSHAPE:
+ pass
+ # result uses SVSHAPE0
+ SVSHAPE0 = SVSHAPE()
+ SVSHAPE0.lims = [ydim2, xdim2, 1]
+ SVSHAPE0.order = [0,2,1] # result iterates through i and j (modulo)
+ SVSHAPE0.mode = 0b00
+ SVSHAPE0.offset = 0 # no offset
+ SVSHAPE0.invxyz = [0,0,0] # no inversion
+ # X uses SVSHAPE1
+ SVSHAPE1 = SVSHAPE()
+ SVSHAPE1.lims = [ydim2, xdim2, ydim1]
+ SVSHAPE1.order = [1,2,0] # X iterates through i and k
+ SVSHAPE1.mode = 0b10
+ SVSHAPE1.offset = 0 # no offset
+ SVSHAPE1.invxyz = [0,0,0] # no inversion
+ # y-selector uses SHAPE2
+ SVSHAPE2 = SVSHAPE()
+ SVSHAPE2.lims = [ydim2, xdim2, ydim1]
+ SVSHAPE2.order = [1,2,0] # Y iterates through k and j
+ SVSHAPE2.mode = 0b01
+ SVSHAPE2.offset = 0 # no offset
+ SVSHAPE2.invxyz = [0,0,0] # no inversion
+
+ # perform the iteration over the *linear* arrays using the
+ # schedules
+ VL = ydim2 * xdim2 * ydim1
+ i = 0
+ for i, idxs in enumerate(iterate_triple(SVSHAPE0, SVSHAPE1, SVSHAPE2)):
+ if i == VL:
+ break
+ print ("idxs", idxs, len(result2), len(xf), len(yf))
+ r_idx, x_idx, y_idx = idxs
+ result2[r_idx] += xf[x_idx] * yf[y_idx]
+
+ # now print out sections of result array, assuming elements of a "row"
+ # are in sequence (inner loop), columns are outer
+ for i in range(0, len(result2), xdim2):
+ print ("\t", result2[i:i+xdim2])
if __name__ == '__main__':
matrix_demo()
skip += 1
continue
# construct the (up to) 3D remap schedule
- yield (x + y * xd + z * xd * yd)
+ if SVSHAPE.mode == 0b00:
+ result = z
+ result += y * zd
+ result += x * zd * yd
+ elif SVSHAPE.mode == 0b01:
+ result = z
+ result += x * zd
+ #result = z
+ #result = result * xd + x
+ #result = result * yd + y
+ elif SVSHAPE.mode == 0b10:
+ result = x
+ result += y * xd
+ #result += z * xd * yd
+
+ yield result
def demo():
# set the dimension sizes here
pass
SVSHAPE0 = SVSHAPE()
SVSHAPE0.lims = [xdim, ydim, zdim]
- SVSHAPE0.idxs = [0,0,0] # starting indices
SVSHAPE0.order = [1,0,2] # experiment with different permutations, here
+ SVSHAPE0.mode = 0b00
SVSHAPE0.offset = 0 # experiment with different offset, here
- SVSHAPE0.invxyz = [0,1,0] # inversion if desired
+ SVSHAPE0.invxyz = [0,0,0] # inversion if desired
# enumerate over the iterator function, getting new indices
for idx, new_idx in enumerate(iterate_indices(SVSHAPE0)):