From 54a243cf40937883f43868b0ba2b3a02f2bb0d01 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 28 Oct 2024 15:19:08 +0100 Subject: [PATCH 01/13] Use default dtype in bounds of test functions --- botorch/test_functions/base.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/botorch/test_functions/base.py b/botorch/test_functions/base.py index d65343315f..c4df1baadb 100644 --- a/botorch/test_functions/base.py +++ b/botorch/test_functions/base.py @@ -47,7 +47,10 @@ def __init__( f"Got {self.dim=} and {len(self._bounds)=}." ) self.register_buffer( - "bounds", torch.tensor(self._bounds, dtype=torch.double).transpose(-1, -2) + "bounds", + torch.tensor(self._bounds, dtype=torch.get_default_dtype()).transpose( + -1, -2 + ), ) def forward(self, X: Tensor, noise: bool = True) -> Tensor: From 7fd74db5029eb5d659a89c242effb8939b8747a0 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Mon, 28 Oct 2024 15:19:27 +0100 Subject: [PATCH 02/13] Update tests to use default dtype instead of double --- test/test_functions/test_synthetic.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/test_functions/test_synthetic.py b/test/test_functions/test_synthetic.py index 247036d5de..f92bb719ca 100644 --- a/test/test_functions/test_synthetic.py +++ b/test/test_functions/test_synthetic.py @@ -100,13 +100,14 @@ def test_custom_bounds(self): self.assertEqual(dummy._bounds[0], (-2, 2)) self.assertEqual(dummy._bounds[1], (-3, 3)) self.assertAllClose( - dummy.bounds, torch.tensor([[-2, -3], [2, 3]], dtype=torch.double) + dummy.bounds, + torch.tensor([[-2, -3], [2, 3]], dtype=torch.torch.get_default_dtype()), ) # Test each function with custom bounds. for func_class, dim in self.functions_with_custom_bounds: bounds = [(-1e5, 1e5) for _ in range(dim)] - bounds_tensor = torch.tensor(bounds, dtype=torch.double).T + bounds_tensor = torch.tensor(bounds, dtype=torch.get_default_dtype()).T func = func_class(bounds=bounds) self.assertEqual(func._bounds, bounds) self.assertAllClose(func.bounds, bounds_tensor) From 0378ca83ca74602262b945add6f5ac2a9b7f0d78 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Tue, 29 Oct 2024 09:00:32 +0100 Subject: [PATCH 03/13] Make dtype an optional argument of init for BaseTestProblem --- botorch/test_functions/base.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/botorch/test_functions/base.py b/botorch/test_functions/base.py index c4df1baadb..2d3ffdcd54 100644 --- a/botorch/test_functions/base.py +++ b/botorch/test_functions/base.py @@ -29,6 +29,7 @@ def __init__( self, noise_std: None | float | list[float] = None, negate: bool = False, + dtype: torch.dtype = torch.double, ) -> None: r"""Base constructor for test functions. @@ -37,10 +38,12 @@ def __init__( provided, specifies separate noise standard deviations for each objective in a multiobjective problem. negate: If True, negate the function. + dtype: The dtype that is used for the bounds of the function. """ super().__init__() self.noise_std = noise_std self.negate = negate + self.dtype = dtype if len(self._bounds) != self.dim: raise InputDataError( "Expected the bounds to match the dimensionality of the domain. " @@ -48,9 +51,7 @@ def __init__( ) self.register_buffer( "bounds", - torch.tensor(self._bounds, dtype=torch.get_default_dtype()).transpose( - -1, -2 - ), + torch.tensor(self._bounds, dtype=self.dtype).transpose(-1, -2), ) def forward(self, X: Tensor, noise: bool = True) -> Tensor: From 84b60e314c73baf7a8f92201e8e5113cb9df6c35 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Tue, 29 Oct 2024 09:01:40 +0100 Subject: [PATCH 04/13] Explicitly use torch.double in TestCustomBounds --- test/test_functions/test_synthetic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_functions/test_synthetic.py b/test/test_functions/test_synthetic.py index f92bb719ca..36c5d1d662 100644 --- a/test/test_functions/test_synthetic.py +++ b/test/test_functions/test_synthetic.py @@ -101,13 +101,13 @@ def test_custom_bounds(self): self.assertEqual(dummy._bounds[1], (-3, 3)) self.assertAllClose( dummy.bounds, - torch.tensor([[-2, -3], [2, 3]], dtype=torch.torch.get_default_dtype()), + torch.tensor([[-2, -3], [2, 3]], dtype=torch.double), ) # Test each function with custom bounds. for func_class, dim in self.functions_with_custom_bounds: bounds = [(-1e5, 1e5) for _ in range(dim)] - bounds_tensor = torch.tensor(bounds, dtype=torch.get_default_dtype()).T + bounds_tensor = torch.tensor(bounds, dtype=torch.double).T func = func_class(bounds=bounds) self.assertEqual(func._bounds, bounds) self.assertAllClose(func.bounds, bounds_tensor) From b11cbcd7da87c6f2e77098060e41ca24af761113 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Tue, 29 Oct 2024 09:15:31 +0100 Subject: [PATCH 05/13] Fix use of default ftype in test_functions/base --- botorch/test_functions/base.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/botorch/test_functions/base.py b/botorch/test_functions/base.py index 2d3ffdcd54..fbdddd05ae 100644 --- a/botorch/test_functions/base.py +++ b/botorch/test_functions/base.py @@ -170,6 +170,7 @@ def __init__( self, noise_std: None | float | list[float] = None, negate: bool = False, + dtype: torch.dtype = torch.double, ) -> None: r"""Base constructor for multi-objective test functions. @@ -184,8 +185,8 @@ def __init__( f"If specified as a list, length of noise_std ({len(noise_std)}) " f"must match the number of objectives ({len(self._ref_point)})" ) - super().__init__(noise_std=noise_std, negate=negate) - ref_point = torch.tensor(self._ref_point, dtype=torch.get_default_dtype()) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) + ref_point = torch.tensor(self._ref_point, dtype=self.dtype) if negate: ref_point *= -1 self.register_buffer("ref_point", ref_point) From 417b1a4c1a919663eb17d15b31a37f7e2340148b Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Tue, 29 Oct 2024 09:16:38 +0100 Subject: [PATCH 06/13] Fix use of default ftype in test_functions/multi_fidelity --- botorch/test_functions/multi_fidelity.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/botorch/test_functions/multi_fidelity.py b/botorch/test_functions/multi_fidelity.py index c7855c22b7..703e30ca3b 100644 --- a/botorch/test_functions/multi_fidelity.py +++ b/botorch/test_functions/multi_fidelity.py @@ -74,13 +74,18 @@ class AugmentedHartmann(SyntheticTestFunction): _optimizers = [(0.20169, 0.150011, 0.476874, 0.275332, 0.311652, 0.6573, 1.0)] _check_grad_at_opt = False - def __init__(self, noise_std: float | None = None, negate: bool = False) -> None: + def __init__( + self, + noise_std: float | None = None, + negate: bool = False, + dtype: torch.dtype = torch.double, + ) -> None: r""" Args: noise_std: Standard deviation of the observation noise. negate: If True, negate the function. """ - super().__init__(noise_std=noise_std, negate=negate) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) self.register_buffer("ALPHA", torch.tensor([1.0, 1.2, 3.0, 3.2])) A = [ [10, 3, 17, 3.5, 1.7, 8], @@ -126,7 +131,11 @@ class AugmentedRosenbrock(SyntheticTestFunction): _optimal_value = 0.0 def __init__( - self, dim=3, noise_std: float | None = None, negate: bool = False + self, + dim=3, + noise_std: float | None = None, + negate: bool = False, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -141,7 +150,7 @@ def __init__( self.dim = dim self._bounds = [(-5.0, 10.0) for _ in range(self.dim)] self._optimizers = [tuple(1.0 for _ in range(self.dim))] - super().__init__(noise_std=noise_std, negate=negate) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) def evaluate_true(self, X: Tensor) -> Tensor: X_curr = X[..., :-3] From 547675b5dcdb83a90003f7b285921606892d7e74 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Tue, 29 Oct 2024 09:22:52 +0100 Subject: [PATCH 07/13] Fix use of default ftype in test_functions/multi_objective --- botorch/test_functions/multi_objective.py | 28 +++++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/botorch/test_functions/multi_objective.py b/botorch/test_functions/multi_objective.py index e592e2db5a..0fd28ff7d4 100644 --- a/botorch/test_functions/multi_objective.py +++ b/botorch/test_functions/multi_objective.py @@ -119,13 +119,15 @@ def __init__( self, noise_std: None | float | list[float] = None, negate: bool = False, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: noise_std: Standard deviation of the observation noise. negate: If True, negate the objectives. + dtype: The dtype that is used for the bounds of the function. """ - super().__init__(noise_std=noise_std, negate=negate) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) self._branin = Branin() def _rescaled_branin(self, X: Tensor) -> Tensor: @@ -179,12 +181,14 @@ def __init__( dim: int, noise_std: None | float | list[float] = None, negate: bool = False, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: dim: The (input) dimension. noise_std: Standard deviation of the observation noise. negate: If True, negate the function. + dtype: The dtype that is used for the bounds of the function. """ if dim < self._min_dim: raise ValueError(f"dim must be >= {self._min_dim}, but got dim={dim}!") @@ -194,7 +198,7 @@ def __init__( ] # max_hv is the area of the box minus the area of the curve formed by the PF. self._max_hv = self._ref_point[0] * self._ref_point[1] - self._area_under_curve - super().__init__(noise_std=noise_std, negate=negate) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) @abstractmethod def _h(self, X: Tensor) -> Tensor: @@ -339,6 +343,7 @@ def __init__( num_objectives: int = 2, noise_std: None | float | list[float] = None, negate: bool = False, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -346,6 +351,7 @@ def __init__( num_objectives: Must be less than dim. noise_std: Standard deviation of the observation noise. negate: If True, negate the function. + dtype: The dtype that is used for the bounds of the function. """ if dim <= num_objectives: raise ValueError( @@ -356,7 +362,7 @@ def __init__( self.k = self.dim - self.num_objectives + 1 self._bounds = [(0.0, 1.0) for _ in range(self.dim)] self._ref_point = [self._ref_val for _ in range(num_objectives)] - super().__init__(noise_std=noise_std, negate=negate) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) class DTLZ1(DTLZ): @@ -608,12 +614,14 @@ def __init__( noise_std: None | float | list[float] = None, negate: bool = False, num_objectives: int = 2, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: noise_std: Standard deviation of the observation noise. negate: If True, negate the objectives. num_objectives: The number of objectives. + dtype: The dtype that is used for the bounds of the function. """ if num_objectives not in (2, 3, 4): raise UnsupportedError("GMM only currently supports 2 to 4 objectives.") @@ -623,7 +631,7 @@ def __init__( if num_objectives > 3: self._ref_point.append(-0.1866) self.num_objectives = num_objectives - super().__init__(noise_std=noise_std, negate=negate) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) gmm_pos = torch.tensor( [ [[0.2, 0.2], [0.8, 0.2], [0.5, 0.7]], @@ -935,6 +943,7 @@ def __init__( num_objectives: int = 2, noise_std: None | float | list[float] = None, negate: bool = False, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -942,6 +951,7 @@ def __init__( num_objectives: Number of objectives. Must not be larger than dim. noise_std: Standard deviation of the observation noise. negate: If True, negate the function. + dtype: The dtype that is used for the bounds of the function. """ if num_objectives != 2: raise NotImplementedError( @@ -954,7 +964,7 @@ def __init__( self.num_objectives = num_objectives self.dim = dim self._bounds = [(0.0, 1.0) for _ in range(self.dim)] - super().__init__(noise_std=noise_std, negate=negate) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) @staticmethod def _g(X: Tensor) -> Tensor: @@ -1246,6 +1256,7 @@ def __init__( noise_std: None | float | list[float] = None, constraint_noise_std: None | float | list[float] = None, negate: bool = False, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -1253,8 +1264,9 @@ def __init__( constraint_noise_std: Standard deviation of the observation noise of the constraint. negate: If True, negate the function. + dtype: The dtype that is used for the bounds of the function. """ - super().__init__(noise_std=noise_std, negate=negate) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) con_bounds = torch.tensor(self._con_bounds, dtype=self.bounds.dtype).transpose( -1, -2 ) @@ -1357,6 +1369,7 @@ def __init__( noise_std: None | float | list[float] = None, constraint_noise_std: None | float | list[float] = None, negate: bool = False, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -1365,12 +1378,13 @@ def __init__( constraint_noise_std: Standard deviation of the observation noise of the constraints. negate: If True, negate the function. + dtype: The dtype that is used for the bounds of the function. """ if dim < 2: raise ValueError("dim must be greater than or equal to 2.") self.dim = dim self._bounds = [(0.0, 1.0) for _ in range(self.dim)] - super().__init__(noise_std=noise_std, negate=negate) + super().__init__(noise_std=noise_std, negate=negate, dtpye=dtype) self.constraint_noise_std = constraint_noise_std def LA2(self, A, B, C, D, theta) -> Tensor: From ce7e7a7ed1cb04d13e6f35c0f87c4034dfed83fb Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Tue, 29 Oct 2024 09:25:12 +0100 Subject: [PATCH 08/13] Fix use of default ftype in test_functions/sensitivity_analysis --- .../test_functions/sensitivity_analysis.py | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/botorch/test_functions/sensitivity_analysis.py b/botorch/test_functions/sensitivity_analysis.py index 51eae546ae..7f842e8bad 100644 --- a/botorch/test_functions/sensitivity_analysis.py +++ b/botorch/test_functions/sensitivity_analysis.py @@ -24,13 +24,18 @@ class Ishigami(SyntheticTestFunction): """ def __init__( - self, b: float = 0.1, noise_std: float | None = None, negate: bool = False + self, + b: float = 0.1, + noise_std: float | None = None, + negate: bool = False, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: b: the b constant, should be 0.1 or 0.05. noise_std: Standard deviation of the observation noise. negative: If True, negative the objective. + dtype: The dtype that is used for the bounds of the function. """ self._optimizers = None if b not in (0.1, 0.05): @@ -52,7 +57,7 @@ def __init__( self.dgsm_gradient_square = [2.8, 24.5, 11] self._bounds = [(-math.pi, math.pi) for _ in range(self.dim)] self.b = b - super().__init__(noise_std=noise_std, negate=negate) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) @property def _optimal_value(self) -> float: @@ -127,13 +132,15 @@ def __init__( a: list = None, noise_std: float | None = None, negate: bool = False, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: dim: Dimensionality of the problem. If 6, 8, or 15, will use standard a. a: a parameter, unless dim is 6, 8, or 15. noise_std: Standard deviation of observation noise. - negate: Return negatie of function. + negate: Return negative of function. + dtype: The dtype that is used for the bounds of the function. """ self._optimizers = None self.dim = dim @@ -163,7 +170,7 @@ def __init__( else: self.a = a self.optimal_sobol_indicies() - super().__init__(noise_std=noise_std, negate=negate) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) @property def _optimal_value(self) -> float: @@ -207,11 +214,17 @@ class Morris(SyntheticTestFunction): Proposed to test sensitivity analysis methods """ - def __init__(self, noise_std: float | None = None, negate: bool = False) -> None: + def __init__( + self, + noise_std: float | None = None, + negate: bool = False, + dtype: torch.dtype = torch.double, + ) -> None: r""" Args: noise_std: Standard deviation of observation noise. negate: Return negative of function. + dtype: The dtype that is used for the bounds of the function. """ self._optimizers = None self.dim = 20 @@ -238,7 +251,7 @@ def __init__(self, noise_std: float | None = None, negate: bool = False) -> None 0, 0, ] - super().__init__(noise_std=noise_std, negate=negate) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) @property def _optimal_value(self) -> float: From 9b1b03960931afb7836078734c0c0d74fd90ffda Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Tue, 29 Oct 2024 09:31:34 +0100 Subject: [PATCH 09/13] Fix use of default ftype in test_functions/synthetic --- botorch/test_functions/synthetic.py | 67 ++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 15 deletions(-) diff --git a/botorch/test_functions/synthetic.py b/botorch/test_functions/synthetic.py index d4d1e110ab..23bc2523ae 100644 --- a/botorch/test_functions/synthetic.py +++ b/botorch/test_functions/synthetic.py @@ -68,6 +68,7 @@ def __init__( noise_std: None | float | list[float] = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -76,10 +77,11 @@ def __init__( objective in a multiobjective problem. negate: If True, negate the function. bounds: Custom bounds for the function specified as (lower, upper) pairs. + dtype: The dtype that is used for the bounds of the function. """ if bounds is not None: self._bounds = bounds - super().__init__(noise_std=noise_std, negate=negate) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) if self._optimizers is not None: if bounds is not None: # Ensure at least one optimizer lies within the custom bounds @@ -138,6 +140,7 @@ def __init__( noise_std: float | None = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -150,7 +153,7 @@ def __init__( if bounds is None: bounds = [(-32.768, 32.768) for _ in range(self.dim)] self._optimizers = [tuple(0.0 for _ in range(self.dim))] - super().__init__(noise_std=noise_std, negate=negate, bounds=bounds) + super().__init__(noise_std=noise_std, negate=negate, bounds=bounds, dtype=dtype) self.a = 20 self.b = 0.2 self.c = 2 * math.pi @@ -261,6 +264,7 @@ def __init__( noise_std: float | None = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -277,7 +281,7 @@ def __init__( for i in range(1, self.dim + 1) ) ] - super().__init__(noise_std=noise_std, negate=negate, bounds=bounds) + super().__init__(noise_std=noise_std, negate=negate, bounds=bounds, dtype=dtype) def evaluate_true(self, X: Tensor) -> Tensor: d = self.dim @@ -330,6 +334,7 @@ def __init__( noise_std: float | None = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -337,12 +342,13 @@ def __init__( noise_std: Standard deviation of the observation noise. negate: If True, negate the function. bounds: Custom bounds for the function specified as (lower, upper) pairs. + dtype: The dtype that is used for the bounds of the function. """ self.dim = dim if bounds is None: bounds = [(-600.0, 600.0) for _ in range(self.dim)] self._optimizers = [tuple(0.0 for _ in range(self.dim))] - super().__init__(noise_std=noise_std, negate=negate, bounds=bounds) + super().__init__(noise_std=noise_std, negate=negate, bounds=bounds, dtype=dtype) def evaluate_true(self, X: Tensor) -> Tensor: part1 = torch.sum(X.pow(2) / 4000.0, dim=-1) @@ -372,6 +378,7 @@ def __init__( noise_std: float | None = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -379,6 +386,7 @@ def __init__( noise_std: Standard deviation of the observation noise. negate: If True, negate the function. bounds: Custom bounds for the function specified as (lower, upper) pairs. + dtype: The dtype that is used for the bounds of the function. """ if dim not in (3, 4, 6): raise ValueError(f"Hartmann with dim {dim} not defined") @@ -393,7 +401,7 @@ def __init__( } self._optimal_value = optvals.get(self.dim) self._optimizers = optimizers.get(self.dim) - super().__init__(noise_std=noise_std, negate=negate, bounds=bounds) + super().__init__(noise_std=noise_std, negate=negate, bounds=bounds, dtype=dtype) self.register_buffer("ALPHA", torch.tensor([1.0, 1.2, 3.0, 3.2])) if dim == 3: A = [[3.0, 10, 30], [0.1, 10, 35], [3.0, 10, 30], [0.1, 10, 35]] @@ -506,6 +514,7 @@ def __init__( noise_std: float | None = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -513,12 +522,13 @@ def __init__( noise_std: Standard deviation of the observation noise. negate: If True, negate the function. bounds: Custom bounds for the function specified as (lower, upper) pairs. + dtype: The dtype that is used for the bounds of the function. """ self.dim = dim if bounds is None: bounds = [(-10.0, 10.0) for _ in range(self.dim)] self._optimizers = [tuple(1.0 for _ in range(self.dim))] - super().__init__(noise_std=noise_std, negate=negate, bounds=bounds) + super().__init__(noise_std=noise_std, negate=negate, bounds=bounds, dtype=dtype) def evaluate_true(self, X: Tensor) -> Tensor: w = 1.0 + (X - 1.0) / 4.0 @@ -548,6 +558,7 @@ def __init__( noise_std: float | None = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -563,7 +574,7 @@ def __init__( optimizers = {2: [(2.20290552, 1.57079633)]} self._optimal_value = optvals.get(self.dim) self._optimizers = optimizers.get(self.dim) - super().__init__(noise_std=noise_std, negate=negate, bounds=bounds) + super().__init__(noise_std=noise_std, negate=negate, bounds=bounds, dtype=dtype) self.register_buffer( "i", torch.tensor(tuple(range(1, self.dim + 1)), dtype=self.bounds.dtype) ) @@ -608,6 +619,7 @@ def __init__( noise_std: float | None = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -615,12 +627,13 @@ def __init__( noise_std: Standard deviation of the observation noise. negate: If True, negate the function. bounds: Custom bounds for the function specified as (lower, upper) pairs. + dtype: The dtype that is used for the bounds of the function. """ self.dim = dim if bounds is None: bounds = [(-4.0, 5.0) for _ in range(self.dim)] self._optimizers = [tuple(0.0 for _ in range(self.dim))] - super().__init__(noise_std=noise_std, negate=negate, bounds=bounds) + super().__init__(noise_std=noise_std, negate=negate, bounds=bounds, dtype=dtype) def evaluate_true(self, X: Tensor) -> Tensor: result = torch.zeros_like(X[..., 0]) @@ -643,6 +656,7 @@ def __init__( noise_std: float | None = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -650,12 +664,13 @@ def __init__( noise_std: Standard deviation of the observation noise. negate: If True, negate the function. bounds: Custom bounds for the function specified as (lower, upper) pairs. + dtype: The dtype that is used for the bounds of the function. """ self.dim = dim if bounds is None: bounds = [(-5.12, 5.12) for _ in range(self.dim)] self._optimizers = [tuple(0.0 for _ in range(self.dim))] - super().__init__(noise_std=noise_std, negate=negate, bounds=bounds) + super().__init__(noise_std=noise_std, negate=negate, bounds=bounds, dtype=dtype) def evaluate_true(self, X: Tensor) -> Tensor: return 10.0 * self.dim + torch.sum( @@ -682,6 +697,7 @@ def __init__( noise_std: float | None = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.dtype, ) -> None: r""" Args: @@ -689,12 +705,13 @@ def __init__( noise_std: Standard deviation of the observation noise. negate: If True, negate the function. bounds: Custom bounds for the function specified as (lower, upper) pairs. + dtype: The dtype that is used for the bounds of the function. """ self.dim = dim if bounds is None: bounds = [(-5.0, 10.0) for _ in range(self.dim)] self._optimizers = [tuple(1.0 for _ in range(self.dim))] - super().__init__(noise_std=noise_std, negate=negate, bounds=bounds) + super().__init__(noise_std=noise_std, negate=negate, bounds=bounds, dtype=dtype) def evaluate_true(self, X: Tensor) -> Tensor: return torch.sum( @@ -724,6 +741,7 @@ def __init__( noise_std: float | None = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -731,11 +749,12 @@ def __init__( noise_std: Standard deviation of the observation noise. negate: If True, negate the function. bounds: Custom bounds for the function specified as (lower, upper) pairs. + dtype: The dtype that is used for the bounds of the function. """ self.m = m optvals = {5: -10.1532, 7: -10.4029, 10: -10.536443} self._optimal_value = optvals[self.m] - super().__init__(noise_std=noise_std, negate=negate, bounds=bounds) + super().__init__(noise_std=noise_std, negate=negate, bounds=bounds, dtype=dtype) self.register_buffer("beta", torch.tensor([1, 2, 2, 4, 4, 6, 3, 7, 5, 5.0])) C_t = torch.tensor( @@ -789,6 +808,7 @@ def __init__( noise_std: float | None = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -796,13 +816,14 @@ def __init__( noise_std: Standard deviation of the observation noise. negate: If True, negate the function. bounds: Custom bounds for the function specified as (lower, upper) pairs. + dtype: The dtype that is used for the bounds of the function. """ self.dim = dim if bounds is None: bounds = [(-5.0, 5.0) for _ in range(self.dim)] self._optimal_value = -39.166166 * self.dim self._optimizers = [tuple(-2.903534 for _ in range(self.dim))] - super().__init__(noise_std=noise_std, negate=negate, bounds=bounds) + super().__init__(noise_std=noise_std, negate=negate, bounds=bounds, dtype=dtype) def evaluate_true(self, X: Tensor) -> Tensor: return 0.5 * (X.pow(4) - 16 * X.pow(2) + 5 * X).sum(dim=-1) @@ -835,6 +856,7 @@ def __init__( constraint_noise_std: None | float | list[float] = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -846,9 +868,10 @@ def __init__( deviations for each constraint. negate: If True, negate the function. bounds: Custom bounds for the function specified as (lower, upper) pairs. + dtype: The dtype that is used for the bounds of the function. """ SyntheticTestFunction.__init__( - self, noise_std=noise_std, negate=negate, bounds=bounds + self, noise_std=noise_std, negate=negate, bounds=bounds, dtype=dtype ) self.constraint_noise_std = self._validate_constraint_noise( constraint_noise_std @@ -927,6 +950,7 @@ def __init__( constraint_noise_std: None | float | list[float] = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -937,9 +961,15 @@ def __init__( deviations for each constraint. negate: If True, negate the function. bounds: Custom bounds for the function specified as (lower, upper) pairs. + dtype: The dtype that is used for the bounds of the function. """ Hartmann.__init__( - self, dim=dim, noise_std=noise_std, negate=negate, bounds=bounds + self, + dim=dim, + noise_std=noise_std, + negate=negate, + bounds=bounds, + dtype=dtype, ) self.constraint_noise_std = self._validate_constraint_noise( constraint_noise_std @@ -965,6 +995,7 @@ def __init__( constraint_noise_std: None | float | list[float] = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: @@ -975,9 +1006,15 @@ def __init__( deviations for each constraint. negate: If True, negate the function. bounds: Custom bounds for the function specified as (lower, upper) pairs. + dtype: The dtype that is used for the bounds of the function. """ Hartmann.__init__( - self, dim=dim, noise_std=noise_std, negate=negate, bounds=bounds + self, + dim=dim, + noise_std=noise_std, + negate=negate, + bounds=bounds, + dtype=dtype, ) self.constraint_noise_std = self._validate_constraint_noise( constraint_noise_std From 01fd83702a8926f35c2512b6b3f3e2e0da34310a Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Tue, 29 Oct 2024 09:43:52 +0100 Subject: [PATCH 10/13] Fix typo in test_functions/multi_objective --- botorch/test_functions/multi_objective.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/botorch/test_functions/multi_objective.py b/botorch/test_functions/multi_objective.py index 0fd28ff7d4..e76bf78907 100644 --- a/botorch/test_functions/multi_objective.py +++ b/botorch/test_functions/multi_objective.py @@ -1384,7 +1384,7 @@ def __init__( raise ValueError("dim must be greater than or equal to 2.") self.dim = dim self._bounds = [(0.0, 1.0) for _ in range(self.dim)] - super().__init__(noise_std=noise_std, negate=negate, dtpye=dtype) + super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) self.constraint_noise_std = constraint_noise_std def LA2(self, A, B, C, D, theta) -> Tensor: From 41d68c5e1eeb4ffe253ca4b18e56638437dd5809 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Tue, 29 Oct 2024 09:44:32 +0100 Subject: [PATCH 11/13] Fix incorrect default in test_functions/synthetic --- botorch/test_functions/synthetic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/botorch/test_functions/synthetic.py b/botorch/test_functions/synthetic.py index 23bc2523ae..91c1df843e 100644 --- a/botorch/test_functions/synthetic.py +++ b/botorch/test_functions/synthetic.py @@ -697,7 +697,7 @@ def __init__( noise_std: float | None = None, negate: bool = False, bounds: list[tuple[float, float]] | None = None, - dtype: torch.dtype = torch.dtype, + dtype: torch.dtype = torch.double, ) -> None: r""" Args: From b9f1cf586283a2ae93ac8c66c2e7a44788a31542 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Tue, 29 Oct 2024 15:39:47 +0100 Subject: [PATCH 12/13] Remove unnecessary assignment of dtype --- botorch/test_functions/base.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/botorch/test_functions/base.py b/botorch/test_functions/base.py index fbdddd05ae..19abe18ebb 100644 --- a/botorch/test_functions/base.py +++ b/botorch/test_functions/base.py @@ -43,7 +43,6 @@ def __init__( super().__init__() self.noise_std = noise_std self.negate = negate - self.dtype = dtype if len(self._bounds) != self.dim: raise InputDataError( "Expected the bounds to match the dimensionality of the domain. " @@ -51,7 +50,7 @@ def __init__( ) self.register_buffer( "bounds", - torch.tensor(self._bounds, dtype=self.dtype).transpose(-1, -2), + torch.tensor(self._bounds, dtype=dtype).transpose(-1, -2), ) def forward(self, X: Tensor, noise: bool = True) -> Tensor: @@ -186,7 +185,7 @@ def __init__( f"must match the number of objectives ({len(self._ref_point)})" ) super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) - ref_point = torch.tensor(self._ref_point, dtype=self.dtype) + ref_point = torch.tensor(self._ref_point, dtype=dtype) if negate: ref_point *= -1 self.register_buffer("ref_point", ref_point) From 6ddd51f5cd9be258a2d27709d2c10e60781e9fe7 Mon Sep 17 00:00:00 2001 From: "Alexander V. Hopp" Date: Tue, 29 Oct 2024 15:40:58 +0100 Subject: [PATCH 13/13] Add missing docstring args --- botorch/test_functions/multi_fidelity.py | 2 ++ botorch/test_functions/synthetic.py | 1 + 2 files changed, 3 insertions(+) diff --git a/botorch/test_functions/multi_fidelity.py b/botorch/test_functions/multi_fidelity.py index 703e30ca3b..22c593f292 100644 --- a/botorch/test_functions/multi_fidelity.py +++ b/botorch/test_functions/multi_fidelity.py @@ -84,6 +84,7 @@ def __init__( Args: noise_std: Standard deviation of the observation noise. negate: If True, negate the function. + dtype: The dtype that is used for the bounds of the function. """ super().__init__(noise_std=noise_std, negate=negate, dtype=dtype) self.register_buffer("ALPHA", torch.tensor([1.0, 1.2, 3.0, 3.2])) @@ -142,6 +143,7 @@ def __init__( dim: The (input) dimension. Must be at least 3. noise_std: Standard deviation of the observation noise. negate: If True, negate the function. + dtype: The dtype that is used for the bounds of the function. """ if dim < 3: raise ValueError( diff --git a/botorch/test_functions/synthetic.py b/botorch/test_functions/synthetic.py index 91c1df843e..b4efc0920c 100644 --- a/botorch/test_functions/synthetic.py +++ b/botorch/test_functions/synthetic.py @@ -271,6 +271,7 @@ def __init__( dim: The (input) dimension. noise_std: Standard deviation of the observation noise. negate: If True, negate the function. + dtype: The dtype that is used for the bounds of the function. """ self.dim = dim if bounds is None: