code: def posterior_eig(
      model,
      design,
      observation_labels,
      target_labels,
      num_samples,
      num_steps,
      guide,
      optim,
      return_history=False,
      final_design=None,
      final_num_samples=None,
      eig=True,
      prior_entropy_kwargs={},
      *args,
      **kwargs,
  ):
      """
      Posterior estimate of expected information gain (EIG) computed from the average posterior entropy (APE)
      using :math:`EIG(d) = H[p(\\theta)] - APE(d)`. See [1] for full details.
  
      The posterior representation of APE is
  
          :math:`\\sup_{q}\\ E_{p(y, \\theta | d)}[\\log q(\\theta | y, d)]`
  
      where :math:`q` is any distribution on :math:`\\theta`.
  
      This method optimises the loss over a given `guide` family representing :math:`q`.
  
      [1] Foster, Adam, et al. "Variational Bayesian Optimal Experimental Design." arXiv preprint arXiv:1903.05480 (2019).
  
      :param function model: A pyro model accepting `design` as only argument.
      :param torch.Tensor design: Tensor representation of design
      :param list observation_labels: A subset of the sample sites
          present in `model`. These sites are regarded as future observations
          and other sites are regarded as latent variables over which a
          posterior is to be inferred.
      :param list target_labels: A subset of the sample sites over which the posterior
          entropy is to be measured.
      :param int num_samples: Number of samples per iteration.
      :param int num_steps: Number of optimization steps.
      :param function guide: guide family for use in the (implicit) posterior estimation.
          The parameters of `guide` are optimised to maximise the posterior
          objective.
      :param pyro.optim.Optim optim: Optimiser to use.
      :param bool return_history: If `True`, also returns a tensor giving the loss function
          at each step of the optimization.
      :param torch.Tensor final_design: The final design tensor to evaluate at. If `None`, uses
          `design`.
      :param int final_num_samples: The number of samples to use at the final evaluation, If `None,
          uses `num_samples`.
      :param bool eig: Whether to compute the EIG or the average posterior entropy (APE). The EIG is given by
          `EIG = prior entropy - APE`. If `True`, the prior entropy will be estimated analytically,
          or by Monte Carlo as appropriate for the `model`. If `False` the APE is returned.
      :param dict prior_entropy_kwargs: parameters for estimating the prior entropy: `num_prior_samples` indicating the
          number of samples for a MC estimate of prior entropy, and `mean_field` indicating if an analytic form for
          a mean-field prior should be tried.
      :return: EIG estimate, optionally includes full optimization history
      :rtype: torch.Tensor or tuple
      """
      if isinstance(observation_labels, str):
          observation_labels = [observation_labels]
      if isinstance(target_labels, str):
          target_labels = [target_labels]
  
      ape = _posterior_ape(
          model,
          design,
          observation_labels,
          target_labels,
          num_samples,
          num_steps,
          guide,
          optim,
          return_history=return_history,
          final_design=final_design,
          final_num_samples=final_num_samples,
          *args,
          **kwargs,
      )
      return _eig_from_ape(
          model, design, target_labels, ape, eig, prior_entropy_kwargs
      )
  
imports: import math
  import warnings
  import torch
  import pyro
  from pyro import poutine
  from pyro.contrib.oed.search import Search
  from pyro.contrib.util import lexpand
  from pyro.infer import SVI, EmpiricalMarginal, Importance
  from pyro.infer.autoguide.utils import mean_field_entropy
  from pyro.util import torch_isinf, torch_isnan
label_desc: Use image node_id 8 for calling a global function with example usage: posterior_eig(model, design, observation_labels, target_labels, num_samples, num_steps, guide, optim, return_history, final_design, final_num_samples, eig, prior_entropy_kwargs) and returns: _eig_from_ape