def metropolis_hastings_step(current_state: State,<EOL>proposed_state: State,<EOL>energy_change: FloatTensor,<EOL>seed=None) -> Tuple[State, tf.Tensor, tf.Tensor]:
flat_current = tf.nest.flatten(current_state)<EOL>flat_proposed = nest.flatten_up_to(current_state, proposed_state)<EOL>flat_current = [<EOL>p if c is None else c for p, c in zip(flat_proposed, flat_current)<EOL>]<EOL>current_state = tf.nest.pack_sequence_as(current_state, flat_current)<EOL>current_state = tf.nest.map_structure(tf.convert_to_tensor, current_state)<EOL>proposed_state = tf.nest.map_structure(tf.convert_to_tensor, proposed_state)<EOL>energy_change = tf.convert_to_tensor(value=energy_change)<EOL>log_accept_ratio = -energy_change<EOL>log_uniform = tf.math.log(<EOL>tf.random.uniform(<EOL>shape=tf.shape(input=log_accept_ratio),<EOL>dtype=log_accept_ratio.dtype.base_dtype,<EOL>seed=seed))<EOL>is_accepted = log_uniform < log_accept_ratio<EOL>next_state = mcmc_util.choose(<EOL>is_accepted, proposed_state, current_state, name='<STR_LIT>')<EOL>return next_state, is_accepted, log_uniform<EOL>
Metropolis-Hastings step.

    This probabilistically chooses between `current_state` and `proposed_state`
    based on the `energy_change` so as to preserve detailed balance.

    Energy change is the negative of `log_accept_ratio`.

    Args:
      current_state: Current state.
      proposed_state: Proposed state.
      energy_change: E(proposed_state) - E(previous_state).
      seed: For reproducibility.

    Returns:
      new_state: The chosen state.
      is_accepted: Whether the proposed state was accepted.
      log_uniform: The random number that was used to select between the two
        states.