code: def grad_optimize_ei_pend(
      self, cand, comp, pend, vals, labels, compute_grad=True
  ):
      # Here we have to compute the gradients for constrained ei
      # This means deriving through the two kernels, the one for predicting
      # constraint violations and the one predicting ei
  
      # First pull out violating points
      compfull = comp.copy()
      comp = comp[labels > 0, :]
      vals = vals[labels > 0]
  
      # Use standard EI if there aren't enough observations of either
      # positive or negative constraint violations
      use_vanilla_ei = np.all(labels > 0) or np.all(labels <= 0)
  
      best = np.min(vals)
      cand = np.reshape(cand, (-1, comp.shape[1]))
      func_constraint_m = 1
  
      if not use_vanilla_ei:
          # First we make predictions for the durations
          # 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
          ff = np.dot(cand_constraint_cross.T, t_alpha)
  
          # Squash through Gaussian cdf
          func_constraint_m = sps.norm.cdf(self.constraint_gain * ff)
  
          # Apply covariance function
          cov_grad_func = getattr(gp, "grad_" + self.cov_func.__name__)
          cand_cross_grad = cov_grad_func(
              self.constraint_ls, compfull, cand
          )
          grad_cross_t = np.squeeze(cand_cross_grad)
  
      # Now compute the gradients w.r.t. ei
      # The primary covariances for prediction.
      comp_cov = self.cov(self.amp2, self.ls, comp)
      cand_cross = self.cov(self.amp2, self.ls, comp, cand)
      comp_cov_full = self.cov(self.amp2, self.ls, compfull)
      cand_cross_full = self.cov(self.amp2, self.ls, compfull, cand)
  
      # Create a composite vector of complete and pending.
      comp_pend = np.concatenate((comp, pend))
  
      # Compute the covariance and Cholesky decomposition.
      comp_pend_cov = self.cov(
          self.amp2, self.ls, comp_pend
      ) + self.noise * np.eye(comp_pend.shape[0])
      comp_pend_chol = spla.cholesky(comp_pend_cov, lower=True)
  
      # Compute submatrices.
      pend_cross = self.cov(self.amp2, self.ls, comp, pend)
      pend_kappa = self.cov(self.amp2, self.ls, pend)
  
      # Use the sub-Cholesky.
      obsv_chol = comp_pend_chol[: comp.shape[0], : comp.shape[0]]
  
      # Compute the required Cholesky.
      # obsv_cov  = comp_cov + self.noise*np.eye(comp.shape[0])
      # obsv_chol = spla.cholesky(obsv_cov, lower=True)
      obsv_cov_full = comp_cov_full + self.noise * np.eye(
          compfull.shape[0]
      )
      obsv_chol_full = spla.cholesky(obsv_cov_full, lower=True)
  
      # Predictive things.
      # Solve the linear systems.
      alpha = spla.cho_solve((obsv_chol, True), vals - self.mean)
      beta = spla.cho_solve((obsv_chol, True), pend_cross)
  
      # Finding predictive means and variances.
      pend_m = np.dot(pend_cross.T, alpha) + self.mean
      pend_K = pend_kappa - np.dot(pend_cross.T, beta)
  
      # Take the Cholesky of the predictive covariance.
      pend_chol = spla.cholesky(pend_K, lower=True)
  
      # Make predictions.
      npr.set_state(self.randomstate)
      pend_fant = (
          np.dot(
              pend_chol, npr.randn(pend.shape[0], self.pending_samples)
          )
          + pend_m[:, None]
      )
  
      # Include the fantasies.
      fant_vals = np.concatenate(
          (
              np.tile(vals[:, np.newaxis], (1, self.pending_samples)),
              pend_fant,
          )
      )
  
      # Compute bests over the fantasies.
      bests = np.min(fant_vals, axis=0)
  
      # Now generalize from these fantasies.
      cand_cross = self.cov(self.amp2, self.ls, comp_pend, cand)
      cov_grad_func = getattr(gp, "grad_" + self.cov_func.__name__)
      cand_cross_grad = cov_grad_func(self.ls, comp_pend, cand)
  
      # Solve the linear systems.
      alpha = spla.cho_solve(
          (comp_pend_chol, True), fant_vals - self.mean
      )
      beta = spla.solve_triangular(
          comp_pend_chol, cand_cross, 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)
  
      # beta  = spla.solve_triangular(obsv_chol_full, cand_cross_full,
      #                               lower=True)
      # beta   = spla.solve_triangular(obsv_chol, cand_cross,
      #                               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)
  
      constrained_ei = -np.sum(ei * func_constraint_m)
      if not compute_grad:
          return constrained_ei
  
      # Gradients of ei w.r.t. mean and variance
      g_ei_m = -ncdf
      g_ei_s2 = 0.5 * npdf / func_s
  
      # Apply covariance function
      grad_cross = np.squeeze(cand_cross_grad)
  
      grad_xp_m = np.dot(alpha.transpose(), grad_cross)
      grad_xp_v = np.dot(
          -2
          * spla.cho_solve(
              (comp_pend_chol, True), cand_cross
          ).transpose(),
          grad_cross,
      )
  
      grad_xp = (
          0.5
          * self.amp2
          * (
              grad_xp_m * np.tile(g_ei_m, (comp.shape[1], 1)).T
              + (grad_xp_v.T * g_ei_s2).T
          )
      )
  
      grad_xp = np.sum(grad_xp, axis=0)
  
      if use_vanilla_ei:
          return -np.sum(ei), grad_xp.flatten()
  
      grad_constraint_xp_m = np.dot(t_alpha.transpose(), grad_cross_t)
      grad_constraint_xp_m = (
          0.5
          * self.constraint_amp2
          * self.constraint_gain
          * grad_constraint_xp_m
          * sps.norm.pdf(self.constraint_gain * ff)
      )
  
      grad_xp = (
          func_constraint_m * grad_xp
          + np.sum(ei) * grad_constraint_xp_m
      )
  
      return constrained_ei, grad_xp.flatten()
  
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 11 for calling the GPConstrainedEIChooser obj's underlying member method code with example usage: obj.grad_optimize_ei_pend(cand, comp, pend, vals, labels, compute_grad) and returns: constrained_ei,  grad_xp, constrained_ei, unknown,  grad_xp