code: def _reduction(
      self,
      method_name,
      axis=None,
      dtype=None,
      keepdims=None,
      todense=False,
      **kw,
  ):
      # TODO: support keepdims
      if isinstance(axis, tuple):
          if sorted(axis) != [0, 1]:
              assert len(axis) == 1
              axis = axis[0]
          else:
              axis = None
  
      if todense:
          x = self.spmatrix.toarray()
          x = getattr(get_array_module(x), method_name)(
              x, axis=axis, **kw
          )
      else:
          x = getattr(self.spmatrix, method_name)(axis=axis, **kw)
      if not isinstance(axis, Iterable):
          axis = (axis,)
      axis = list(range(len(self.shape))) if axis is None else axis
      shape = tuple(
          s if i not in axis else 1
          for i, s in enumerate(self.shape)
          if keepdims or i not in axis
      )
      m = get_array_module(x)
      if issparse(x):
          return SparseNDArray(x, shape=shape)
      if m.isscalar(x):
          if keepdims:
              return m.array([x])[0].reshape((1,) * self.ndim)
          else:
              return m.array([x])[0]
      else:
          return m.asarray(x).reshape(shape)
  
imports: import numpy
  from collections.abc import Iterable
  from typing import List
  from .core import issparse, get_array_module, cp, cps, get_sparse_module, naked, sps, splinalg
  from .array import SparseNDArray, SparseArray
label_desc: Use image node_id 8 for calling the SparseMatrix obj's underlying member method code with example usage: obj._reduction(method_name, axis, dtype, keepdims, todense) and returns: SparseNDArray, m, m, m