code: def suggest(
      new_ids,
      domain,
      trials,
      seed,
      prior_weight=_default_prior_weight,
      n_startup_jobs=_default_n_startup_jobs,
      n_EI_candidates=_default_n_EI_candidates,
      gamma=_default_gamma,
      verbose=True,
  ):
      """
      Given previous trials and the domain, suggest the best expected hp point
      according to the TPE-EI algo
  
  
      Args:
          prior_weight(
          n_startup_jobs:
          n_EI_candidates:
          gamma:
          verbose:
  
      Returns:
  
      """
  
      t0 = time.time()
      # use build_posterior_wrapper to create the pyll nodes
      observed, observed_loss, posterior = build_posterior_wrapper(
          domain, prior_weight, gamma
      )
      tt = time.time() - t0
      if verbose:
          logger.info("build_posterior_wrapper took %f seconds" % tt)
  
      # Loop over previous trials to collect best_docs and best_docs_loss
      best_docs = dict()
      best_docs_loss = dict()
      for doc in trials.trials:
          # get either these docs own tid or the one that it's from
          tid = doc["misc"].get("from_tid", doc["tid"])
  
          # associate infinite loss to new/running/failed jobs
          loss = doc["result"].get("loss")
          loss = float("inf") if loss is None else float(loss)
  
          # if set, update loss for this tid if it's higher than current loss
          # otherwise, set it
          best_docs_loss.setdefault(tid, loss)
          if loss <= best_docs_loss[tid]:
              best_docs_loss[tid] = loss
              best_docs[tid] = doc
  
      # -- sort docs by order of suggestion
      #    so that linear_forgetting removes the oldest ones
      tid_docs = sorted(best_docs.items())
      losses = [best_docs_loss[tid] for tid, doc in tid_docs]
      tids, docs = list(zip(*tid_docs)) if tid_docs else ([], [])
  
      if verbose:
          if docs:
              s = "%i/%i trials with best loss %f" % (
                  len(docs),
                  len(trials),
                  np.nanmin(losses),
              )
          else:
              s = "0 trials"
          logger.info("TPE using %s" % s)
  
      if len(docs) < n_startup_jobs:
          # N.B. THIS SEEDS THE RNG BASED ON THE new_id
          return rand.suggest(new_ids, domain, trials, seed)
  
      # Sample and compute log-probability.
      first_new_id = new_ids[0]
      if tids:
          # -- the +2 coordinates with an assertion above
          #    to ensure that fake ids are used during sampling
          #    TODO: not sure what assertion this refers to...
          fake_id_0 = max(max(tids), first_new_id) + 2
      else:
          # -- weird - we're running the TPE algo from scratch
          assert n_startup_jobs <= 0
          fake_id_0 = first_new_id + 2
  
      fake_ids = list(range(fake_id_0, fake_id_0 + n_EI_candidates))
  
      # -- this dictionary will map pyll nodes to the values
      #    they should take during the evaluation of the pyll program
      memo = {
          domain.s_new_ids: fake_ids,
          domain.s_rng: np.random.default_rng(seed),
      }
  
      memo[observed_loss["idxs"]] = tids
      memo[observed_loss["vals"]] = losses
  
      observed_idxs_dict, observed_vals_dict = miscs_to_idxs_vals(
          [doc["misc"] for doc in docs], keys=list(domain.params.keys())
      )
      memo[observed["idxs"]] = observed_idxs_dict
      memo[observed["vals"]] = observed_vals_dict
  
      # evaluate `n_EI_candidates` pyll nodes in `posterior` using `memo`
      # TODO: it seems to return idxs, vals, all the same. Is this correct?
      idxs, vals = pyll.rec_eval(
          posterior, memo=memo, print_node_on_error=False
      )
  
      # hack to add offset again for randint params
      for label, param in domain.params.items():
          if param.name == "randint" and len(param.pos_args) == 2:
              offset = param.pos_args[0].obj
              vals[label] = [val + offset for val in vals[label]]
  
      # -- retrieve the best of the samples and form the return tuple
  
      # specs are deprecated since build_posterior makes all the same
      rval_specs = [None]
      rval_results = [domain.new_result()]
      rval_miscs = [
          {
              "tid": first_new_id,
              "cmd": domain.cmd,
              "workdir": domain.workdir,
          }
      ]
  
      miscs_update_idxs_vals(
          rval_miscs,
          idxs,
          vals,
          idxs_map={fake_ids[0]: first_new_id},
          assert_all_vals_used=False,
      )
      # return the doc for the best new trial
      return trials.new_trial_docs(
          [first_new_id], rval_specs, rval_results, rval_miscs
      )
  
imports: import logging
  import time
  import numpy
  from scipy.special import erf
  from .None import pyll
  from .pyll import scope
  from .pyll.stochastic import implicit_stochastic
  from .base import miscs_to_idxs_vals
  from .base import miscs_update_idxs_vals
  from .None import rand
label_desc: Use image node_id 31 for calling a global function with example usage: suggest(new_ids, domain, trials, seed, prior_weight, n_startup_jobs, n_EI_candidates, gamma, verbose) and returns: trials, rand