From f1fca01fca58a641cdc9bc9dc0aba2f1f25ff9ad Mon Sep 17 00:00:00 2001 From: Sait Cakmak Date: Fri, 3 May 2024 14:17:23 -0700 Subject: [PATCH] Clarify is_non_dominated behavior with NaN (#2332) Summary: Pull Request resolved: https://github.com/pytorch/botorch/pull/2332 Since `<=` & `>=` always evaluate to False with NaN elements of tensors, this counts NaNs as dominated point, which is the desired behavior. Reviewed By: Balandat Differential Revision: D56945207 fbshipit-source-id: c439ac75c762980bc0035f70cd925377d28157e2 --- botorch/utils/multi_objective/pareto.py | 2 ++ test/utils/multi_objective/test_pareto.py | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/botorch/utils/multi_objective/pareto.py b/botorch/utils/multi_objective/pareto.py index af4c3dd0ca..4f099466ea 100644 --- a/botorch/utils/multi_objective/pareto.py +++ b/botorch/utils/multi_objective/pareto.py @@ -30,6 +30,8 @@ def is_non_dominated( Args: Y: A `(batch_shape) x n x m`-dim tensor of outcomes. + If any element of `Y` is NaN, the corresponding point + will be treated as a dominated point (returning False). maximize: If True, assume maximization (default). deduplicate: A boolean indicating whether to only return unique points on the pareto frontier. diff --git a/test/utils/multi_objective/test_pareto.py b/test/utils/multi_objective/test_pareto.py index f448f1aa47..d352c0128a 100644 --- a/test/utils/multi_objective/test_pareto.py +++ b/test/utils/multi_objective/test_pareto.py @@ -158,6 +158,13 @@ def test_is_non_dominated(self) -> None: cargs = mock_is_non_dominated_loop.call_args[0] self.assertTrue(torch.equal(cargs[0], y)) + def test_is_non_dominated_with_nan(self) -> None: + # NaN should always evaluate to False. + Y = torch.rand(10, 2) + Y[3, 1] = float("nan") + Y[7, 0] = float("nan") + self.assertFalse(is_non_dominated(Y)[[3, 7]].any()) + def test_is_non_dominated_loop(self): n = 20 tkwargs = {"device": self.device}