code: def histogram(a, bins=10, range=None, density=None, weights=None):
      r"""
      Compute the histogram of a dataset.
  
      Parameters
      ----------
      a : array_like
          Input data. The histogram is computed over the flattened array.
      bins : int or sequence of scalars or str, optional
          If `bins` is an int, it defines the number of equal-width
          bins in the given range (10, by default). If `bins` is a
          sequence, it defines a monotonically increasing array of bin edges,
          including the rightmost edge, allowing for non-uniform bin widths.
  
          .. versionadded:: 1.11.0
  
          If `bins` is a string, it defines the method used to calculate the
          optimal bin width, as defined by `histogram_bin_edges`.
  
      range : (float, float), optional
          The lower and upper range of the bins.  If not provided, range
          is simply ``(a.min(), a.max())``.  Values outside the range are
          ignored. The first element of the range must be less than or
          equal to the second. `range` affects the automatic bin
          computation as well. While bin width is computed to be optimal
          based on the actual data within `range`, the bin count will fill
          the entire range including portions containing no data.
      weights : array_like, optional
          An array of weights, of the same shape as `a`.  Each value in
          `a` only contributes its associated weight towards the bin count
          (instead of 1). If `density` is True, the weights are
          normalized, so that the integral of the density over the range
          remains 1.
          Please note that the ``dtype`` of `weights` will also become the
          ``dtype`` of the returned accumulator (`hist`), so it must be
          large enough to hold accumulated values as well.
      density : bool, optional
          If ``False``, the result will contain the number of samples in
          each bin. If ``True``, the result is the value of the
          probability *density* function at the bin, normalized such that
          the *integral* over the range is 1. Note that the sum of the
          histogram values will not be equal to 1 unless bins of unity
          width are chosen; it is not a probability *mass* function.
  
      Returns
      -------
      hist : array
          The values of the histogram. See `density` and `weights` for a
          description of the possible semantics.  If `weights` are given,
          ``hist.dtype`` will be taken from `weights`.
      bin_edges : array of dtype float
          Return the bin edges ``(length(hist)+1)``.
  
  
      See Also
      --------
      histogramdd, bincount, searchsorted, digitize, histogram_bin_edges
  
      Notes
      -----
      All but the last (righthand-most) bin is half-open.  In other words,
      if `bins` is::
  
        [1, 2, 3, 4]
  
      then the first bin is ``[1, 2)`` (including 1, but excluding 2) and
      the second ``[2, 3)``.  The last bin, however, is ``[3, 4]``, which
      *includes* 4.
  
  
      Examples
      --------
      >>> np.histogram([1, 2, 1], bins=[0, 1, 2, 3])
      (array([0, 2, 1]), array([0, 1, 2, 3]))
      >>> np.histogram(np.arange(4), bins=np.arange(5), density=True)
      (array([0.25, 0.25, 0.25, 0.25]), array([0, 1, 2, 3, 4]))
      >>> np.histogram([[1, 2, 1], [1, 0, 1]], bins=[0,1,2,3])
      (array([1, 4, 1]), array([0, 1, 2, 3]))
  
      >>> a = np.arange(5)
      >>> hist, bin_edges = np.histogram(a, density=True)
      >>> hist
      array([0.5, 0. , 0.5, 0. , 0. , 0.5, 0. , 0.5, 0. , 0.5])
      >>> hist.sum()
      2.4999999999999996
      >>> np.sum(hist * np.diff(bin_edges))
      1.0
  
      .. versionadded:: 1.11.0
  
      Automated Bin Selection Methods example, using 2 peak random data
      with 2000 points.
  
      .. plot::
          :include-source:
  
          import matplotlib.pyplot as plt
          import numpy as np
  
          rng = np.random.RandomState(10)  # deterministic random data
          a = np.hstack((rng.normal(size=1000),
                         rng.normal(loc=5, scale=2, size=1000)))
          plt.hist(a, bins='auto')  # arguments are passed to np.histogram
          plt.title("Histogram with 'auto' bins")
          plt.show()
  
      """
      a, weights = _ravel_and_check_weights(a, weights)
  
      bin_edges, uniform_bins = _get_bin_edges(a, bins, range, weights)
  
      # Histogram is an integer or a float array depending on the weights.
      if weights is None:
          ntype = np.dtype(np.intp)
      else:
          ntype = weights.dtype
  
      # We set a block size, as this allows us to iterate over chunks when
      # computing histograms, to minimize memory usage.
      BLOCK = 65536
  
      # The fast path uses bincount, but that only works for certain types
      # of weight
      simple_weights = (
          weights is None
          or np.can_cast(weights.dtype, np.double)
          or np.can_cast(weights.dtype, complex)
      )
  
      if uniform_bins is not None and simple_weights:
          # Fast algorithm for equal bins
          # We now convert values of a to bin indices, under the assumption of
          # equal bin widths (which is valid here).
          first_edge, last_edge, n_equal_bins = uniform_bins
  
          # Initialize empty histogram
          n = np.zeros(n_equal_bins, ntype)
  
          # Pre-compute histogram scaling factor
          norm_numerator = n_equal_bins
          norm_denom = _unsigned_subtract(last_edge, first_edge)
  
          # We iterate over blocks here for two reasons: the first is that for
          # large arrays, it is actually faster (for example for a 10^8 array it
          # is 2x as fast) and it results in a memory footprint 3x lower in the
          # limit of large arrays.
          for i in _range(0, len(a), BLOCK):
              tmp_a = a[i : i + BLOCK]
              if weights is None:
                  tmp_w = None
              else:
                  tmp_w = weights[i : i + BLOCK]
  
              # Only include values in the right range
              keep = tmp_a >= first_edge
              keep &= tmp_a <= last_edge
              if not np.logical_and.reduce(keep):
                  tmp_a = tmp_a[keep]
                  if tmp_w is not None:
                      tmp_w = tmp_w[keep]
  
              # This cast ensures no type promotions occur below, which gh-10322
              # make unpredictable. Getting it wrong leads to precision errors
              # like gh-8123.
              tmp_a = tmp_a.astype(bin_edges.dtype, copy=False)
  
              # Compute the bin indices, and for values that lie exactly on
              # last_edge we need to subtract one
              f_indices = (
                  _unsigned_subtract(tmp_a, first_edge) / norm_denom
              ) * norm_numerator
              indices = f_indices.astype(np.intp)
              indices[indices == n_equal_bins] -= 1
  
              # The index computation is not guaranteed to give exactly
              # consistent results within ~1 ULP of the bin edges.
              decrement = tmp_a < bin_edges[indices]
              indices[decrement] -= 1
              # The last bin includes the right edge. The other bins do not.
              increment = (tmp_a >= bin_edges[indices + 1]) & (
                  indices != n_equal_bins - 1
              )
              indices[increment] += 1
  
              # We now compute the histogram using bincount
              if ntype.kind == "c":
                  n.real += np.bincount(
                      indices,
                      weights=tmp_w.real,
                      minlength=n_equal_bins,
                  )
                  n.imag += np.bincount(
                      indices,
                      weights=tmp_w.imag,
                      minlength=n_equal_bins,
                  )
              else:
                  n += np.bincount(
                      indices, weights=tmp_w, minlength=n_equal_bins
                  ).astype(ntype)
      else:
          # Compute via cumulative histogram
          cum_n = np.zeros(bin_edges.shape, ntype)
          if weights is None:
              for i in _range(0, len(a), BLOCK):
                  sa = np.sort(a[i : i + BLOCK])
                  cum_n += _search_sorted_inclusive(sa, bin_edges)
          else:
              zero = np.zeros(1, dtype=ntype)
              for i in _range(0, len(a), BLOCK):
                  tmp_a = a[i : i + BLOCK]
                  tmp_w = weights[i : i + BLOCK]
                  sorting_index = np.argsort(tmp_a)
                  sa = tmp_a[sorting_index]
                  sw = tmp_w[sorting_index]
                  cw = np.concatenate((zero, sw.cumsum()))
                  bin_index = _search_sorted_inclusive(sa, bin_edges)
                  cum_n += cw[bin_index]
  
          n = np.diff(cum_n)
  
      if density:
          db = np.array(np.diff(bin_edges), float)
          return n / db / n.sum(), bin_edges
  
      return n, bin_edges
  
imports: import contextlib
  import functools
  import operator
  import warnings
  import numpy
  from numpy._core import overrides
label_desc: Use image node_id 18 for calling a global function with example usage: histogram(a, bins, range, density, weights) and returns: n,  bin_edges, unknown,  bin_edges