code: def compute_ei(self, comp, pend, cand, vals, labels):
      # First we make predictions for the durations as that
      # doesn't depend on pending experiments
      # First pull out violating points
      compfull = comp.copy()
      comp = comp[labels > 0, :]
      vals = vals[labels > 0]
  
      # Compute covariances
      comp_constraint_cov = self.cov(
          self.constraint_amp2, self.constraint_ls, compfull
      )
      cand_constraint_cross = self.cov(
          self.constraint_amp2, self.constraint_ls, compfull, cand
      )
  
      # Cholesky decompositions
      obsv_constraint_cov = (
          comp_constraint_cov
          + self.constraint_noise * np.eye(compfull.shape[0])
      )
      obsv_constraint_chol = spla.cholesky(
          obsv_constraint_cov, lower=True
      )
  
      # Linear systems
      t_alpha = spla.cho_solve((obsv_constraint_chol, True), self.ff)
  
      # Predict marginal mean times and (possibly) variances
      func_constraint_m = np.dot(cand_constraint_cross.T, t_alpha)
  
      # Squash through a probit to get prob of not violating a constraint
      func_constraint_m = 1.0 / (
          1 + np.exp(-self.constraint_gain * func_constraint_m)
      )
  
      if pend.shape[0] == 0:
          # If there are no pending, don't do anything fancy.
  
          # Current best.
          best = np.min(vals)
  
          # The primary covariances for prediction.
          comp_cov = self.cov(self.amp2, self.ls, comp)
          comp_cov_full = self.cov(self.amp2, self.ls, compfull)
          cand_cross = self.cov(self.amp2, self.ls, comp, cand)
          cand_cross_full = self.cov(self.amp2, self.ls, compfull, cand)
  
          # Compute the required Cholesky.
          obsv_cov = comp_cov + self.noise * np.eye(comp.shape[0])
          obsv_cov_full = comp_cov_full + self.noise * np.eye(
              compfull.shape[0]
          )
          obsv_chol = spla.cholesky(obsv_cov, lower=True)
          obsv_chol_full = spla.cholesky(obsv_cov_full, lower=True)
  
          # Solve the linear systems.
          alpha = spla.cho_solve((obsv_chol, True), vals - self.mean)
          beta = spla.solve_triangular(
              obsv_chol, cand_cross, lower=True
          )
          # beta   = spla.solve_triangular(obsv_chol_full, cand_cross_full,
          # lower=True)
  
          # Predict the marginal means and variances at candidates.
          func_m = np.dot(cand_cross.T, alpha) + self.mean
          func_v = self.amp2 * (1 + 1e-6) - np.sum(beta**2, axis=0)
  
          # Expected improvement
          func_s = np.sqrt(func_v)
          u = (best - func_m) / func_s
          ncdf = sps.norm.cdf(u)
          npdf = sps.norm.pdf(u)
          ei = func_s * (u * ncdf + npdf)
  
          return ei
      else:
          return 0
  
imports: import os
  from ..None import gp
  import sys
  from ..None import util
  import tempfile
  import numpy
  import math
  import numpy.random
  import scipy.linalg
  import scipy.stats
  import scipy.optimize
  import pickle
  import matplotlib.pyplot
  import multiprocessing
  import copy
  from ..helpers import *
  from ..Locker import *
  import logging
label_desc: Use image node_id 14 for calling the GPConstrainedEIChooser obj's underlying member method code with example usage: obj.compute_ei(comp, pend, cand, vals, labels) and returns: ei, int