class_docstr: Wrapper around an algorithm that applies some transformation to the trials it suggests.
  
  The inverse transformation is applied to the observed trials before they get passed down to the
  wrapped algorithm's `observe` method.
class_docstr_tok: ["Wrapper","around","an","algorithm","that","applies","some","transformation","to","the","trials","it","suggests",".","The","inverse","transformation","is","applied","to","the","observed","trials","before","they","get","passed","down","to","the","wrapped","algorithm","'s","`","observe","`","method","."]
docstr: Suggest a `num` of new sets of parameters.
  
  Parameters
  ----------
  num: int
      Number of trials to suggest. The algorithm may return less than the number of trials
      requested.
  
  Returns
  -------
  list of trials
      A list of trials representing values suggested by the algorithm. The algorithm may opt
      out if it cannot make a good suggestion at the moment (it may be waiting for other
      trials to complete), in which case it will return an empty list.
  
  Notes
  -----
  New parameters must be compliant with the problem's domain `orion.algo.space.Space`.
docstr_tok: ["Suggest","a","`","num","`","of","new","sets","of","parameters",".","Parameters","--","--","--","--","--","num",":","int","Number","of","trials","to","suggest",".","The","algorithm","may","return","less","than","the","number","of","trials","requested",".","Returns","--","--","--","-","list","of","trials","A","list","of","trials","representing","values","suggested","by","the","algorithm",".","The","algorithm","may","opt","out","if","it","can","not","make","a","good","suggestion","at","the","moment","(","it","may","be","waiting","for","other","trials","to","complete",")",",","in","which","case","it","will","return","an","empty","list",".","Notes","--","--","-","New","parameters","must","be","compliant","with","the","problem","'s","domain","`","orion.algo.space.Space","`","."]
code: def suggest(self, num: int) -> list[Trial]:
      """Suggest a `num` of new sets of parameters.
  
      Parameters
      ----------
      num: int
          Number of trials to suggest. The algorithm may return less than the number of trials
          requested.
  
      Returns
      -------
      list of trials
          A list of trials representing values suggested by the algorithm. The algorithm may opt
          out if it cannot make a good suggestion at the moment (it may be waiting for other
          trials to complete), in which case it will return an empty list.
  
      Notes
      -----
      New parameters must be compliant with the problem's domain `orion.algo.space.Space`.
  
      """
  
      trials: list[Trial] = []
  
      transformed_trials: list[Trial] = (
          self.algorithm.suggest(num) or []
      )
  
      for transformed_trial in transformed_trials:
          if transformed_trial not in self.algorithm.space:
              raise ValueError(
                  f"Trial {transformed_trial.id} not contained in space:\n"
                  f"Params: {transformed_trial.params}\n"
                  f"Space: {self.algorithm.space}"
              )
          original = self.reverse_transform(transformed_trial)
          original.parent = None
          # The parent attribute is copied over from the transformed trial to the original trial.
          # this might be wrong, so we correct any errors if necessary.
          if transformed_trial.parent:
              # NOTE: This block of code was previously in what has become the SpaceTransform
              # wrapper, which assumes the following: (remove if this is unnecessary and holds
              # otherwise).
              assert isinstance(
                  self.algorithm.space,
                  (TransformedSpace, ReshapedSpace),
              )
              original_parent = _get_original_parent(
                  reverse_transformation=self.reverse_transform,
                  transformed_registry=self.algorithm.registry,
                  transformed_trial_parent_id=transformed_trial.parent,
              )
              if original_parent.id not in self.registry:
                  raise KeyError(
                      f"Parent trial with id {original_parent.id} is not registered in the "
                      f"algorithm!"
                  )
              original.parent = original_parent.id
  
          # NOTE: We're setting the original.parent above because `self.has_suggested` uses the
          # trial id, which itself depends on the parent attribute of the trial.
  
          if self.has_suggested(original):
              logger.debug(
                  "Already have a trial that matches %s in the registry.",
                  original,
              )
              # We already have a trial that is equivalent to this one.
              # Fetch the actual trial (with the status and possibly results)
              original_with_status = self.registry.get_existing(
                  original
              )
              logger.debug(
                  "Matching trial (with results/status): %s",
                  original_with_status,
              )
  
              # Copy over the status and results from the original to the transformed trial
              # and observe it.
              transformed_trial = _copy_status_and_results(
                  trial_with_status=original_with_status,
                  trial=transformed_trial,
              )
              logger.debug(
                  "Transformed trial (with results/status): %s",
                  transformed_trial,
              )
              self.algorithm.observe([transformed_trial])
  
              # Register the equivalence between these trials.
              self.registry_mapping.register(
                  original_with_status, transformed_trial
              )
          else:
              # We haven't seen this trial before. Register it.
              self.register(original)
              trials.append(original)
  
              # NOTE: Here we DON'T register the transformed trial, we let the algorithm do it
              # itself in its `suggest`.
              # Register the equivalence between these trials.
              self.registry_mapping.register(
                  original, transformed_trial
              )
      return trials
  
imports: from __future__ import annotations
  import copy
  import typing
  from abc import ABC, abstractmethod
  from logging import getLogger
  from typing import Any, Callable
  from orion.algo.base.registry import Registry, RegistryMapping
  from orion.algo.space import Space
  from orion.core.worker.algo_wrappers.algo_wrapper import AlgoT, AlgoWrapper
  from orion.core.worker.transformer import ReshapedSpace, TransformedSpace
  from orion.core.worker.trial import Trial
label_desc: Use image node_id 4 for calling the TransformWrapper obj's underlying member method code with example usage: obj.suggest(num) and returns: trials