class_docstr: General class for acquisition optimizers defined in domains with mix of discrete, continuous, bandit variables
  
  :param space: design space class from GPyOpt.
  :param optimizer: optimizer to use. Can be selected among:
      - 'lbfgs': L-BFGS.
      - 'DIRECT': Dividing Rectangles.
      - 'CMA': covariance matrix adaptation.
docstr: Optimizes the input function.
  
  :param f: function to optimize.
  :param df: gradient of the function to optimize.
  :param f_df: returns both the function to optimize and its gradient.
code: def optimize(
      self, f=None, df=None, f_df=None, duplicate_manager=None
  ):
      """
      Optimizes the input function.
  
      :param f: function to optimize.
      :param df: gradient of the function to optimize.
      :param f_df: returns both the function to optimize and its gradient.
  
      """
      self.f = f
      self.df = df
      self.f_df = f_df
  
      ## --- Update the optimizer, in case context has beee passed.
      self.optimizer = choose_optimizer(
          self.optimizer_name, self.context_manager.noncontext_bounds
      )
  
      ## --- Selecting the anchor points and removing duplicates
      if (
          self.type_anchor_points_logic
          == max_objective_anchor_points_logic
      ):
          anchor_points_generator = ObjectiveAnchorPointsGenerator(
              self.space, random_design_type, f
          )
      elif (
          self.type_anchor_points_logic
          == thompson_sampling_anchor_points_logic
      ):
          anchor_points_generator = (
              ThompsonSamplingAnchorPointsGenerator(
                  self.space, sobol_design_type, self.model
              )
          )
  
      ## -- Select the anchor points (with context)
      anchor_points = anchor_points_generator.get(
          duplicate_manager=duplicate_manager,
          context_manager=self.context_manager,
      )
  
      ## --- Applying local optimizers at the anchor points and update bounds of the optimizer (according to the context)
      optimized_points = [
          apply_optimizer(
              self.optimizer,
              a,
              f=f,
              df=None,
              f_df=f_df,
              duplicate_manager=duplicate_manager,
              context_manager=self.context_manager,
              space=self.space,
          )
          for a in anchor_points
      ]
      x_min, fx_min = min(optimized_points, key=lambda t: t[1])
  
      # x_min, fx_min = min([apply_optimizer(self.optimizer, a, f=f, df=None, f_df=f_df, duplicate_manager=duplicate_manager, context_manager=self.context_manager, space = self.space) for a in anchor_points], key=lambda t:t[1])
  
      return x_min, fx_min
  
file_path: GPyOpt/GPyOpt/optimization/acquisition_optimizer.py
imports: from .optimizer import OptLbfgs, OptDirect, OptCma, apply_optimizer, choose_optimizer
  from .anchor_points_generator import ObjectiveAnchorPointsGenerator, ThompsonSamplingAnchorPointsGenerator
  from ..core.task.space import Design_space
  import numpy
label_desc: Use image node_id 2 for calling the AcquisitionOptimizer obj's underlying member method code with example usage: obj.optimize(f, df, f_df, duplicate_manager) and returns: x_min,  fx_min