qpots.utils.acq_utils

Acquisition-function helper routines used by qPOTS experiments and baselines, including model initialization, hypervolume utilities, qNEHVI/HVKG helpers, and decoupled PESMO utilities.

class qpots.utils.acq_utils._CompetitiveDecouplingMixin[source]

Bases: object

Minimal mask plumbing for competitive decoupling.

This intentionally supports only q=1 when a mask is provided. That is the standard ‘pick one x and one outcome to evaluate’ setting used in the decoupled HVKG tutorial.

X_evaluation_mask: Tensor | None
_selected_output_indices(q: int) list[int][source]

Return output indices selected by the current decoupling mask.

Parameters:

q (int) – Acquisition batch size. Masked competitive decoupling currently supports only q=1 because it compares one candidate-output pair at a time.

Returns:

Selected output indices. If no mask is set, all outputs are returned.

Return type:

list[int]

_selected_output_mask(q: int, *, dtype: dtype, device: device) Tensor[source]

Build a numeric one-dimensional mask for selected model outputs.

Parameters:
  • q (int) – Acquisition batch size forwarded to _selected_output_indices.

  • dtype (torch.dtype) – Desired dtype for the returned mask.

  • device (torch.device) – Desired device for the returned mask.

Returns:

Tensor of length model.num_outputs with ones at selected outputs and zeros elsewhere.

Return type:

torch.Tensor

_set_X_evaluation_mask(X_evaluation_mask: Tensor | None) None[source]

Set and validate the output-observation mask for the next acquisition call.

Parameters:

X_evaluation_mask (torch.Tensor or None) – Boolean q x M mask selecting the outputs to observe. Passing None restores coupled evaluation of all outputs.

qpots.utils.acq_utils._validate_mask(mask: Tensor | None, num_outputs: int) None[source]

Validate a decoupled-evaluation mask used by competitive acquisition rules.

Parameters:
  • mask (torch.Tensor or None) – Boolean tensor of shape q x num_outputs. Each row marks which model outputs would be observed for the associated candidate. None means all outputs are observed.

  • num_outputs (int) – Total number of model outputs, including objectives and constraints.

Raises:

ValueError – If mask has the wrong shape or contains a row with no selected output.

qpots.utils.acq_utils.build_pareto_state(model, bounds: Tensor, *, num_pareto_samples: int = 8, num_pareto_points: int = 8, maximize: bool = True) tuple[Tensor, Tensor, Tensor][source]

Sample Pareto sets/fronts and compute hypercell bounds.

qpots.utils.acq_utils.choose_competitive_decoupled_candidate(make_acqf: Callable[[Tensor], object], bounds: Tensor, options: dict, num_outputs: int, *, objective_costs: Sequence[float] | Tensor | None = None, num_restarts: int = 10, raw_samples: int = 512) dict[str, Tensor | int][source]

Optimize one acquisition per outcome and pick the best (x, outcome) pair.

make_acqf(mask) must return an acquisition function that accepts a one-hot 1 x M evaluation mask.

qpots.utils.acq_utils.generate_sobol_data(n, problem)[source]

Generate an initial Sobol design and evaluate the optimization problem.

Parameters:
  • n (int) – Number of Sobol points to draw.

  • problem (callable) – BoTorch-style test problem with a bounds attribute and a callable interface that evaluates inputs in the original design space.

Returns:

(train_x, train_obj_true) where train_x has shape n x d and train_obj_true contains the corresponding objective values.

Return type:

tuple[torch.Tensor, torch.Tensor]

qpots.utils.acq_utils.get_current_value(model, ref_point, bounds, mcobjective=None)[source]

Helper to get the hypervolume of the current hypervolume maximizing set.

qpots.utils.acq_utils.hypervolume_from_posterior_mean_gp(model, X: Tensor, ncons, *, ref_point, maximize) Tensor[source]

Compute the hypervolume of the posterior mean Pareto front from a GP model.

This function evaluates the GP posterior mean at a set of input points, filters infeasible solutions (if constraints are present), extracts the non-dominated subset, and computes the hypervolume indicator.

Parameters:
  • model (ModelListGP or compatible GP model) – A trained BoTorch model. Must support posterior(X) and return a posterior with mean of shape n x m, where n is the number of input points and m is the number of outputs.

  • X (torch.Tensor) – Candidate design points with shape n x d. These are the design points at which the posterior mean is evaluated.

  • ncons (int) –

    Number of constraint outputs included in the model. Assumes that the last ncons outputs correspond to constraints.

    A point is feasible if all constraint values are nonnegative. Infeasible points are penalized and excluded from Pareto computation.

  • ref_point (array-like or torch.Tensor) – Reference point for hypervolume computation. Must have shape (m_obj,), where m_obj = number of objectives (i.e., total outputs minus constraints).

  • maximize (bool) – Whether the objectives are being maximized. If False, objectives and the reference point are negated to convert the calculation into a maximization problem.

Returns:

hv – The computed hypervolume of the non-dominated posterior mean set.

Return type:

torch.Tensor (scalar)

Notes

This uses the posterior mean only, not posterior samples. It assumes constraints are ordered as the final ncons outputs. If no nondominated points are available, it returns a scalar zero tensor.

qpots.utils.acq_utils.initialize_model(train_x_list, train_obj_list, bounds)[source]

Used for HVKG, qNEHVI, Sobol models

Initialize a multi-output Gaussian Process model (ModelListGP) for objectives and (optionally) constraints using independent SingleTaskGPs.

Each entry in train_obj_list corresponds to one GP model. Inputs are normalized to [0, 1]^d using the provided bounds.

Parameters:
  • train_x_list (list of torch.Tensor) – List of input tensors, one per objective or constraint. Each tensor has shape n_i x d, where n_i is the number of training points for output i and d is the input dimension. Different outputs may use different input sets. Note: This allows different datasets per output (i.e., not necessarily shared X).

  • train_obj_list (list of torch.Tensor) –

    List of output tensors (objectives and/or constraints), one per model. Each tensor has shape (n_i, 1).

    Objectives and constraints should already be combined into this list. Constraints are modeled the same way as objectives here.

  • bounds (torch.Tensor) – Tensor of shape 2 x d specifying lower and upper bounds for each input dimension. bounds[0] contains lower bounds and bounds[1] contains upper bounds.

Returns:

  • mll (SumMarginalLogLikelihood) – Marginal log likelihood object used for training the ModelListGP.

  • model (ModelListGP) – A container of independent SingleTaskGP models, one per objective/constraint.

  • Assumptions

  • ———–

    • train_x_list and train_obj_list have the same length.

  • - Each (train_x_list[i], train_obj_list[i]) pair is aligned.

  • - Outputs are already properly shaped (n_i, 1).

  • Potential Extensions

  • ——————–

  • - Use a MultiTaskGP instead of ModelListGP to model correlations between outputs.

    • Learn noise instead of fixing it (remove train_Yvar).

  • - Add kernel priors or ARD lengthscales for better performance in higher dimensions.

qpots.utils.acq_utils.optimize_HVKG_and_get_obs_decoupled(model, q, problem, cost_model, standard_bounds, objective_indices, nobj, ncons, train_x)[source]

Utility to initialize and optimize HVKG.

qpots.utils.acq_utils.optimize_qnehvi_and_get_observation(model, train_x, sampler, q, problem, standard_bounds, ncons, nobj)[source]

Optimizes the qNEHVI acquisition function, and returns a new candidate and observation.

class qpots.utils.acq_utils.qDecoupledPESMO(*args, X_evaluation_mask: Tensor | None = None, **kwargs)[source]

Bases: _CompetitiveDecouplingMixin, qMultiObjectivePredictiveEntropySearch

Predictive entropy search acquisition with competitive decoupled outputs.

This subclass adapts BoTorch’s qMultiObjectivePredictiveEntropySearch so that a single output can be scored at a candidate point. It is useful for decoupled multiobjective experiments where evaluating every objective or constraint at every point is unnecessary or has different cost.

Notes

The implementation is intentionally narrow: when an evaluation mask is set, it supports the common competitive setting q=1 and compares one candidate-output pair at a time.

_abc_impl = <_abc._abc_data object>
_compute_information_gain(X: Tensor) Tensor[source]

Evaluate the approximate PESMO information gain at candidate points.

Parameters:

X (torch.Tensor) – Candidate tensor with BoTorch acquisition shape batch_shape x q x d.

Returns:

Acquisition value for each batch element. Larger values indicate higher expected information gain about the Pareto-optimal set.

Return type:

torch.Tensor

_masked_logdet(cov: Tensor, q: int) Tensor[source]

Compute the PES log-determinant term for selected outputs only.

Parameters:
  • cov (torch.Tensor) – Predictive covariance tensor produced by BoTorch’s PES utilities.

  • q (int) – Batch size represented in cov.

Returns:

Log-determinant contribution averaged over Pareto samples and restricted to the selected output mask when one is active.

Return type:

torch.Tensor

forward(X: Any, *args: Any, **kwargs: Any) Any

Evaluate the acquisition function on the candidate set X.

Parameters:

X – A (b) x q x d-dim Tensor of (b) t-batches with q d-dim design points each.

Returns:

A (b)-dim Tensor of acquisition function values at the given design points X.