code: def laplace_eig(
      model,
      design,
      observation_labels,
      target_labels,
      guide,
      loss,
      optim,
      num_steps,
      final_num_samples,
      y_dist=None,
      eig=True,
      **prior_entropy_kwargs,
  ):
      """
      Estimates the expected information gain (EIG) by making repeated Laplace approximations to the posterior.
  
      :param function model: Pyro stochastic function taking `design` as only argument.
      :param torch.Tensor design: Tensor of possible designs.
      :param list observation_labels: labels of sample sites to be regarded as observables.
      :param list target_labels: labels of sample sites to be regarded as latent variables of interest, i.e. the sites
          that we wish to gain information about.
      :param function guide: Pyro stochastic function corresponding to `model`.
      :param loss: a Pyro loss such as `pyro.infer.Trace_ELBO().differentiable_loss`.
      :param optim: optimizer for the loss
      :param int num_steps: Number of gradient steps to take per sampled pseudo-observation.
      :param int final_num_samples: Number of `y` samples (pseudo-observations) to take.
      :param y_dist: Distribution to sample `y` from- if `None` we use the Bayesian marginal distribution.
      :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
      """
  
      if isinstance(observation_labels, str):
          observation_labels = [observation_labels]
      if target_labels is not None and isinstance(target_labels, str):
          target_labels = [target_labels]
  
      ape = _laplace_vi_ape(
          model,
          design,
          observation_labels,
          target_labels,
          guide,
          loss,
          optim,
          num_steps,
          final_num_samples,
          y_dist=y_dist,
      )
      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 1 for calling a global function with example usage: laplace_eig(model, design, observation_labels, target_labels, guide, loss, optim, num_steps, final_num_samples, y_dist, eig) and returns: _eig_from_ape