Create tensor representing estimate of posterior.

  Args:
    posterior_dist: An instance of `tfp.distributions.Distribution`.
        The variational posterior from which to produce an estimate of the
        variable in question.
    posterior_estimate_mode: A `Tensor` of dtype `tf.string`, which
        determines the inference mode.
    raw_var_name: The name of the variable over which inference is done.

  Returns:
    `z_sample`, a `Tensor` representing an estimate derived from the
        posterior distribution.

def _produce_posterior_estimate(posterior_dist, posterior_estimate_mode,
                                raw_var_name):
  """Create tensor representing estimate of posterior.

  Args:
    posterior_dist: An instance of `tfp.distributions.Distribution`.
        The variational posterior from which to produce an estimate of the
        variable in question.
    posterior_estimate_mode: A `Tensor` of dtype `tf.string`, which
        determines the inference mode.
    raw_var_name: The name of the variable over which inference is done.

  Returns:
    `z_sample`, a `Tensor` representing an estimate derived from the
        posterior distribution.
  """
  conds = [
      tf.equal(posterior_estimate_mode,
               tf.constant(EstimatorModes.sample),
               name="equal_sample_mode"),
      tf.equal(posterior_estimate_mode,
               tf.constant(EstimatorModes.mean),
               name="equal_mean_mode"),
      tf.equal(posterior_estimate_mode,
               tf.constant(EstimatorModes.last_sample),
               name="equal_last_sample_mode"),
  ]
  # pylint: disable=unnecessary-lambda
  results = [
      lambda: posterior_dist.sample(),
      lambda: posterior_dist.mean(),
      lambda: posterior_dist.last_sample()
  ]

  def default_case_branch_raising_error():
    err_msg = "Invalid posterior estimate mode."
    raise_err = tf.Assert(tf.constant(False), data=[tf.constant(err_msg)])
    with tf.control_dependencies([raise_err]):
      return posterior_dist.mean()

  if hasattr(posterior_dist, "last_sample"):
    cases = {conds[0]: results[0], conds[1]: results[1], conds[2]: results[2]}
  else:
    cases = {conds[0]: results[0], conds[1]: results[1]}
  z_sample = tf.case(
      cases,
      exclusive=True,
      default=default_case_branch_raising_error,
      name="{}_posterior_estimate".format(raw_var_name))
  # pylint: enable=unnecessary-lambda
  return z_sample