class_docstr: Runner of Bayesian optimization loop. This class wraps the optimization loop around the different handlers.
  :param model: GPyOpt model class.
  :param space: GPyOpt space class.
  :param objective: GPyOpt objective class.
  :param acquisition: GPyOpt acquisition class.
  :param evaluator: GPyOpt evaluator class.
  :param X_init: 2d numpy array containing the initial inputs (one per row) of the model.
  :param Y_init: 2d numpy array containing the initial outputs (one per row) of the model.
  :param cost: GPyOpt cost class (default, none).
  :param normalize_Y: whether to normalize the outputs before performing any optimization (default, True).
  :param model_update_interval: interval of collected observations after which the model is updated (default, 1).
  :param de_duplication: GPyOpt DuplicateManager class. Avoids re-evaluating the objective at previous, pending or infeasible locations (default, False).
docstr: Saves a report with the main results of the optimization.
  
  :param report_file: name of the file in which the results of the optimization are saved.
docstr_tok: ["Saves","a","report","with","the","main","results","of","the","optimization",".",":","param","report_file",":","name","of","the","file","in","which","the","results","of","the","optimization","are","saved","."]
code: def save_report(self, report_file=None):
      """
      Saves a report with the main results of the optimization.
  
      :param report_file: name of the file in which the results of the optimization are saved.
      """
  
      with open(report_file, "w") as file:
          import GPyOpt
          import time
  
          file.write(
              "-----------------------------"
              + " GPyOpt Report file "
              + "-----------------------------------\n"
          )
          file.write("GPyOpt Version " + str(GPyOpt.__version__) + "\n")
          file.write(
              "Date and time:               "
              + time.strftime("%c")
              + "\n"
          )
          if self.num_acquisitions == self.max_iter:
              file.write(
                  "Optimization completed:      "
                  + "YES, "
                  + str(self.X.shape[0]).strip("[]")
                  + " samples collected.\n"
              )
              file.write(
                  "Number initial samples:      "
                  + str(self.initial_design_numdata)
                  + " \n"
              )
          else:
              file.write(
                  "Optimization completed:      "
                  + "NO,"
                  + str(self.X.shape[0]).strip("[]")
                  + " samples collected.\n"
              )
              file.write(
                  "Number initial samples:      "
                  + str(self.initial_design_numdata)
                  + " \n"
              )
  
          file.write(
              "Tolerance:                   " + str(self.eps) + ".\n"
          )
          file.write(
              "Optimization time:           "
              + str(self.cum_time).strip("[]")
              + " seconds.\n"
          )
  
          file.write("\n")
          file.write(
              "--------------------------------"
              + " Problem set up "
              + "------------------------------------\n"
          )
          file.write(
              "Problem name:                "
              + self.objective_name
              + "\n"
          )
          file.write(
              "Problem dimension:           "
              + str(self.space.dimensionality)
              + "\n"
          )
          file.write(
              "Number continuous variables  "
              + str(len(self.space.get_continuous_dims()))
              + "\n"
          )
          file.write(
              "Number discrete variables    "
              + str(len(self.space.get_discrete_dims()))
              + "\n"
          )
          file.write(
              "Number bandits               "
              + str(self.space.get_bandit().shape[0])
              + "\n"
          )
          file.write(
              "Noiseless evaluations:       "
              + str(self.exact_feval)
              + "\n"
          )
          file.write(
              "Cost used:                   "
              + self.cost.cost_type
              + "\n"
          )
          file.write(
              "Constraints:                  "
              + str(self.constraints == True)
              + "\n"
          )
  
          file.write("\n")
          file.write(
              "------------------------------"
              + " Optimization set up "
              + "---------------------------------\n"
          )
          file.write(
              "Normalized outputs:          "
              + str(self.normalize_Y)
              + "\n"
          )
          file.write(
              "Model type:                  "
              + str(self.model_type).strip("[]")
              + "\n"
          )
          file.write(
              "Model update interval:       "
              + str(self.model_update_interval)
              + "\n"
          )
          file.write(
              "Acquisition type:            "
              + str(self.acquisition_type).strip("[]")
              + "\n"
          )
          file.write(
              "Acquisition optimizer:       "
              + str(self.acquisition_optimizer.optimizer_name).strip(
                  "[]"
              )
              + "\n"
          )
  
          file.write(
              "Acquisition type:            "
              + str(self.acquisition_type).strip("[]")
              + "\n"
          )
          if hasattr(self, "acquisition_optimizer") and hasattr(
              self.acquisition_optimizer, "optimizer_name"
          ):
              file.write(
                  "Acquisition optimizer:       "
                  + str(
                      self.acquisition_optimizer.optimizer_name
                  ).strip("[]")
                  + "\n"
              )
          else:
              file.write("Acquisition optimizer:       None\n")
          file.write(
              "Evaluator type (batch size): "
              + str(self.evaluator_type).strip("[]")
              + " ("
              + str(self.batch_size)
              + ")"
              + "\n"
          )
          file.write(
              "Cores used:                  "
              + str(self.num_cores)
              + "\n"
          )
  
          file.write("\n")
          file.write(
              "---------------------------------"
              + " Summary "
              + "------------------------------------------\n"
          )
          file.write(
              "Value at minimum:            "
              + str(min(self.Y)).strip("[]")
              + "\n"
          )
          file.write(
              "Best found minimum location: "
              + str(self.X[np.argmin(self.Y), :]).strip("[]")
              + "\n"
          )
  
          file.write(
              "----------------------------------------------------------------------------------------------\n"
          )
          file.close()
  
imports: import GPyOpt
  import collections
  import numpy
  import time
  import csv
  import logging
  from ..util.general import best_value, normalize
  from ..util.duplicate_manager import DuplicateManager
  from ..core.errors import InvalidConfigError
  from ..core.task.cost import CostModel
  from ..optimization.acquisition_optimizer import ContextManager
label_desc: Use image node_id 14 for calling the BO obj's underlying member method code with example usage: obj.save_report(report_file) without return types