class_docstr: Expected Improvement (with or without function values in log space) acquisition function
  
  :math:`EI(X) := \mathbb{E}\left[ \max\{0, f(\mathbf{X^+}) - f_{t+1}(\mathbf{X}) - \xi \} \right]`,
  with :math:`f(X^+)` as the best location.
  
  Parameters
  ----------
  xi : float, defaults to 0.0
      Controls the balance between exploration and exploitation of the
      acquisition function.
  log : bool, defaults to False
      Whether the function values are in log-space.
  
  
  Attributes
  ----------
  _xi : float
      Exploration-exloitation trade-off parameter.
  _log: bool
      Function values in log-space or not.
  _eta : float
      Current incumbent function value (best value observed so far).
class_docstr_tok: ["Expected","Improvement","(","with","or","without","function","values","in","log","space",")","acquisition","function",":","math",":","`","EI","(","X",")",":","=","\\mathbb","{","E","}","\\left","[","\\max\\","{","0",",","f","(","\\mathbf","{","X^+","}",")","-","f_","{","t+1","}","(","\\mathbf","{","X","}",")","-","\\xi","\\","}","\\right","]","`",",","with",":","math",":","`","f","(","X^+",")","`","as","the","best","location",".","Parameters","--","--","--","--","--","xi",":","float",",","defaults","to","0.0","Controls","the","balance","between","exploration","and","exploitation","of","the","acquisition","function",".","log",":","bool",",","defaults","to","False","Whether","the","function","values","are","in","log-space",".","Attributes","--","--","--","--","--","_xi",":","float","Exploration-exloitation","trade-off","parameter",".","_log",":","bool","Function","values","in","log-space","or","not",".","_eta",":","float","Current","incumbent","function","value","(","best","value","observed","so","far",")","."]
docstr: Compute EI 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 `update` has not been called before (current incumbent value `eta` unspecified).
  ValueError
      If EI is < 0 for at least one sample (normal function value space).
  ValueError
      If EI is < 0 for at least one sample (log function value space).
docstr_tok: ["Compute","EI","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","`","update","`","has","not","been","called","before","(","current","incumbent","value","`","eta","`","unspecified",")",".","ValueError","If","EI","is","<","0","for","at","least","one","sample","(","normal","function","value","space",")",".","ValueError","If","EI","is","<","0","for","at","least","one","sample","(","log","function","value","space",")","."]
code: def _compute(self, X: np.ndarray) -> np.ndarray:
      """Compute EI 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 `update` has not been called before (current incumbent value `eta` unspecified).
      ValueError
          If EI is < 0 for at least one sample (normal function value space).
      ValueError
          If EI is < 0 for at least one sample (log function value space).
      """
      assert self._model is not None
      assert self._xi is not None
  
      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."
          )
  
      if not self._log:
          if len(X.shape) == 1:
              X = X[:, np.newaxis]
  
          m, v = self._model.predict_marginalized(X)
          s = np.sqrt(v)
  
          def calculate_f() -> np.ndarray:
              z = (self._eta - m - self._xi) / s
              return (self._eta - m - self._xi) * norm.cdf(
                  z
              ) + s * norm.pdf(z)
  
          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 is smaller than 0 for at least one "
                  "sample."
              )
  
          return f
      else:
          if len(X.shape) == 1:
              X = X[:, np.newaxis]
  
          m, var_ = self._model.predict_marginalized(X)
          std = np.sqrt(var_)
  
          def calculate_log_ei() -> np.ndarray:
              # we expect that f_min is in log-space
              assert self._eta is not None
              assert self._xi is not None
  
              f_min = self._eta - self._xi
              v = (f_min - m) / std
              return (np.exp(f_min) * norm.cdf(v)) - (
                  np.exp(0.5 * var_ + m) * norm.cdf(v - std)
              )
  
          if np.any(std == 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."
              )
              std_copy = np.copy(std)
              std[std_copy == 0.0] = 1.0
              log_ei = calculate_log_ei()
              log_ei[std_copy == 0.0] = 0.0
          else:
              log_ei = calculate_log_ei()
  
          if (log_ei < 0).any():
              raise ValueError(
                  "Expected Improvement is smaller than 0 for at least one sample."
              )
  
          return log_ei.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 5 for calling the EI obj's underlying member method code with example usage: obj._compute(X) and returns: f, log_ei, unknown, unknown