def test_discrete_search_space___mul___for_identity_space() -> None: dss = DiscreteSearchSpace(tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])) identity = DiscreteSearchSpace(tf.zeros([1, 0])) npt.assert_array_equal((dss * identity).points, dss.points) npt.assert_array_equal((identity * dss).points, dss.points)
def test_discrete_search_space___mul___for_empty_search_space() -> None: dss = DiscreteSearchSpace(tf.constant([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])) empty = DiscreteSearchSpace(tf.zeros([0, 1])) npt.assert_array_equal((empty * dss).points, tf.zeros([0, 3])) npt.assert_array_equal((dss * empty).points, tf.zeros([0, 3]))
def test_product_space___mul___() -> None: space_A = Box([-1], [2]) space_B = DiscreteSearchSpace(tf.ones([100, 2], dtype=tf.float64)) product_space_1 = TaggedProductSearchSpace(spaces=[space_A, space_B], tags=["A", "B"]) space_C = Box([-2, -2], [2, 3]) space_D = DiscreteSearchSpace(tf.ones([5, 3], dtype=tf.float64)) product_space_2 = TaggedProductSearchSpace(spaces=[space_C, space_D], tags=["C", "D"]) product_of_product_spaces = product_space_1 * product_space_2 subspace_0 = product_of_product_spaces.get_subspace("0") subspace_0_A = subspace_0.get_subspace("A") # type: ignore assert isinstance(subspace_0_A, Box) npt.assert_array_equal(subspace_0_A.lower, [-1]) npt.assert_array_equal(subspace_0_A.upper, [2]) subspace_0_B = subspace_0.get_subspace("B") # type: ignore assert isinstance(subspace_0_B, DiscreteSearchSpace) npt.assert_array_equal(subspace_0_B.points, tf.ones([100, 2], dtype=tf.float64)) subspace_1 = product_of_product_spaces.get_subspace("1") subspace_1_C = subspace_1.get_subspace("C") # type: ignore assert isinstance(subspace_1_C, Box) npt.assert_array_equal(subspace_1_C.lower, [-2, -2]) npt.assert_array_equal(subspace_1_C.upper, [2, 3]) subspace_1_D = subspace_1.get_subspace("D") # type: ignore assert isinstance(subspace_1_D, DiscreteSearchSpace) npt.assert_array_equal(subspace_1_D.points, tf.ones([5, 3], dtype=tf.float64))
def test_discrete_search_space___mul___raises_if_points_have_different_types( ) -> None: dss1 = DiscreteSearchSpace(_points_in_2D_search_space()) dss2 = DiscreteSearchSpace( tf.constant([[1.0, 1.4], [-1.5, 3.6]], tf.float64)) with pytest.raises(TypeError): _ = dss1 * dss2
def test_discrete_search_space_product_points_is_the_concatenation_of_original_points( ) -> None: dss1 = DiscreteSearchSpace( tf.constant([[-1.0, -1.4], [-1.5, -3.6], [-0.5, -0.6]])) dss2 = DiscreteSearchSpace(tf.constant([[1.0, 1.4], [1.5, 3.6]])) [n1, d1] = dss1.points.shape [n2, d2] = dss2.points.shape res = dss1 * dss2 assert res.points.shape[0] == n1 * n2 assert res.points.shape[1] == d1 + d2 assert all(point in dss1 for point in res.points[:, :2]) assert all(point in dss2 for point in res.points[:, 2:])
def test_discrete_search_space_sampling_raises_when_too_many_samples_are_requested( num_samples: int, ) -> None: search_space = DiscreteSearchSpace(_points_in_2D_search_space()) with pytest.raises(tf.errors.InvalidArgumentError): search_space.sample(num_samples)
def test_discrete_search_space_sampling_raises_when_too_many_samples_are_requested( num_samples: int, ) -> None: search_space = DiscreteSearchSpace(_points_in_2D_search_space()) with pytest.raises(ValueError, match="samples"): search_space.sample(num_samples)
def test_product_space_subspace_tags_attribute() -> None: decision_space = Box([-1, -2], [2, 3]) context_space = DiscreteSearchSpace(tf.constant([[-0.5, 0.5]])) product_space = TaggedProductSearchSpace( spaces=[context_space, decision_space], tags=["context", "decision"] ) npt.assert_array_equal(product_space.subspace_tags, ["context", "decision"])
def test_product_space_discretize_raises_if_sample_larger_than_discretization( num_samples: int, ) -> None: space_A = Box([-1], [2]) space_B = DiscreteSearchSpace(tf.ones([100, 2], dtype=tf.float64)) product_space = TaggedProductSearchSpace(spaces=[space_A, space_B]) dss = product_space.discretize(num_samples) with pytest.raises(tf.errors.InvalidArgumentError): dss.sample(num_samples + 1)
def test_discrete_search_space___mul___points_is_the_concatenation_of_original_points( ) -> None: dss1 = DiscreteSearchSpace( tf.constant([[-1.0, -1.4], [-1.5, -3.6], [-0.5, -0.6]])) dss2 = DiscreteSearchSpace(tf.constant([[1.0, 1.4], [1.5, 3.6]])) product = dss1 * dss2 all_expected_points = tf.constant([ [-1.0, -1.4, 1.0, 1.4], [-1.0, -1.4, 1.5, 3.6], [-1.5, -3.6, 1.0, 1.4], [-1.5, -3.6, 1.5, 3.6], [-0.5, -0.6, 1.0, 1.4], [-0.5, -0.6, 1.5, 3.6], ]) assert len(product.points) == len(all_expected_points) assert all(point in product for point in all_expected_points)
def test_product_space_discretize_returns_search_space_with_correct_number_of_points( num_samples: int, ) -> None: space_A = Box([-1], [2]) space_B = DiscreteSearchSpace(tf.ones([100, 2], dtype=tf.float64)) product_space = TaggedProductSearchSpace(spaces=[space_A, space_B]) dss = product_space.discretize(num_samples) samples = dss.sample(num_samples) assert len(samples) == num_samples
def test_product_space_discretize_returns_search_space_with_only_points_contained_within_box( num_samples: int, ) -> None: space_A = Box([-1], [2]) space_B = DiscreteSearchSpace(tf.ones([100, 2], dtype=tf.float64)) product_space = TaggedProductSearchSpace(spaces=[space_A, space_B]) dss = product_space.discretize(num_samples) samples = dss.sample(num_samples) assert all(sample in product_space for sample in samples)
def test_product_space_get_subspace() -> None: space_A = Box([-1, -2], [2, 3]) space_B = DiscreteSearchSpace(tf.constant([[-0.5, 0.5]])) space_C = Box([-1], [2]) product_space = TaggedProductSearchSpace( spaces=[space_A, space_B, space_C], tags=["A", "B", "C"] ) subspace_A = product_space.get_subspace("A") assert isinstance(subspace_A, Box) npt.assert_array_equal(subspace_A.lower, [-1, -2]) npt.assert_array_equal(subspace_A.upper, [2, 3]) subspace_B = product_space.get_subspace("B") assert isinstance(subspace_B, DiscreteSearchSpace) npt.assert_array_equal(subspace_B.points, tf.constant([[-0.5, 0.5]])) subspace_C = product_space.get_subspace("C") assert isinstance(subspace_C, Box) npt.assert_array_equal(subspace_C.lower, [-1]) npt.assert_array_equal(subspace_C.upper, [2])
def test_product_space_raises_for_non_unqique_subspace_names() -> None: space_A = Box([-1, -2], [2, 3]) space_B = DiscreteSearchSpace(tf.constant([[-0.5, 0.5]])) with pytest.raises(TF_DEBUGGING_ERROR_TYPES): TaggedProductSearchSpace(spaces=[space_A, space_B], tags=["A", "A"])
def test_product_space_raises_for_length_mismatch_between_spaces_and_tags() -> None: space_A = Box([-1, -2], [2, 3]) space_B = DiscreteSearchSpace(tf.constant([[-0.5, 0.5]])) with pytest.raises(TF_DEBUGGING_ERROR_TYPES): TaggedProductSearchSpace(spaces=[space_A, space_B], tags=["A", "B", "C"])
def test_discrete_search_space_sampling(num_samples: int) -> None: search_space = DiscreteSearchSpace(_points_in_2D_search_space()) samples = search_space.sample(num_samples) _assert_correct_number_of_unique_constrained_samples( num_samples, search_space, samples)
def test_discrete_search_space_contains_raises_for_invalid_shapes( points: tf.Tensor, test_point: tf.Tensor) -> None: space = DiscreteSearchSpace(points) with pytest.raises(ValueError): _ = test_point in space
def test_product_space_subspace_tags_default_behaviour() -> None: decision_space = Box([-1, -2], [2, 3]) context_space = DiscreteSearchSpace(tf.constant([[-0.5, 0.5]])) product_space = TaggedProductSearchSpace(spaces=[context_space, decision_space]) npt.assert_array_equal(product_space.subspace_tags, ["0", "1"])
def test_discrete_search_space_contains_all_its_points( point: tf.Tensor) -> None: assert point in DiscreteSearchSpace(_points_in_2D_search_space())
def test_discrete_search_space_raises_for_invalid_shapes( shape: ShapeLike) -> None: with pytest.raises(ValueError): DiscreteSearchSpace(tf.random.uniform(shape))
def test_product_space_does_not_contain_point(point: tf.Tensor) -> None: space_A = Box([-1.0, -2.0], [2.0, 3.0]) space_B = DiscreteSearchSpace(tf.constant([[-0.5, 0.5]], dtype=tf.float64)) product_space = TaggedProductSearchSpace(spaces=[space_A, space_B]) assert point not in product_space
def test_discrete_search_space_raises_for_invalid_shapes(shape: ShapeLike) -> None: with pytest.raises(TF_DEBUGGING_ERROR_TYPES): DiscreteSearchSpace(tf.random.uniform(shape))
def test_product_space_sampling_raises_for_invalid_sample_size(num_samples: int) -> None: space_A = Box([-1], [2]) space_B = DiscreteSearchSpace(tf.ones([100, 2], dtype=tf.float64)) product_space = TaggedProductSearchSpace(spaces=[space_A, space_B]) with pytest.raises(TF_DEBUGGING_ERROR_TYPES): product_space.sample(num_samples)
def test_product_space_sampling_returns_correct_shape(num_samples: int) -> None: space_A = Box([-1], [2]) space_B = DiscreteSearchSpace(tf.ones([100, 2], dtype=tf.float64)) product_space = TaggedProductSearchSpace(spaces=[space_A, space_B]) samples = product_space.sample(num_samples) npt.assert_array_equal(tf.shape(samples), [num_samples, 3])
def test_discrete_search_space_deepcopy() -> None: dss = DiscreteSearchSpace(_points_in_2D_search_space()) npt.assert_allclose( copy.deepcopy(dss).points, _points_in_2D_search_space())
def test_discrete_search_space_contains_raises_for_invalid_shapes( points: tf.Tensor, test_point: tf.Tensor ) -> None: space = DiscreteSearchSpace(points) with pytest.raises(TF_DEBUGGING_ERROR_TYPES): _ = test_point in space
def test_discrete_search_space_points() -> None: space = DiscreteSearchSpace(_points_in_2D_search_space()) npt.assert_array_equal(space.points, _points_in_2D_search_space())
OBJECTIVE, BatchAcquisitionRule, EfficientGlobalOptimization, ThompsonSampling, TrustRegion, ) from trieste.data import Dataset from trieste.models import ProbabilisticModel from trieste.space import Box, DiscreteSearchSpace, SearchSpace @pytest.mark.parametrize( "search_space, expected_minimum", [ ( DiscreteSearchSpace( tf.constant([[-2.2, -1.0], [0.1, -0.1], [1.3, 3.3]])), tf.constant([[0.1, -0.1]]), ), (Box(tf.constant([-2.2, -1.0]), tf.constant( [1.3, 3.3])), tf.constant([[0.0, 0.0]])), ], ) def test_ego(search_space: SearchSpace, expected_minimum: tf.Tensor) -> None: ego = EfficientGlobalOptimization( NegativeLowerConfidenceBound(0).using(OBJECTIVE)) dataset = Dataset(tf.zeros([0, 2]), tf.zeros([0, 1])) query_point, _ = ego.acquire(search_space, {OBJECTIVE: dataset}, {OBJECTIVE: QuadraticMeanAndRBFKernel()}) npt.assert_array_almost_equal(query_point, expected_minimum, decimal=5)
def test_discrete_search_space_does_not_contain_other_points( point: tf.Tensor) -> None: assert point not in DiscreteSearchSpace(_points_in_2D_search_space())
optimize_discrete, ) from trieste.space import Box, DiscreteSearchSpace from trieste.type import TensorType def _quadratic_sum(shift: list[float]) -> AcquisitionFunction: return lambda x: tf.reduce_sum(0.5 - quadratic(x - shift), axis=-2) @random_seed @pytest.mark.parametrize( "search_space, shift, expected_maximizer, optimizers", [ ( DiscreteSearchSpace(tf.constant([[-0.5], [0.2], [1.2], [1.7]])), [1.0], [[1.2]], [optimize_discrete, generate_random_search_optimizer()], ), # 1D ( # 2D DiscreteSearchSpace( tf.constant([[-0.5, -0.3], [-0.2, 0.3], [0.2, -0.3], [1.2, 0.4]])), [0.3, -0.4], [[0.2, -0.3]], [optimize_discrete, generate_random_search_optimizer()], ), (