class_docstr: Combines a function and its parametrization for running experiments (see benchmark subpackage)
  
  Parameters
  ----------
  function: callable
      the callable to convert
  parametrization: Parameter
      the parametrization of the function
  Notes
  -----
  - you can redefine custom "evaluation_function" and "compute_pseudotime" for custom behaviors in experiments
  - the bool/int/str/float init arguments are added as descriptors for the experiment which will serve in
    definining test cases. You can add more through "add_descriptors".
  - Makes sure you the "copy()" methods works (provides a new copy of the function *and* its parametrization)
    if you subclass ExperimentFunction since it is intensively used in benchmarks.
    By default, this will create a new instance using the same init arguments as your current instance
    (they were recorded through "__new__"'s magic) and apply the additional descriptors you may have added,
    as well as propagate the new parametrization *if it has a different name as the current one*.
class_docstr_tok: ["Combines","a","function","and","its","parametrization","for","running","experiments","(","see","benchmark","subpackage",")","Parameters","--","--","--","--","--","function",":","callable","the","callable","to","convert","parametrization",":","Parameter","the","parametrization","of","the","function","Notes","--","--","-","-","you","can","redefine","custom","``","evaluation_function","''","and","``","compute_pseudotime","''","for","custom","behaviors","in","experiments","-","the","bool\/int\/str\/float","init","arguments","are","added","as","descriptors","for","the","experiment","which","will","serve","in","definining","test","cases",".","You","can","add","more","through","``","add_descriptors","''",".","-","Makes","sure","you","the","``","copy","(",")","''","methods","works","(","provides","a","new","copy","of","the","function","*","and","*","its","parametrization",")","if","you","subclass","ExperimentFunction","since","it","is","intensively","used","in","benchmarks",".","By","default",",","this","will","create","a","new","instance","using","the","same","init","arguments","as","your","current","instance","(","they","were","recorded","through","``","__new__","''","'s","magic",")","and","apply","the","additional","descriptors","you","may","have","added",",","as","well","as","propagate","the","new","parametrization","*","if","it","has","a","different","name","as","the","current","one","*","."]
docstr: Provides a new equivalent instance of the class, possibly with
  different random initialization, to provide different equivalent test cases
  when using different seeds.
  This also checks that parametrization and descriptors are correct.
  You should preferably override _internal_copy
docstr_tok: ["Provides","a","new","equivalent","instance","of","the","class",",","possibly","with","different","random","initialization",",","to","provide","different","equivalent","test","cases","when","using","different","seeds",".","This","also","checks","that","parametrization","and","descriptors","are","correct",".","You","should","preferably","override","_internal_copy"]
code: def copy(self: EF) -> EF:
      """Provides a new equivalent instance of the class, possibly with
      different random initialization, to provide different equivalent test cases
      when using different seeds.
      This also checks that parametrization and descriptors are correct.
      You should preferably override _internal_copy
      """
      # add descriptors present in self but not added by initialization
      # (they must have been added manually)
      output = self._internal_copy()
      keys = set(output.descriptors)
      output.add_descriptors(
          **{x: y for x, y in self.descriptors.items() if x not in keys}
      )
      # parametrization may have been overriden, so let's always update it
      # Caution: only if names differ!
      if output.parametrization.name != self.parametrization.name:
          output.parametrization = _reset_copy(self.parametrization)
      # then if there are still differences, something went wrong
      if not output.equivalent_to(self):
          raise errors.ExperimentFunctionCopyError(
              f"Copy of\n{self}\nwith descriptors:\n{self._descriptors}\nreturned non-equivalent\n"
              f"{output}\nwith descriptors\n{output._descriptors}.\n\n"
              "This means that the auto-copy behavior of ExperimentFunction does not work.\n"
              "You may want to implement your own copy method, or check implementation of "
              "ExperimentFunction.__new__ and copy to better understand what happens"
          )
      # propagate other useful information # TODO a bit hacky
      output.parametrization._constraint_checkers = (
          self.parametrization._constraint_checkers
      )
      output.multiobjective_upper_bounds = (
          self.multiobjective_upper_bounds
      )  # TODO not sure why this is needed
      return output
  
imports: import inspect
  from pathlib import Path
  import numbers
  import numpy
  import nevergrad.common.typing
  from nevergrad.common import errors
  from nevergrad.common.errors import UnsupportedExperiment
  from nevergrad.parametrization import parameter
  from nevergrad.optimization import multiobjective
label_desc: Use image node_id 13 for calling the ExperimentFunction obj's underlying member method code with example usage: obj.copy() and returns: output