Skip to content

Commit 83ffd36

Browse files
authored
Merge pull request #398 from LemurPwned/issues/394
Issues/394
2 parents 202dc3c + ea1a95e commit 83ffd36

File tree

2 files changed

+63
-4
lines changed

2 files changed

+63
-4
lines changed

bayes_opt/domain_reduction.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ def initialize(self, target_space: TargetSpace) -> None:
6868

6969
self.r = self.contraction_rate * self.r
7070

71+
# check if the minimum window fits in the orignal bounds
72+
self._window_bounds_compatiblity(self.original_bounds)
73+
7174
def _update(self, target_space: TargetSpace) -> None:
7275

7376
# setting the previous
@@ -105,11 +108,27 @@ def _trim(self, new_bounds: np.array, global_bounds: np.array) -> np.array:
105108
new_bounds[i, 1] = entry[0]
106109
window_width = abs(entry[0] - entry[1])
107110
if window_width < self.minimum_window[i]:
108-
new_bounds[i, 0] -= (self.minimum_window[i] - window_width) / 2.0
109-
new_bounds[i, 1] += (self.minimum_window[i] - window_width) / 2.0
110-
111+
dw = (self.minimum_window[i] - window_width) / 2.0
112+
left_expansion_space = abs(global_bounds[i, 0] - entry[0]) # should be non-positive
113+
right_expansion_space = abs(global_bounds[i, 1] - entry[1]) # should be non-negative
114+
# conservative
115+
dw_l = min(dw, left_expansion_space)
116+
dw_r = min(dw, right_expansion_space)
117+
# this crawls towards the edge
118+
ddw_r = dw_r + max(dw - dw_l, 0)
119+
ddw_l = dw_l + max(dw - dw_r, 0)
120+
new_bounds[i, 0] -= ddw_l
121+
new_bounds[i, 1] += ddw_r
111122
return new_bounds
112123

124+
def _window_bounds_compatiblity(self, global_bounds: np.array) -> bool:
125+
"""Checks if global bounds are compatible with the minimum window sizes."""
126+
for i, entry in enumerate(global_bounds):
127+
global_window_width = abs(entry[1] - entry[0])
128+
if global_window_width < self.minimum_window[i]:
129+
raise ValueError(
130+
"Global bounds are not compatible with the minimum window size.")
131+
113132
def _create_bounds(self, parameters: dict, bounds: np.array) -> dict:
114133
return {param: bounds[i, :] for i, param in enumerate(parameters)}
115134

tests/test_seq_domain_red.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import numpy as np
2+
import pytest
23

34
from bayes_opt import SequentialDomainReductionTransformer
45
from bayes_opt import BayesianOptimization
5-
6+
from bayes_opt.target_space import TargetSpace
67

78
def black_box_function(x, y):
89
"""Function with unknown internals we wish to maximize.
@@ -104,3 +105,42 @@ def test_minimum_window_array_is_kept():
104105
)
105106
window_widths = np.diff(bounds_transformer.bounds)
106107
assert np.all(np.isclose(np.squeeze(np.min(window_widths, axis=0)), window_ranges))
108+
109+
def test_trimming_bounds():
110+
"""Test if the bounds are trimmed correctly within the bounds"""
111+
def dummy_function(x1, x2, x3, x4, x5):
112+
return 0.0
113+
114+
min_window = 1.0
115+
bounds_transformer = SequentialDomainReductionTransformer(minimum_window=min_window)
116+
pbounds = {
117+
'x1': (-1, 0.6),
118+
'x2': (-1, 0.5),
119+
'x3': (-0.4, 0.6),
120+
'x4': (0.3, 1.3),
121+
'x5': (-1, 0.8),
122+
}
123+
target_sp = TargetSpace(target_func=dummy_function, pbounds=pbounds)
124+
bounds_transformer.initialize(target_sp)
125+
new_bounds = np.concatenate((np.ones((5, 1)) * 0.1, np.ones((5, 1))), axis=1)
126+
global_bounds = np.asarray(list(pbounds.values()))
127+
128+
trimmed_bounds = bounds_transformer._trim(new_bounds, global_bounds)
129+
# check that the bounds are trimmed to the minimum window
130+
# raises ValueError if the bounds are not trimmed correctly
131+
bounds_transformer._window_bounds_compatiblity(trimmed_bounds)
132+
133+
134+
def test_exceeded_bounds():
135+
"""Raises Value Error if the bounds are exceeded."""
136+
window_ranges = [1.01, 0.72]
137+
bounds_transformer = SequentialDomainReductionTransformer(minimum_window=window_ranges)
138+
pbounds = {'x': (-0.5, 0.5), 'y': (-0.7, 0.0)}
139+
with pytest.raises(ValueError):
140+
_ = BayesianOptimization(
141+
f=black_box_function,
142+
pbounds=pbounds,
143+
verbose=0,
144+
random_state=1,
145+
bounds_transformer=bounds_transformer
146+
)

0 commit comments

Comments
 (0)