class_docstr: Expected Improvement per Second acquisition function
  
  :math:`EI(X) := \frac{\mathbb{E}\left[\max\{0,f(\mathbf{X^+})-f_{t+1}(\mathbf{X})-\xi\right]\}]}{np.log(r(x))}`,
  with :math:`f(X^+)` as the best location and :math:`r(x)` as runtime.
  
  Parameters
  ----------
  xi : float, defaults to 0.0
      Controls the balance between exploration and exploitation of the acquisition function.
class_docstr_tok: ["Expected","Improvement","per","Second","acquisition","function",":","math",":","`","EI","(","X",")",":","=","\\frac","{","\\mathbb","{","E","}","\\left","[","\\max\\","{","0",",","f","(","\\mathbf","{","X^+","}",")","-f_","{","t+1","}","(","\\mathbf","{","X","}",")","-\\xi\\right","]","\\","}","]","}","{","np.log","(","r","(","x",")",")","}","`",",","with",":","math",":","`","f","(","X^+",")","`","as","the","best","location","and",":","math",":","`","r","(","x",")","`","as","runtime",".","Parameters","--","--","--","--","--","xi",":","float",",","defaults","to","0.0","Controls","the","balance","between","exploration","and","exploitation","of","the","acquisition","function","."]
docstr: Compute EI per second acquisition value
  
  Parameters
  ----------
  X : np.ndarray [N, D]
      The input points where the acquisition function should be evaluated. The dimensionality of X is (N, D),
      with N as the number of points to evaluate at and D is the number of dimensions of one X.
  
  Returns
  -------
  np.ndarray [N,1]
      Acquisition function values wrt X.
  
  Raises
  ------
  ValueError
      If the mean has the wrong shape, should have shape (-1, 2).
  ValueError
      If the variance has the wrong shape, should have shape (-1, 2).
  ValueError
      If `update` has not been called before (current incumbent value `eta` unspecified).
  ValueError
      If EIPS is < 0 for at least one sample.
docstr_tok: ["Compute","EI","per","second","acquisition","value","Parameters","--","--","--","--","--","X",":","np.ndarray","[","N",",","D","]","The","input","points","where","the","acquisition","function","should","be","evaluated",".","The","dimensionality","of","X","is","(","N",",","D",")",",","with","N","as","the","number","of","points","to","evaluate","at","and","D","is","the","number","of","dimensions","of","one","X",".","Returns","--","--","--","-","np.ndarray","[","N,1","]","Acquisition","function","values","wrt","X",".","Raises","--","--","--","ValueError","If","the","mean","has","the","wrong","shape",",","should","have","shape","(","-1",",","2",")",".","ValueError","If","the","variance","has","the","wrong","shape",",","should","have","shape","(","-1",",","2",")",".","ValueError","If","`","update","`","has","not","been","called","before","(","current","incumbent","value","`","eta","`","unspecified",")",".","ValueError","If","EIPS","is","<","0","for","at","least","one","sample","."]
code: def _compute(self, X: np.ndarray) -> np.ndarray:
      """Compute EI per second acquisition value
  
      Parameters
      ----------
      X : np.ndarray [N, D]
          The input points where the acquisition function should be evaluated. The dimensionality of X is (N, D),
          with N as the number of points to evaluate at and D is the number of dimensions of one X.
  
      Returns
      -------
      np.ndarray [N,1]
          Acquisition function values wrt X.
  
      Raises
      ------
      ValueError
          If the mean has the wrong shape, should have shape (-1, 2).
      ValueError
          If the variance has the wrong shape, should have shape (-1, 2).
      ValueError
          If `update` has not been called before (current incumbent value `eta` unspecified).
      ValueError
          If EIPS is < 0 for at least one sample.
      """
      assert self._model is not None
      if len(X.shape) == 1:
          X = X[:, np.newaxis]
  
      m, v = self._model.predict_marginalized(X)
      if m.shape[1] != 2:
          raise ValueError(f"m has wrong shape: {m.shape} != (-1, 2)")
      if v.shape[1] != 2:
          raise ValueError(f"v has wrong shape: {v.shape} != (-1, 2)")
  
      m_cost = m[:, 0]
      v_cost = v[:, 0]
  
      # The model already predicts log(runtime)
      m_runtime = m[:, 1]
      s = np.sqrt(v_cost)
  
      if self._eta is None:
          raise ValueError(
              "No current best specified. Call update("
              "eta=<int>) to inform the acquisition function "
              "about the current best value."
          )
  
      def calculate_f() -> np.ndarray:
          z = (self._eta - m_cost - self._xi) / s
          f = (self._eta - m_cost - self._xi) * norm.cdf(
              z
          ) + s * norm.pdf(z)
          f = f / m_runtime
  
          return f
  
      if np.any(s == 0.0):
          # if std is zero, we have observed x on all instances
          # using a RF, std should be never exactly 0.0
          # Avoid zero division by setting all zeros in s to one.
          # Consider the corresponding results in f to be zero.
          logger.warning(
              "Predicted std is 0.0 for at least one sample."
          )
          s_copy = np.copy(s)
          s[s_copy == 0.0] = 1.0
          f = calculate_f()
          f[s_copy == 0.0] = 0.0
      else:
          f = calculate_f()
  
      if (f < 0).any():
          raise ValueError(
              "Expected Improvement per Second is smaller than 0 "
              "for at least one sample."
          )
  
      return f.reshape((-1, 1))
  
file_path: SMAC3/smac/acquisition/function/expected_improvement.py
imports: from __future__ import annotations
  from typing import Any
  import numpy
  from scipy.stats import norm
  from smac.acquisition.function.abstract_acquisition_function import AbstractAcquisitionFunction
  from smac.utils.logging import get_logger
label_desc: Use image node_id 3 for calling the EIPS obj's underlying member method code with example usage: obj._compute(X) and returns: f, f