code: def histogram(
      x,
      edges,
      axis=None,
      weights=None,
      extend_lower_interval=False,
      extend_upper_interval=False,
      dtype=None,
      name=None,
  ):
      """Count how often `x` falls in intervals defined by `edges`.
  
      Given `edges = [c0, ..., cK]`, defining intervals
      `I0 = [c0, c1)`, `I1 = [c1, c2)`, ..., `I_{K-1} = [c_{K-1}, cK]`,
      This function counts how often `x` falls into each interval.
  
      Values of `x` outside of the intervals cause errors.  Consider using
      `extend_lower_interval`, `extend_upper_interval` to deal with this.
  
      Args:
        x:  Numeric `N-D` `Tensor` with `N > 0`.  If `axis` is not
          `None`, must have statically known number of dimensions. The
          `axis` kwarg determines which dimensions index iid samples.
          Other dimensions of `x` index "events" for which we will compute different
          histograms.
        edges:  `Tensor` of same `dtype` as `x`.  The first dimension indexes edges
          of intervals.  Must either be `1-D` or have `edges.shape[1:]` the same
          as the dimensions of `x` excluding `axis`.
          If `rank(edges) > 1`, `edges[k]` designates a shape `edges.shape[1:]`
          `Tensor` of interval edges for the corresponding dimensions of `x`.
        axis:  Optional `0-D` or `1-D` integer `Tensor` with constant
          values. The axis in `x` that index iid samples.
          `Default value:` `None` (treat every dimension as sample dimension).
        weights:  Optional `Tensor` of same `dtype` and `shape` as `x`.
          For each value in `x`, the bin will be incremented by
          the corresponding weight instead of 1.
        extend_lower_interval:  Python `bool`.  If `True`, extend the lowest
          interval `I0` to `(-inf, c1]`.
        extend_upper_interval:  Python `bool`.  If `True`, extend the upper
          interval `I_{K-1}` to `[c_{K-1}, +inf)`.
        dtype: The output type (`int32` or `int64`). `Default value:` `x.dtype`.
        name:  A Python string name to prepend to created ops.
          `Default value:` 'histogram'
  
      Returns:
        counts: `Tensor` of type `dtype` and, with
          `~axis = [i for i in range(arr.ndim) if i not in axis]`,
          `counts.shape = [edges.shape[0]] + x.shape[~axis]`.
          With `I` a multi-index into `~axis`, `counts[k][I]` is the number of times
          event(s) fell into the `kth` interval of `edges` or with `weights`
          non-None the sum of the weight(s) corresponding to the event(s) in a bin.
  
      Raises:
        ValueError: if the shape of `x` and `weights` are not the same.
  
      #### Examples
  
      ```python
      # x.shape = [1000, 2]
      # x[:, 0] ~ Uniform(0, 1), x[:, 1] ~ Uniform(1, 2).
      x = tf.stack([tf.random.uniform([1000]), 1 + tf.random.uniform([1000])],
                   axis=-1)
  
      # edges ==> bins [0, 0.5), [0.5, 1.0), [1.0, 1.5), [1.5, 2.0].
      edges = [0., 0.5, 1.0, 1.5, 2.0]
  
      tfp.stats.histogram(x, edges)
      ==> approximately [500, 500, 500, 500]
  
      tfp.stats.histogram(x, edges, axis=0)
      ==> approximately [[500, 500, 0, 0], [0, 0, 500, 500]]
      ```
  
      """
      with tf.name_scope(name or "histogram"):
          # Tensor conversions.
          in_dtype = dtype_util.common_dtype(
              [x, edges, weights], dtype_hint=tf.float32
          )
  
          x = tf.convert_to_tensor(x, name="x", dtype=in_dtype)
          edges = tf.convert_to_tensor(
              edges, name="edges", dtype=in_dtype
          )
          if weights is not None:
              weights = tf.convert_to_tensor(
                  weights, name="weights", dtype=in_dtype
              )
  
          # Move dims in axis to the left end as one flattened dim.
          # After this, x.shape = [n_samples] + E.
          if axis is None:
              x = tf.reshape(x, shape=[-1])
              if weights is not None:
                  weights = tf.reshape(weights, shape=[-1])
          else:
              x_ndims = _get_static_ndims(
                  x, expect_static=True, expect_ndims_at_least=1
              )
              axis = _make_static_axis_non_negative_list(axis, x_ndims)
              if not axis:
                  raise ValueError(
                      "`axis` cannot be empty.  Found: {}".format(axis)
                  )
              x = _move_dims_to_flat_end(
                  x, axis, x_ndims, right_end=False
              )
  
              if weights is not None:
                  weights_ndims = _get_static_ndims(
                      weights,
                      expect_static=True,
                      expect_ndims_at_least=1,
                  )
                  if x_ndims != weights_ndims:
                      raise ValueError(
                          "Number of dimensions of `x` and `weights` must "
                          "coincide. Found: x has {}, weights has {}".format(
                              x_ndims, weights_ndims
                          )
                      )
                  weights = _move_dims_to_flat_end(
                      weights, axis, weights_ndims, right_end=False
                  )
  
          # bins.shape = x.shape = [n_samples] + E,
          # and bins[i] is a shape E Tensor of the bins that sample `i` fell into.
          # E is the "event shape", which is [] if axis is None.
          bins = find_bins(
              x,
              edges=edges,
              # If not extending intervals, then values outside the edges will return
              # -1, which gives an error when fed to bincount.
              extend_lower_interval=extend_lower_interval,
              extend_upper_interval=extend_upper_interval,
              dtype=tf.int32,
          )
  
          # TODO(b/124015136) Use standard tf.math.bincount once it supports `axis`.
          counts = count_integers(
              bins,
              weights=weights,
              # Ensure we get correct output, even if x did not fall into every bin
              minlength=tf.shape(edges)[0] - 1,
              maxlength=tf.shape(edges)[0] - 1,
              axis=0,
              dtype=dtype or in_dtype,
          )
          n_edges = tf.compat.dimension_value(edges.shape[0])
          if n_edges is not None:
              tensorshape_util.set_shape(
                  counts,
                  tf.TensorShape([n_edges - 1]).concatenate(
                      counts.shape[1:]
                  ),
              )
          return counts
  
file_path: probability/tensorflow_probability/python/stats/quantiles.py
imports: import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.internal import assert_util
  from tensorflow_probability.python.internal import distribution_util
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import tensorshape_util
label_desc: Use image node_id 3 for calling a global function with example usage: histogram(x, edges, axis, weights, extend_lower_interval, extend_upper_interval, dtype, name) and returns: counts