Advertisement
EelcoHoogendoorn

named tensor axes

Aug 15th, 2014
365
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.46 KB | None | 0 0
  1. import numpy as np
  2.  
  3. def prepare_order(current, target):
  4.     """
  5.    precalc the reordering of axes
  6.    this need only be done once
  7.    note; we need to allow for ... operator still.
  8.    left of ... in target have plus or minus sign respectively
  9.    """
  10.     def calc(t):
  11.         r = tuple(i for i,v in enumerate(current) if v==t) #all locactions of t in current
  12.         if len(r)==0:
  13.             return None
  14.         if len(r)==1:       #most common case; unpack for readability and performance
  15.             return r[0]
  16.         return r
  17.     return map(calc, target)
  18.  
  19. def reform(arr, current, target):
  20.     """
  21.    use as_strided to map current axes layout to target axes layout
  22.    prepare an order object
  23.    then apply it
  24.    """
  25.     order = prepare_order(current, target)
  26.  
  27.     def calc(o):
  28.         if o is None: return (1,0)                                  #broadcasting axis
  29.         if isinstance(o, int): return arr.shape[o],arr.strides[o]   #transposed axes
  30.         return arr.shape[o[0]],sum(arr.strides[i] for i in o)       #diag axis
  31.     layout = map(calc, order)
  32.  
  33.     shape, strides = zip(*layout)
  34.     return np.lib.index_tricks.as_strided(arr, shape, strides)
  35.  
  36. Q = np.arange((3*3*3)).reshape(3,3,3)
  37.  
  38. #reorder axes
  39. print reform(Q, ['a','b','c'], ['b','c','a'])
  40. #view higher order diagonal
  41. print reform(Q, ['a','a','a'], ['a'])
  42. #broadcast left and right
  43. Q = np.arange(3)
  44. print reform(Q, ['a'], ['a','b'])
  45. print reform(Q, ['a'], ['b','a'])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement