(
    train_x: "torch.Tensor",
    train_obj: "torch.Tensor",
    train_con: Optional["torch.Tensor"],
    bounds: "torch.Tensor",
)
return candidates
Quasi MC-based batch Expected Improvement (qEI).

    The default value of ``candidates_func`` in :class:`~optuna.integration.BoTorchSampler`
    with single-objective optimization.

    Args:
        train_x:
            Previous parameter configurations. A ``torch.Tensor`` of shape
            ``(n_trials, n_params)``. ``n_trials`` is the number of already observed trials
            and ``n_params`` is the number of parameters. ``n_params`` may be larger than the
            actual number of parameters if categorical parameters are included in the search
            space, since these parameters are one-hot encoded.
            Values are not normalized.
        train_obj:
            Previously observed objectives. A ``torch.Tensor`` of shape
            ``(n_trials, n_objectives)``. ``n_trials`` is identical to that of ``train_x``.
            ``n_objectives`` is the number of objectives. Observations are not normalized.
        train_con:
            Objective constraints. A ``torch.Tensor`` of shape ``(n_trials, n_constraints)``.
            ``n_trials`` is identical to that of ``train_x``. ``n_constraints`` is the number of
            constraints. A constraint is violated if strictly larger than 0. If no constraints are
            involved in the optimization, this argument will be :obj:`None`.
        bounds:
            Search space bounds. A ``torch.Tensor`` of shape ``(2, n_params)``. ``n_params`` is
            identical to that of ``train_x``. The first and the second rows correspond to the
            lower and upper bounds for each parameter respectively.

    Returns:
        Next set of candidates. Usually the return value of BoTorch's ``optimize_acqf``.
Quasi MC-based batch Expected Improvement (qEI).
Quasi MC - based batch Expected Improvement ( qEI ) .
def qei_candidates_func(
    train_x: "torch.Tensor",
    train_obj: "torch.Tensor",
    train_con: Optional["torch.Tensor"],
    bounds: "torch.Tensor",
) -> "torch.Tensor":
    """Quasi MC-based batch Expected Improvement (qEI).

    The default value of ``candidates_func`` in :class:`~optuna.integration.BoTorchSampler`
    with single-objective optimization.

    Args:
        train_x:
            Previous parameter configurations. A ``torch.Tensor`` of shape
            ``(n_trials, n_params)``. ``n_trials`` is the number of already observed trials
            and ``n_params`` is the number of parameters. ``n_params`` may be larger than the
            actual number of parameters if categorical parameters are included in the search
            space, since these parameters are one-hot encoded.
            Values are not normalized.
        train_obj:
            Previously observed objectives. A ``torch.Tensor`` of shape
            ``(n_trials, n_objectives)``. ``n_trials`` is identical to that of ``train_x``.
            ``n_objectives`` is the number of objectives. Observations are not normalized.
        train_con:
            Objective constraints. A ``torch.Tensor`` of shape ``(n_trials, n_constraints)``.
            ``n_trials`` is identical to that of ``train_x``. ``n_constraints`` is the number of
            constraints. A constraint is violated if strictly larger than 0. If no constraints are
            involved in the optimization, this argument will be :obj:`None`.
        bounds:
            Search space bounds. A ``torch.Tensor`` of shape ``(2, n_params)``. ``n_params`` is
            identical to that of ``train_x``. The first and the second rows correspond to the
            lower and upper bounds for each parameter respectively.

    Returns:
        Next set of candidates. Usually the return value of BoTorch's ``optimize_acqf``.

    """

    if train_obj.size(-1) != 1:
        raise ValueError("Objective may only contain single values with qEI.")
    if train_con is not None:
        train_y = torch.cat([train_obj, train_con], dim=-1)

        is_feas = (train_con <= 0).all(dim=-1)
        train_obj_feas = train_obj[is_feas]

        if train_obj_feas.numel() == 0:
            # TODO(hvy): Do not use 0 as the best observation.
            _logger.warning(
                "No objective values are feasible. Using 0 as the best objective in qEI."
            )
            best_f = torch.zeros(())
        else:
            best_f = train_obj_feas.max()

        constraints = []
        n_constraints = train_con.size(1)
        for i in range(n_constraints):
            constraints.append(lambda Z, i=i: Z[..., -n_constraints + i])
        objective = ConstrainedMCObjective(
            objective=lambda Z: Z[..., 0],
            constraints=constraints,
        )
    else:
        train_y = train_obj

        best_f = train_obj.max()

        objective = None  # Using the default identity objective.

    train_x = normalize(train_x, bounds=bounds)

    model = SingleTaskGP(train_x, train_y, outcome_transform=Standardize(m=train_y.size(-1)))
    mll = ExactMarginalLogLikelihood(model.likelihood, model)
    fit_gpytorch_model(mll)

    acqf = qExpectedImprovement(
        model=model,
        best_f=best_f,
        sampler=SobolQMCNormalSampler(num_samples=256),
        objective=objective,
    )

    standard_bounds = torch.zeros_like(bounds)
    standard_bounds[1] = 1

    candidates, _ = optimize_acqf(
        acq_function=acqf,
        bounds=standard_bounds,
        q=1,
        num_restarts=10,
        raw_samples=512,
        options={"batch_limit": 5, "maxiter": 200},
        sequential=True,
    )

    candidates = unnormalize(candidates.detach(), bounds=bounds)

    return candidates
def qei_candidates_func ( train_x : "torch.Tensor" , train_obj : "torch.Tensor" , train_con : Optional [ "torch.Tensor" ] , bounds : "torch.Tensor" , ) -> "torch.Tensor" : if train_obj . size ( - 1 ) != 1 : raise ValueError ( "Objective may only contain single values with qEI." ) if train_con is not None : train_y = torch . cat ( [ train_obj , train_con ] , dim = - 1 ) is_feas = ( train_con <= 0 ) . all ( dim = - 1 ) train_obj_feas = train_obj [ is_feas ] if train_obj_feas . numel ( ) == 0 : # TODO(hvy): Do not use 0 as the best observation. _logger . warning ( "No objective values are feasible. Using 0 as the best objective in qEI." ) best_f = torch . zeros ( ( ) ) else : best_f = train_obj_feas . max ( ) constraints = [ ] n_constraints = train_con . size ( 1 ) for i in range ( n_constraints ) : constraints . append ( lambda Z , i = i : Z [ ... , - n_constraints + i ] ) objective = ConstrainedMCObjective ( objective = lambda Z : Z [ ... , 0 ] , constraints = constraints , ) else : train_y = train_obj best_f = train_obj . max ( ) objective = None # Using the default identity objective. train_x = normalize ( train_x , bounds = bounds ) model = SingleTaskGP ( train_x , train_y , outcome_transform = Standardize ( m = train_y . size ( - 1 ) ) ) mll = ExactMarginalLogLikelihood ( model . likelihood , model ) fit_gpytorch_model ( mll ) acqf = qExpectedImprovement ( model = model , best_f = best_f , sampler = SobolQMCNormalSampler ( num_samples = 256 ) , objective = objective , ) standard_bounds = torch . zeros_like ( bounds ) standard_bounds [ 1 ] = 1 candidates , _ = optimize_acqf ( acq_function = acqf , bounds = standard_bounds , q = 1 , num_restarts = 10 , raw_samples = 512 , options = { "batch_limit" : 5 , "maxiter" : 200 } , sequential = True , ) candidates = unnormalize ( candidates . detach ( ) , bounds = bounds ) return candidates