code: def __affinity_bandwidth(
      rec: scipy.sparse.csr_matrix,
      bw_mode: Optional[Union[np.ndarray, _FloatLike_co, str]],
      k: int,
  ) -> Union[float, np.ndarray]:
      # rec should be a csr_matrix
  
      # the api allows users to specify a scalar bandwidth directly, besides the string based options.
      if isinstance(bw_mode, np.ndarray):
          bandwidth = bw_mode
          # check if bw is the right size
          if bandwidth.shape != rec.shape:
              raise ParameterError(
                  f"Invalid matrix bandwidth shape: {bandwidth.shape}."
                  f"Should be {rec.shape}."
              )
          if (bandwidth <= 0).any():
              raise ParameterError(
                  "Invalid bandwidth. All entries must be strictly positive."
              )
          return np.array(bandwidth[rec.nonzero()])
  
      elif isinstance(bw_mode, (int, float)):
          scalar_bandwidth = float(bw_mode)
          if scalar_bandwidth <= 0:
              raise ParameterError(
                  f"Invalid scalar bandwidth={scalar_bandwidth}. Must be strictly positive."
              )
          return scalar_bandwidth
  
      if bw_mode is None:
          bw_mode = "med_k_scalar"
  
      if bw_mode not in [
          "med_k_scalar",
          "mean_k",
          "gmean_k",
          "mean_k_avg",
          "gmean_k_avg",
          "mean_k_avg_and_pair",
      ]:
          raise ParameterError(
              f"Invalid bandwidth='{bw_mode}'. Must be either a positive scalar or one of "
              "['med_k_scalar', 'mean_k', 'gmean_k', 'mean_k_avg', 'gmean_k_avg', 'mean_k_avg_and_pair']"
          )
  
      # build a list of list that stores the distances to k nearest neighbors for all t points.
      t = rec.shape[0]
      knn_dists = []
      for i in range(t):
          # Get the links from point i
          links = rec[i].nonzero()[1]
          # catch empty dists lists in knn_dists
          if len(links) == 0:
              # Disconnected vertices are only a problem for point-wise bandwidth estimation
              if bw_mode not in ["med_k_scalar"]:
                  raise ParameterError(
                      f"The sample at time point {i} has no neighbors"
                  )
              else:
                  # If we have no links, then there's no distance
                  # shove a nan in here
                  knn_dists.append(np.array([np.nan]))
          else:
              # Compute k nearest neighbors' distance and sort ascending
              knn_dist_row = np.sort(rec[i, links].toarray()[0])[:k]
              knn_dists.append(knn_dist_row)
  
      # take the last element of each list for the distance to kth neighbor
      dist_to_k = np.asarray([dists[-1] for dists in knn_dists])
      avg_dist_to_first_ks = np.asarray(
          [np.mean(dists) for dists in knn_dists]
      )
  
      if bw_mode == "med_k_scalar":
          if not np.any(np.isfinite(dist_to_k)):
              raise ParameterError(
                  "Cannot estimate bandwidth from an empty graph"
              )
          return float(np.nanmedian(dist_to_k))
  
      if bw_mode in ["mean_k", "gmean_k"]:
          # building bandwidth components (sigma) using sparse matrix structures and indices
          sigma_i_data = np.empty_like(rec.data)
          sigma_j_data = np.empty_like(rec.data)
          for row in range(t):
              sigma_i_data[
                  rec.indptr[row] : rec.indptr[row + 1]
              ] = dist_to_k[row]
              col_idx = rec.indices[
                  rec.indptr[row] : rec.indptr[row + 1]
              ]
              sigma_j_data[
                  rec.indptr[row] : rec.indptr[row + 1]
              ] = dist_to_k[col_idx]
  
          if bw_mode == "mean_k":
              out = np.array((sigma_i_data + sigma_j_data) / 2)
          elif bw_mode == "gmean_k":
              out = np.array((sigma_i_data * sigma_j_data) ** 0.5)
  
      if bw_mode in [
          "mean_k_avg",
          "gmean_k_avg",
          "mean_k_avg_and_pair",
      ]:
          # building bandwidth components (sigma) using sparse matrix structures and indices
          sigma_i_data = np.empty_like(rec.data)
          sigma_j_data = np.empty_like(rec.data)
          for row in range(t):
              sigma_i_data[
                  rec.indptr[row] : rec.indptr[row + 1]
              ] = avg_dist_to_first_ks[row]
              col_idx = rec.indices[
                  rec.indptr[row] : rec.indptr[row + 1]
              ]
              sigma_j_data[
                  rec.indptr[row] : rec.indptr[row + 1]
              ] = avg_dist_to_first_ks[col_idx]
  
          if bw_mode == "mean_k_avg":
              out = np.array((sigma_i_data + sigma_j_data) / 2)
          elif bw_mode == "gmean_k_avg":
              out = np.array((sigma_i_data * sigma_j_data) ** 0.5)
          elif bw_mode == "mean_k_avg_and_pair":
              out = np.array(
                  (sigma_i_data + sigma_j_data + rec.data) / 3
              )
  
      return out
  
imports: from decorator import decorator
  import numpy
  import scipy
  import scipy.signal
  import scipy.ndimage
  import sklearn
  import sklearn.cluster
  import sklearn.feature_extraction
  import sklearn.neighbors
  from ._cache import cache
  from .None import util
  from .filters import diagonal_filter
  from .util.exceptions import ParameterError
  from typing import Any, Callable, Optional, TypeVar, Union, overload
  from typing_extensions import Literal
  from ._typing import _WindowSpec, _FloatLike_co
label_desc: Use image node_id 13 for calling a global function with example usage: __affinity_bandwidth(rec, bw_mode, k) and returns: out, np, float, scalar_bandwidth