parameters: (a, b, dense_output=False)
return_statement: return ret
docstring: Dot product that handle the sparse matrix case correctly
  
      Parameters
      ----------
      a : array or sparse matrix
      b : array or sparse matrix
      dense_output : boolean, (default=False)
          When False, ``a`` and ``b`` both being sparse will yield sparse output.
          When True, output will always be a dense array.
  
      Returns
      -------
      dot_product : array or sparse matrix
          sparse if ``a`` and ``b`` are sparse and ``dense_output=False``.
docstring_summary: Dot product that handle the sparse matrix case correctly
docstring_tokens: Dot product that handle the sparse matrix case correctly
function: def safe_sparse_dot(a, b, dense_output=False):
      """Dot product that handle the sparse matrix case correctly
  
      Parameters
      ----------
      a : array or sparse matrix
      b : array or sparse matrix
      dense_output : boolean, (default=False)
          When False, ``a`` and ``b`` both being sparse will yield sparse output.
          When True, output will always be a dense array.
  
      Returns
      -------
      dot_product : array or sparse matrix
          sparse if ``a`` and ``b`` are sparse and ``dense_output=False``.
      """
      if a.ndim > 2 or b.ndim > 2:
          if sparse.issparse(a):
              # sparse is always 2D. Implies b is 3D+
              # [i, j] @ [k, ..., l, m, n] -> [i, k, ..., l, n]
              b_ = np.rollaxis(b, -2)
              b_2d = b_.reshape((b.shape[-2], -1))
              ret = a @ b_2d
              ret = ret.reshape(a.shape[0], *b_.shape[1:])
          elif sparse.issparse(b):
              # sparse is always 2D. Implies a is 3D+
              # [k, ..., l, m] @ [i, j] -> [k, ..., l, j]
              a_2d = a.reshape(-1, a.shape[-1])
              ret = a_2d @ b
              ret = ret.reshape(*a.shape[:-1], b.shape[1])
          else:
              ret = np.dot(a, b)
      else:
          ret = a @ b
  
      if (sparse.issparse(a) and sparse.issparse(b)
              and dense_output and hasattr(ret, "toarray")):
          return ret.toarray()
      return ret
function_tokens: def safe_sparse_dot ( a , b , dense_output = False ) : if a . ndim > 2 or b . ndim > 2 : if sparse . issparse ( a ) : # sparse is always 2D. Implies b is 3D+ # [i, j] @ [k, ..., l, m, n] -> [i, k, ..., l, n] b_ = np . rollaxis ( b , - 2 ) b_2d = b_ . reshape ( ( b . shape [ - 2 ] , - 1 ) ) ret = a @ b_2d ret = ret . reshape ( a . shape [ 0 ] , * b_ . shape [ 1 : ] ) elif sparse . issparse ( b ) : # sparse is always 2D. Implies a is 3D+ # [k, ..., l, m] @ [i, j] -> [k, ..., l, j] a_2d = a . reshape ( - 1 , a . shape [ - 1 ] ) ret = a_2d @ b ret = ret . reshape ( * a . shape [ : - 1 ] , b . shape [ 1 ] ) else : ret = np . dot ( a , b ) else : ret = a @ b if ( sparse . issparse ( a ) and sparse . issparse ( b ) and dense_output and hasattr ( ret , "toarray" ) ) : return ret . toarray ( ) return ret