def gen( self, n: int, bounds: List[Tuple[float, float]], linear_constraints: Optional[Tuple[np.ndarray, np.ndarray]] = None, fixed_features: Optional[Dict[int, float]] = None, model_gen_options: Optional[TConfig] = None, rounding_func: Optional[Callable[[np.ndarray], np.ndarray]] = None, ) -> Tuple[np.ndarray, np.ndarray]: """Generate new candidates. Args: n: Number of candidates to generate. bounds: A list of (lower, upper) tuples for each column of X. Defined on [0, 1]^d. linear_constraints: A tuple of (A, b). For k linear constraints on d-dimensional x, A is (k x d) and b is (k x 1) such that A x <= b. fixed_features: A map {feature_index: value} for features that should be fixed to a particular value during generation. model_gen_options: A config dictionary that is passed along to the model. rounding_func: A function that rounds an optimization result appropriately (e.g., according to `round-trip` transformations). Returns: 2-element tuple containing - (n x d) array of generated points. - Uniform weights, an n-array of ones for each point. """ tf_indices = tunable_feature_indices(bounds=bounds, fixed_features=fixed_features) if fixed_features: fixed_feature_indices = np.array(list(fixed_features.keys())) else: fixed_feature_indices = np.array([]) validate_bounds(bounds=bounds, fixed_feature_indices=fixed_feature_indices) attempted_draws = 0 max_draws = None if model_gen_options: max_draws = model_gen_options.get("max_rs_draws") if max_draws is not None: max_draws: int = int(max_draws) # Always rejection sample, but this only rejects if there are # constraints or actual duplicates and deduplicate is specified. points, attempted_draws = rejection_sample( gen_unconstrained=self._gen_unconstrained, n=n, d=len(bounds), tunable_feature_indices=tf_indices, linear_constraints=linear_constraints, deduplicate=self.deduplicate, max_draws=max_draws, fixed_features=fixed_features, rounding_func=rounding_func, existing_points=self.generated_points, ) # pyre-fixme[16]: `RandomModel` has no attribute `attempted_draws`. self.attempted_draws = attempted_draws if self.deduplicate: if self.generated_points is None: self.generated_points = points else: # pyre-fixme[6]: Expected `Collection[ndarray]` for 1st param but # got `List[Optional[ndarray]]`. self.generated_points = np.vstack( [self.generated_points, points]) return (points, np.ones(len(points)))
def gen( self, n: int, bounds: List[Tuple[float, float]], linear_constraints: Optional[Tuple[np.ndarray, np.ndarray]] = None, fixed_features: Optional[Dict[int, float]] = None, model_gen_options: Optional[TConfig] = None, rounding_func: Optional[Callable[[np.ndarray], np.ndarray]] = None, ) -> Tuple[np.ndarray, np.ndarray]: """Generate new candidates. Args: n: Number of candidates to generate. bounds: A list of (lower, upper) tuples for each column of X. Defined on [0, 1]^d. linear_constraints: A tuple of (A, b). For k linear constraints on d-dimensional x, A is (k x d) and b is (k x 1) such that A x <= b. fixed_features: A map {feature_index: value} for features that should be fixed to a particular value during generation. model_gen_options: A config dictionary that is passed along to the model. rounding_func: A function that rounds an optimization result appropriately (e.g., according to `round-trip` transformations). Returns: 2-element tuple containing - (n x d) array of generated points. - Uniform weights, an n-array of ones for each point. """ tf_indices = tunable_feature_indices( bounds=bounds, fixed_features=fixed_features ) if fixed_features: fixed_feature_indices = np.array(list(fixed_features.keys())) else: fixed_feature_indices = np.array([]) validate_bounds(bounds=bounds, fixed_feature_indices=fixed_feature_indices) attempted_draws = 0 max_draws = None if model_gen_options: max_draws = model_gen_options.get("max_rs_draws") if max_draws is not None: # pyre-fixme[6]: Expected `Union[bytes, str, typing.SupportsInt]` # for 1st param but got # `Union[botorch.acquisition.acquisition.AcquisitionFunction, float, # int, str]`. # pyre-fixme[35]: Target cannot be annotated. max_draws: int = int(max_draws) try: # Always rejection sample, but this only rejects if there are # constraints or actual duplicates and deduplicate is specified. # If rejection sampling fails, fall back to polytope sampling points, attempted_draws = rejection_sample( gen_unconstrained=self._gen_unconstrained, n=n, d=len(bounds), tunable_feature_indices=tf_indices, linear_constraints=linear_constraints, deduplicate=self.deduplicate, max_draws=max_draws, fixed_features=fixed_features, rounding_func=rounding_func, existing_points=self.generated_points, ) except SearchSpaceExhausted as e: if self.fallback_to_sample_polytope: logger.info( "Rejection sampling exceeded specified maximum draws." "Falling back on polytope sampler" ) # If rejection sampling fails, try polytope sampler. polytope_sampler = HitAndRunPolytopeSampler( inequality_constraints=self._convert_inequality_constraints( linear_constraints ), equality_constraints=self._convert_equality_constraints( len(bounds), fixed_features ), interior_point=self._get_last_point(), bounds=self._convert_bounds(bounds), ) points = polytope_sampler.draw(n).numpy() else: raise e # pyre-fixme[16]: `RandomModel` has no attribute `attempted_draws`. self.attempted_draws = attempted_draws if self.deduplicate: if self.generated_points is None: self.generated_points = points else: self.generated_points = np.vstack([self.generated_points, points]) return points, np.ones(len(points))