def canonical_free(base, gens, g, num_free):
 g = g.array_form
 size = len(g)
 if (not base):
  return g[:]
 transversals = get_transversals(base, gens)
 m = len(base)
 for x in sorted(g[:(-2)]):
  if (x not in base):
   base.append(x)
 h = g
 for (i, transv) in enumerate(transversals):
  b = base[i]
  h_i = ([size] * num_free)
  s = None
  for sk in transv.values():
   h1 = _af_rmul(h, sk)
   hi = [h1.index(ix) for ix in range(num_free)]
   if (hi < h_i):
    h_i = hi
    s = sk
  if s:
   h = _af_rmul(h, s)
 return h

def canonical_free ( base , gens , g , num_free ) : g = g . array_form size = len ( g ) if ( not base ) : return g [ : ] transversals = get_transversals ( base , gens ) m = len ( base ) for x in sorted ( g [ : ( - 2 ) ] ) : if ( x not in base ) : base . append ( x ) h = g for ( i , transv ) in enumerate ( transversals ) : b = base [ i ] h_i = ( [ size ] * num_free ) s = None for sk in transv . values ( ) : h1 = _af_rmul ( h , sk ) hi = [ h1 . index ( ix ) for ix in range ( num_free ) ] if ( hi < h_i ) : h_i = hi s = sk if s : h = _af_rmul ( h , s ) return h
canonicalization of a tensor with respect to free indices choosing the minimum with respect to lexicographical ordering in the free indices base .