code: def pairwise_distances_chunked(
      X,
      Y=None,
      *,
      reduce_func=None,
      metric="euclidean",
      n_jobs=None,
      working_memory=None,
      **kwds,
  ):
      """Generate a distance matrix chunk by chunk with optional reduction.
  
      In cases where not all of a pairwise distance matrix needs to be
      stored at once, this is used to calculate pairwise distances in
      ``working_memory``-sized chunks.  If ``reduce_func`` is given, it is
      run on each chunk and its return values are concatenated into lists,
      arrays or sparse matrices.
  
      Parameters
      ----------
      X : ndarray of shape (n_samples_X, n_samples_X) or \
              (n_samples_X, n_features)
          Array of pairwise distances between samples, or a feature array.
          The shape the array should be (n_samples_X, n_samples_X) if
          metric='precomputed' and (n_samples_X, n_features) otherwise.
  
      Y : ndarray of shape (n_samples_Y, n_features), default=None
          An optional second feature array. Only allowed if
          metric != "precomputed".
  
      reduce_func : callable, default=None
          The function which is applied on each chunk of the distance matrix,
          reducing it to needed values.  ``reduce_func(D_chunk, start)``
          is called repeatedly, where ``D_chunk`` is a contiguous vertical
          slice of the pairwise distance matrix, starting at row ``start``.
          It should return one of: None; an array, a list, or a sparse matrix
          of length ``D_chunk.shape[0]``; or a tuple of such objects.
          Returning None is useful for in-place operations, rather than
          reductions.
  
          If None, pairwise_distances_chunked returns a generator of vertical
          chunks of the distance matrix.
  
      metric : str or callable, default='euclidean'
          The metric to use when calculating distance between instances in a
          feature array. If metric is a string, it must be one of the options
          allowed by scipy.spatial.distance.pdist for its metric parameter,
          or a metric listed in pairwise.PAIRWISE_DISTANCE_FUNCTIONS.
          If metric is "precomputed", X is assumed to be a distance matrix.
          Alternatively, if metric is a callable function, it is called on
          each pair of instances (rows) and the resulting value recorded.
          The callable should take two arrays from X as input and return a
          value indicating the distance between them.
  
      n_jobs : int, default=None
          The number of jobs to use for the computation. This works by
          breaking down the pairwise matrix into n_jobs even slices and
          computing them in parallel.
  
          ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
          ``-1`` means using all processors. See :term:`Glossary <n_jobs>`
          for more details.
  
      working_memory : int, default=None
          The sought maximum memory for temporary distance matrix chunks.
          When None (default), the value of
          ``sklearn.get_config()['working_memory']`` is used.
  
      **kwds : optional keyword parameters
          Any further parameters are passed directly to the distance function.
          If using a scipy.spatial.distance metric, the parameters are still
          metric dependent. See the scipy docs for usage examples.
  
      Yields
      ------
      D_chunk : {ndarray, sparse matrix}
          A contiguous slice of distance matrix, optionally processed by
          ``reduce_func``.
  
      Examples
      --------
      Without reduce_func:
  
      >>> import numpy as np
      >>> from sklearn.metrics import pairwise_distances_chunked
      >>> X = np.random.RandomState(0).rand(5, 3)
      >>> D_chunk = next(pairwise_distances_chunked(X))
      >>> D_chunk
      array([[0.  ..., 0.29..., 0.41..., 0.19..., 0.57...],
             [0.29..., 0.  ..., 0.57..., 0.41..., 0.76...],
             [0.41..., 0.57..., 0.  ..., 0.44..., 0.90...],
             [0.19..., 0.41..., 0.44..., 0.  ..., 0.51...],
             [0.57..., 0.76..., 0.90..., 0.51..., 0.  ...]])
  
      Retrieve all neighbors and average distance within radius r:
  
      >>> r = .2
      >>> def reduce_func(D_chunk, start):
      ...     neigh = [np.flatnonzero(d < r) for d in D_chunk]
      ...     avg_dist = (D_chunk * (D_chunk < r)).mean(axis=1)
      ...     return neigh, avg_dist
      >>> gen = pairwise_distances_chunked(X, reduce_func=reduce_func)
      >>> neigh, avg_dist = next(gen)
      >>> neigh
      [array([0, 3]), array([1]), array([2]), array([0, 3]), array([4])]
      >>> avg_dist
      array([0.039..., 0.        , 0.        , 0.039..., 0.        ])
  
      Where r is defined per sample, we need to make use of ``start``:
  
      >>> r = [.2, .4, .4, .3, .1]
      >>> def reduce_func(D_chunk, start):
      ...     neigh = [np.flatnonzero(d < r[i])
      ...              for i, d in enumerate(D_chunk, start)]
      ...     return neigh
      >>> neigh = next(pairwise_distances_chunked(X, reduce_func=reduce_func))
      >>> neigh
      [array([0, 3]), array([0, 1]), array([2]), array([0, 3]), array([4])]
  
      Force row-by-row generation by reducing ``working_memory``:
  
      >>> gen = pairwise_distances_chunked(X, reduce_func=reduce_func,
      ...                                  working_memory=0)
      >>> next(gen)
      [array([0, 3])]
      >>> next(gen)
      [array([0, 1])]
      """
      n_samples_X = _num_samples(X)
      if metric == "precomputed":
          slices = (slice(0, n_samples_X),)
      else:
          if Y is None:
              Y = X
          # We get as many rows as possible within our working_memory budget to
          # store len(Y) distances in each row of output.
          #
          # Note:
          #  - this will get at least 1 row, even if 1 row of distances will
          #    exceed working_memory.
          #  - this does not account for any temporary memory usage while
          #    calculating distances (e.g. difference of vectors in manhattan
          #    distance.
          chunk_n_rows = get_chunk_n_rows(
              row_bytes=8 * _num_samples(Y),
              max_n_rows=n_samples_X,
              working_memory=working_memory,
          )
          slices = gen_batches(n_samples_X, chunk_n_rows)
  
      # precompute data-derived metric params
      params = _precompute_metric_params(X, Y, metric=metric, **kwds)
      kwds.update(**params)
  
      for sl in slices:
          if sl.start == 0 and sl.stop == n_samples_X:
              X_chunk = X  # enable optimised paths for X is Y
          else:
              X_chunk = X[sl]
          D_chunk = pairwise_distances(
              X_chunk, Y, metric=metric, n_jobs=n_jobs, **kwds
          )
          if (X is Y or Y is None) and PAIRWISE_DISTANCE_FUNCTIONS.get(
              metric, None
          ) is euclidean_distances:
              # zeroing diagonal, taking care of aliases of "euclidean",
              # i.e. "l2"
              D_chunk.flat[sl.start :: _num_samples(X) + 1] = 0
          if reduce_func is not None:
              chunk_size = D_chunk.shape[0]
              D_chunk = reduce_func(D_chunk, sl.start)
              _check_chunk_size(D_chunk, chunk_size)
          yield D_chunk
  
imports: import itertools
  import warnings
  from functools import partial
  import numpy
  from joblib import effective_n_jobs
  from scipy.sparse import csr_matrix, issparse
  from scipy.spatial import distance
  from ..None import config_context
  from ..exceptions import DataConversionWarning
  from ..preprocessing import normalize
  from ..utils import check_array, gen_batches, gen_even_slices, get_chunk_n_rows, is_scalar_nan
  from ..utils._mask import _get_mask
  from ..utils._param_validation import Hidden, Integral, Interval, MissingValues, Options, Real, StrOptions, validate_params
  from ..utils.extmath import row_norms, safe_sparse_dot
  from ..utils.fixes import parse_version, sp_base_version
  from ..utils.parallel import Parallel, delayed
  from ..utils.validation import _num_samples, check_non_negative
  from ._pairwise_distances_reduction import ArgKmin
  from ._pairwise_fast import _chi2_kernel_fast, _sparse_manhattan
label_desc: Use image node_id 33 for calling a global function with example usage: pairwise_distances_chunked(X, Y) without return types