docs: def row_norms(ii, f=Ellipsis, squared=False):
      '''
      row_norms(ii) yields a potential function h(x) that calculates the vector norms of the rows of
        the matrix formed by [x[i] for i in ii] (ii is a matrix of parameter indices).
      row_norms(ii, f) yield a potential function h(x) equivalent to compose(row_norms(ii), f).
      '''
      try:
          (n,m) = ii
          # matrix shape given
          ii = np.reshape(np.arange(n*m), (n,m))
      except Exception: ii = np.asarray(ii)
      f = to_potential(f)
      if is_const_potential(f):
          q = flattest(f.c)
          q = np.sum([q[i]**2 for i in ii.T], axis=0)
          return PotentialConstant(q if squared else np.sqrt(q))
      F = reduce(lambda a,b: a + b, [part(Ellipsis, col)**2 for col in ii.T])
      F = compose(F, f)
      if not squared: F = sqrt(F)
      return F