code: def _random_poisson_low_rate(
      sample_shape, rate, internal_dtype=tf.float64, seed=None
  ):
      """Samples from the Poisson distribution using Knuth's algorithm.
  
      We use an algorithm attributed to Knuth: Seminumerical Algorithms. Art of
      Computer Programming, Volume 2. This algorithm runs in O(rate) time, and
      requires O(rate) uniform variates. This algorithm is performant for rate ~<10.
  
      Given a Poisson process, the time between events is exponentially distributed.
      If we have a Poisson process with rate lambda, then, the time between events
      is distributed as Exp(lambda). If X ~ Uniform(0, 1), then Y ~ Exp(lambda)
      where Y = -log(X) / lambda. Thus, to simulate a Poisson draw, we can sample
      X_i ~ Exp(lambda), and we will haver N ~ Poisson(lambda), where N is the
      smallest number such that sum_i^N X_i > 1.
  
      Args:
        sample_shape: The output sample shape. Must broadcast with `rate`.
        rate: Floating point tensor, rate.
        internal_dtype: (optional) dtype to use for internal computations.
        seed: PRNG seed; see `tfp.random.sanitize_seed` for details.
  
      Returns:
        Samples from the poisson distribution.
      """
      exp_neg_rate = tf.math.exp(-rate)
  
      def loop_body(should_continue, samples, prod, num_iters, seed):
          u_seed, next_seed = samplers.split_seed(seed)
          prod = prod * samplers.uniform(
              sample_shape, dtype=internal_dtype, seed=u_seed
          )
          accept = should_continue & (prod <= exp_neg_rate)
          samples = tf.where(accept, num_iters, samples)
          return [
              should_continue & (~accept),
              samples,
              prod,
              num_iters + 1,
              next_seed,
          ]
  
      _, samples, _, _, _ = tf.while_loop(
          cond=lambda should_continue, *ignore: tf.reduce_any(
              should_continue
          ),
          body=loop_body,
          loop_vars=[
              tf.ones(sample_shape, dtype=tf.bool),  # should_continue
              tf.zeros(sample_shape, dtype=tf.int32),  # samples
              tf.ones(sample_shape, dtype=internal_dtype),  # prod
              tf.zeros([], dtype=tf.int32),  # num_iters
              seed,  # seed
          ],
          # Using a Chernoff-like bound, we can show that for lambda < 10,
          # Pr[X >= lambda + n] <= exp(-n^2 / 2(lambda + n)) < exp(-90). Hence,
          # there is miniscule probability that, even after a union bound over
          # batch size, a poisson sample with rate < 10 would attain a value > 200.
          maximum_iterations=200,
      )
      return samples
  
imports: import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.bijectors import softplus
  from tensorflow_probability.python.distributions import distribution
  from tensorflow_probability.python.internal import assert_util
  from tensorflow_probability.python.internal import batched_rejection_sampler
  from tensorflow_probability.python.internal import distribution_util
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import implementation_selection
  from tensorflow_probability.python.internal import parameter_properties
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import reparameterization
  from tensorflow_probability.python.internal import samplers
  from tensorflow_probability.python.internal import tensor_util
label_desc: Use image node_id 5 for calling a global function with example usage: _random_poisson_low_rate(sample_shape, rate, internal_dtype, seed) and returns: samples, list