class_docstr: Generation strategy for REMBO.
  
  Both quasirandom initialization and BO are done with the same random
  projection. As is done in the REMBO paper, k independent optimizations
  are done, each with an independently generated projection.
  
  Args:
      D: Dimensionality of high-dimensional space
      d: Dimensionality of low-dimensional space
      k: Number of random projections
      init_per_proj: Number of arms to use for random initialization of each
          of the k projections.
      name: Name of strategy
      dtype: torch dtype
      device: torch device
      gp_kwargs: kwargs sent along to the GP model
class_docstr_tok: ["Generation","strategy","for","REMBO",".","Both","quasirandom","initialization","and","BO","are","done","with","the","same","random","projection",".","As","is","done","in","the","REMBO","paper",",","k","independent","optimizations","are","done",",","each","with","an","independently","generated","projection",".","Args",":","D",":","Dimensionality","of","high-dimensional","space","d",":","Dimensionality","of","low-dimensional","space","k",":","Number","of","random","projections","init_per_proj",":","Number","of","arms","to","use","for","random","initialization","of","each","of","the","k","projections",".","name",":","Name","of","strategy","dtype",":","torch","dtype","device",":","torch","device","gp_kwargs",":","kwargs","sent","along","to","the","GP","model"]
docstr: Generate new points, rotating through projections each time.
docstr_tok: ["Generate","new","points",",","rotating","through","projections","each","time","."]
code: def gen(
      self,
      experiment: Experiment,
      data: Optional[Data] = None,
      n: int = 1,
      **kwargs: Any,
  ) -> GeneratorRun:
      """Generate new points, rotating through projections each time."""
      if data is None:
          data = experiment.fetch_data()
      # Get the next model in the rotation
      i = self.current_iteration % self.k
      data_by_proj = self._filter_data_to_projection(
          experiment=experiment,
          data=data,
          arm_sigs=self.arms_by_proj[i],
      )
      lgr = self.last_generator_run
      # NOTE: May need to `model_class.deserialize_model_state` in the
      # future if using non-readily serializable state.
      model_state = (
          not_none(lgr._model_state_after_gen)
          if lgr is not None and lgr._model_state_after_gen is not None
          else {}
      )
  
      A, bounds_d = self.projections[i]
      if (
          data_by_proj is None
          or len(data_by_proj.df["arm_name"].unique())
          < self.init_per_proj
      ):
          # Not enough data to switch to GP, use Sobol for initialization
          m = get_rembo_initializer(
              search_space=experiment.search_space,
              A=A.double().numpy(),
              bounds_d=bounds_d,
              **model_state,
          )
      else:
          # We have enough data to switch to GP.
          m = get_REMBO(
              experiment=experiment,
              data=data_by_proj,
              A=A,
              initial_X_d=torch.tensor(
                  self.X_d_by_proj[i],
                  dtype=self.dtype,
                  device=self.device,
              ),
              bounds_d=bounds_d,
              **self.gp_kwargs,
          )
  
      self.current_iteration += 1
      # Call gen
      gr = m.gen(n=n)
      self.X_d_by_proj[i].extend(
          not_none(m.model).X_d_gen
      )  # pyre-ignore[16]
      self.arms_by_proj[i].update(a.signature for a in gr.arms)
      self._generator_runs.append(gr)
      return gr
  
imports: import math
  from collections import defaultdict
  from typing import Any, Dict, List, Optional, Set, Tuple
  import numpy
  import torch
  from ax.core.data import Data
  from ax.core.experiment import Experiment
  from ax.core.generator_run import GeneratorRun
  from ax.core.search_space import SearchSpace
  from ax.modelbridge.factory import DEFAULT_TORCH_DEVICE
  from ax.modelbridge.generation_strategy import GenerationStep, GenerationStrategy
  from ax.modelbridge.random import RandomModelBridge
  from ax.modelbridge.torch import TorchModelBridge
  from ax.modelbridge.transforms.centered_unit_x import CenteredUnitX
  from ax.modelbridge.transforms.standardize_y import StandardizeY
  from ax.models.random.rembo_initializer import REMBOInitializer
  from ax.models.torch.rembo import REMBO
  from ax.utils.common.typeutils import not_none
label_desc: Use image node_id 3 for calling the REMBOStrategy obj's underlying member method code with example usage: obj.gen(experiment, data, n) and returns: gr