docs: def inner(a,b):
      '''
      inner(a,b) yields the dot product of a and b, doing so in a fashion that respects sparse
        matrices when encountered. This does not error check for bad dimensionality.
  
      If a or b are constants, then the result is just the a*b; if a and b are both vectors or both
      matrices, then the inner product is dot(a,b); if a is a vector and b is a matrix, this is
      equivalent to as if a were a matrix with 1 row; and if a is a matrix and b a vector, this is
      equivalent to as if b were a matrix with 1 column.
      '''
      if   sps.issparse(a): return a.dot(b)
      else: a = np.asarray(a)
      if len(a.shape) == 0: return a*b
      if sps.issparse(b):
          if len(a.shape) == 1: return b.T.dot(a)
          else:                 return b.T.dot(a.T).T
      else: b = np.asarray(b)
      if len(b.shape) == 0: return a*b
      if len(a.shape) == 1 and len(b.shape) == 2: return np.dot(b.T, a)
      else: return np.dot(a,b)