in botorch/utils/multi_objective/pareto.py [0:0]
def is_non_dominated(Y: Tensor, deduplicate: bool = True) -> Tensor:
r"""Computes the non-dominated front.
Note: this assumes maximization.
For small `n`, this method uses a highly parallel methodology
that compares all pairs of points in Y. However, this is memory
intensive and slow for large `n`. For large `n` (or if Y is larger
than 5MB), this method will dispatch to a loop-based approach
that is faster and has a lower memory footprint.
Args:
Y: A `(batch_shape) x n x m`-dim tensor of outcomes.
deduplicate: A boolean indicating whether to only return
unique points on the pareto frontier.
Returns:
A `(batch_shape) x n`-dim boolean tensor indicating whether
each point is non-dominated.
"""
n = Y.shape[-2]
if n == 0:
return torch.zeros(Y.shape[:-1], dtype=torch.bool, device=Y.device)
el_size = 64 if Y.dtype == torch.double else 32
if n > 1000 or n ** 2 * Y.shape[:-2].numel() * el_size / 8 > MAX_BYTES:
return _is_non_dominated_loop(Y)
Y1 = Y.unsqueeze(-3)
Y2 = Y.unsqueeze(-2)
dominates = (Y1 >= Y2).all(dim=-1) & (Y1 > Y2).any(dim=-1)
nd_mask = ~(dominates.any(dim=-1))
if deduplicate:
# remove duplicates
# find index of first occurrence of each unique element
indices = (Y1 == Y2).all(dim=-1).long().argmax(dim=-1)
keep = torch.zeros_like(nd_mask)
keep.scatter_(dim=-1, index=indices, value=1.0)
return nd_mask & keep
return nd_mask