code: def histogramdd(
      sample, bins=10, range=None, density=None, weights=None
  ):
      """
      Compute the multidimensional histogram of some data.
  
      Parameters
      ----------
      sample : (N, D) array, or (N, D) array_like
          The data to be histogrammed.
  
          Note the unusual interpretation of sample when an array_like:
  
          * When an array, each row is a coordinate in a D-dimensional space -
            such as ``histogramdd(np.array([p1, p2, p3]))``.
          * When an array_like, each element is the list of values for single
            coordinate - such as ``histogramdd((X, Y, Z))``.
  
          The first form should be preferred.
  
      bins : sequence or int, optional
          The bin specification:
  
          * A sequence of arrays describing the monotonically increasing bin
            edges along each dimension.
          * The number of bins for each dimension (nx, ny, ... =bins)
          * The number of bins for all dimensions (nx=ny=...=bins).
  
      range : sequence, optional
          A sequence of length D, each an optional (lower, upper) tuple giving
          the outer bin edges to be used if the edges are not given explicitly in
          `bins`.
          An entry of None in the sequence results in the minimum and maximum
          values being used for the corresponding dimension.
          The default, None, is equivalent to passing a tuple of D None values.
      density : bool, optional
          If False, the default, returns the number of samples in each bin.
          If True, returns the probability *density* function at the bin,
          ``bin_count / sample_count / bin_volume``.
      weights : (N,) array_like, optional
          An array of values `w_i` weighing each sample `(x_i, y_i, z_i, ...)`.
          Weights are normalized to 1 if density is True. If density is False,
          the values of the returned histogram are equal to the sum of the
          weights belonging to the samples falling into each bin.
  
      Returns
      -------
      H : ndarray
          The multidimensional histogram of sample x. See density and weights
          for the different possible semantics.
      edges : list
          A list of D arrays describing the bin edges for each dimension.
  
      See Also
      --------
      histogram: 1-D histogram
      histogram2d: 2-D histogram
  
      Examples
      --------
      >>> r = np.random.randn(100,3)
      >>> H, edges = np.histogramdd(r, bins = (5, 8, 4))
      >>> H.shape, edges[0].size, edges[1].size, edges[2].size
      ((5, 8, 4), 6, 9, 5)
  
      """
  
      try:
          # Sample is an ND-array.
          N, D = sample.shape
      except (AttributeError, ValueError):
          # Sample is a sequence of 1D arrays.
          sample = np.atleast_2d(sample).T
          N, D = sample.shape
  
      nbin = np.empty(D, np.intp)
      edges = D * [None]
      dedges = D * [None]
      if weights is not None:
          weights = np.asarray(weights)
  
      try:
          M = len(bins)
          if M != D:
              raise ValueError(
                  "The dimension of bins must be equal to the dimension of the "
                  "sample x."
              )
      except TypeError:
          # bins is an integer
          bins = D * [bins]
  
      # normalize the range argument
      if range is None:
          range = (None,) * D
      elif len(range) != D:
          raise ValueError(
              "range argument must have one entry per dimension"
          )
  
      # Create edge arrays
      for i in _range(D):
          if np.ndim(bins[i]) == 0:
              if bins[i] < 1:
                  raise ValueError(
                      "`bins[{}]` must be positive, when an integer".format(
                          i
                      )
                  )
              smin, smax = _get_outer_edges(sample[:, i], range[i])
              try:
                  n = operator.index(bins[i])
  
              except TypeError as e:
                  raise TypeError(
                      "`bins[{}]` must be an integer, when a scalar".format(
                          i
                      )
                  ) from e
  
              edges[i] = np.linspace(smin, smax, n + 1)
          elif np.ndim(bins[i]) == 1:
              edges[i] = np.asarray(bins[i])
              if np.any(edges[i][:-1] > edges[i][1:]):
                  raise ValueError(
                      "`bins[{}]` must be monotonically increasing, when an array".format(
                          i
                      )
                  )
          else:
              raise ValueError(
                  "`bins[{}]` must be a scalar or 1d array".format(i)
              )
  
          nbin[i] = len(edges[i]) + 1  # includes an outlier on each end
          dedges[i] = np.diff(edges[i])
  
      # Compute the bin number each sample falls into.
      Ncount = tuple(
          # avoid np.digitize to work around gh-11022
          np.searchsorted(edges[i], sample[:, i], side="right")
          for i in _range(D)
      )
  
      # Using digitize, values that fall on an edge are put in the right bin.
      # For the rightmost bin, we want values equal to the right edge to be
      # counted in the last bin, and not as an outlier.
      for i in _range(D):
          # Find which points are on the rightmost edge.
          on_edge = sample[:, i] == edges[i][-1]
          # Shift these points one bin to the left.
          Ncount[i][on_edge] -= 1
  
      # Compute the sample indices in the flattened histogram matrix.
      # This raises an error if the array is too large.
      xy = np.ravel_multi_index(Ncount, nbin)
  
      # Compute the number of repetitions in xy and assign it to the
      # flattened histmat.
      hist = np.bincount(xy, weights, minlength=nbin.prod())
  
      # Shape into a proper matrix
      hist = hist.reshape(nbin)
  
      # This preserves the (bad) behavior observed in gh-7845, for now.
      hist = hist.astype(float, casting="safe")
  
      # Remove outliers (indices 0 and -1 for each dimension).
      core = D * (slice(1, -1),)
      hist = hist[core]
  
      if density:
          # calculate the probability density function
          s = hist.sum()
          for i in _range(D):
              shape = np.ones(D, int)
              shape[i] = nbin[i] - 2
              hist = hist / dedges[i].reshape(shape)
          hist /= s
  
      if (hist.shape != nbin - 2).any():
          raise RuntimeError("Internal Shape Error")
      return hist, edges
  
imports: import contextlib
  import functools
  import operator
  import warnings
  import numpy
  from numpy.core import overrides
label_desc: Use image node_id 20 for calling a global function with example usage: histogramdd(sample, bins, range, density, weights) and returns: hist,  edges