code: def even_odd_swap_proposal_fn(swap_frequency, name=None):
      """Make a deterministic swap proposal function, alternating even/odd swaps.
  
      This proposal function swaps deterministically `swap_frequency` fraction of
      the time, alternating even and odd parity.
      This was shown in [2] to mix better than random schemes.
  
      Contrast this with `default_swap_proposal_fn`, which swaps randomly with
      probability `prob_swap`.
  
      ```
      swap_fn = even_odd_swap_proposal_fn(swap_frequency=1)
  
      even_odd_swap_proposal_fn(num_replica=4, step_count=0)
      ==> [1, 0, 3, 2]  # Swap 0 <--> 1 and 2 <--> 3, even parity.
  
      even_odd_swap_proposal_fn(num_replica=4, step_count=1)
      ==> [0, 2, 1, 3]  # Swap 1 <--> 2, odd parity.
      ```
  
      Args:
        swap_frequency: Scalar `Tensor` in `[0, 1]` giving the frequency of swaps.
          Swaps will occur, with alternating parity, every `N` steps, where
          `N = 1 / swap_frequency`.
        name: Python `str` name given to ops created by this function.
          Default value: `'even_odd_swaps'`.
  
      Returns:
        default_swap_proposal_fn_: Python callable which take a number of
          replicas (a Python integer), and integer `Tensor` `batch_shape`, a
          `step_count`, a `seed`, and returns `swaps`, a shape
          `[num_replica] + batch_shape` `Tensor`, where axis 0 indexes
          "one-time swaps", i.e., such that (if `rank(swaps) == 1`,
          `range(num_replicas) == tf.gather(swaps, swaps)`.
  
      #### References
  
      [1]: S. Syed, A. Bouchard-Cote G. Deligiannidis, A. Doucet
           Non-Reversible Parallel Tempering: a Scalable Highly Parallel MCMC Scheme
           https://arxiv.org/abs/1905.02939
      """
  
      def even_odd_swaps(
          num_replica, batch_shape=(), step_count=None, seed=None
      ):
          """Make deterministic even_odd one time swaps."""
          if step_count is None:
              raise ValueError(
                  "`step_count` must be supplied. Found `None`."
              )
          del seed  # Unused for this function.
          with tf.name_scope(name or "even_odd_swaps"):
              # Period is 1 / frequency, and we want period = Inf if frequency = 0.
              # safe_swap_period is the correct swap period in case swap_frequency > 0.
              # If swap_frequency == 0, safe_swap_period is set to 1 (to avoid integer
              # div by zero below). We will hard-set this case to "null swap."
              swap_freq = tf.convert_to_tensor(
                  swap_frequency, name="swap_frequency"
              )
              safe_swap_period = tf.cast(
                  tf.where(
                      swap_freq > 0,
                      tf.math.ceil(
                          tf.math.reciprocal_no_nan(swap_freq)
                      ),
                      1,
                  ),
                  # Although period = 1 / frequency may have roundoff error, and result
                  # in a period different than what the user intended, the
                  # user will end up with a single integer period, and thus well defined
                  # deterministic swaps.
                  tf.int32,
              )
  
              # u selects parity.  E.g.,
              #  u==False ==> [1, 0, 3, 2, 4] even parity swaps
              #  u==True ==>  [0, 2, 1, 4, 3] odd parity swaps
              # If there are 2 replicas, then the "True" swaps are null
              # swaps...which would contradict the user provided `swap_frequency`.
              # So special case num_replica==2, forcing u==False in this case.
              u_shape = ps.concat(
                  (
                      ps.ones(1, dtype=tf.int32),
                      ps.cast(batch_shape, tf.int32),
                  ),
                  axis=0,
              )
              u = tf.fill(
                  u_shape,
                  tf.cast(
                      (step_count // safe_swap_period) % 2, tf.bool
                  ),
              )
              u = tf.where(num_replica > 2, u, False)
  
              x = bu.left_justified_expand_dims_to(
                  tf.range(num_replica, dtype=tf.int64),
                  rank=ps.size(u_shape),
              )
              y = tf.where(
                  tf.equal(x % 2, tf.cast(u, dtype=tf.int64)),
                  x + 1,
                  x - 1,
              )
              y = tf.clip_by_value(y, 0, num_replica - 1)
              # TODO(b/142689785): Consider using tf.cond and returning an empty list
              # then in REMC consider using a tf.cond for short-circuiting.
              return tf.where(
                  (
                      tf.cast(step_count % safe_swap_period, tf.bool)
                      | tf.math.equal(swap_freq, 0)
                  ),
                  x,  # Don't swap
                  y,  # Swap
              )
  
      return even_odd_swaps
  
imports: import collections
  import warnings
  import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.internal import assert_util
  from tensorflow_probability.python.internal import broadcast_util
  from tensorflow_probability.python.internal import distribution_util
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import samplers
  from tensorflow_probability.python.internal import tensorshape_util
  from tensorflow_probability.python.internal import unnest
  from tensorflow_probability.python.mcmc import kernel
  from tensorflow_probability.python.mcmc.internal import util
label_desc: Use image node_id 2 for calling a global function with example usage: even_odd_swap_proposal_fn(swap_frequency, name) and returns: even_odd_swaps, tf