code: def evaluate_density(
          distribution,
          x_data,
          parameters=None,
          cache=None,
  ):
      
      assert len(x_data) == len(distribution)
      assert len(x_data.shape) == 2
  
      cache = cache if cache is not None else {}
      out = numpy.zeros(x_data.shape)
  
      # Distribution self know how to handle density evaluation.
      if hasattr(distribution, "_pdf"):
          parameters = load_parameters(
              distribution, "_pdf", parameters=parameters, cache=cache)
          out[:] = distribution._pdf(x_data, **parameters)
  
      # Approximate density evaluation based on cumulative distribution function.
      else:
          from .. import approximation
          parameters = load_parameters(
              distribution, "_cdf", parameters=parameters, cache=cache)
          out[:] = approximation.approximate_density(
              distribution, x_data, parameters=parameters, cache=cache)
  
      # dependency handling.
      if distribution in cache:
          out = numpy.where(x_data == cache[distribution], out, 0)
      else:
          cache[distribution] = x_data
  
      return out
docs: Evaluate probability density function (PDF).
  
      Args:
          distribution (Dist):
              Distribution to evaluate.
          x_data (numpy.ndarray):
              Locations for where evaluate density at.
          parameters (:py:data:typing.Any):
              Collection of parameters to override the default ones in the
              distribution.
          cache (:py:data:typing.Any):
              A collection of previous calculations in case the same distribution
              turns up on more than one occasion.
  
      Returns:
          The probability density values of ``distribution`` at location
          ``x_data`` using parameters ``parameters``.